chatroom-cli 1.138.0 → 1.138.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/index.js +1730 -347
- package/dist/index.js.map +12 -7
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -3795,6 +3795,385 @@ var init_meshoptimizer = __esm(() => {
|
|
|
3795
3795
|
init_meshopt_tangents();
|
|
3796
3796
|
});
|
|
3797
3797
|
|
|
3798
|
+
// src/commands/generate-3d/asset-analysis.ts
|
|
3799
|
+
function toUnit(value) {
|
|
3800
|
+
return value / 255;
|
|
3801
|
+
}
|
|
3802
|
+
function percentile(histogram, total, fraction) {
|
|
3803
|
+
const target = Math.min(total, Math.ceil(fraction * total));
|
|
3804
|
+
let seen = 0;
|
|
3805
|
+
for (let value = 0;value < HISTOGRAM_BINS; value += 1) {
|
|
3806
|
+
seen += histogram[value] ?? 0;
|
|
3807
|
+
if (seen >= target)
|
|
3808
|
+
return toUnit(value);
|
|
3809
|
+
}
|
|
3810
|
+
return 1;
|
|
3811
|
+
}
|
|
3812
|
+
function countInRange(histogram, first, last) {
|
|
3813
|
+
let count = 0;
|
|
3814
|
+
for (let value = first;value <= last; value += 1)
|
|
3815
|
+
count += histogram[value] ?? 0;
|
|
3816
|
+
return count;
|
|
3817
|
+
}
|
|
3818
|
+
function channelStats(pixels, channel) {
|
|
3819
|
+
const total = Math.floor(pixels.length / CHANNELS_PER_TEXEL);
|
|
3820
|
+
if (total === 0)
|
|
3821
|
+
return EMPTY_STATS;
|
|
3822
|
+
const histogram = new Uint32Array(HISTOGRAM_BINS);
|
|
3823
|
+
let weighted = 0;
|
|
3824
|
+
for (let index = channel;index < pixels.length; index += CHANNELS_PER_TEXEL) {
|
|
3825
|
+
const value = pixels[index];
|
|
3826
|
+
histogram[value] += 1;
|
|
3827
|
+
weighted += value;
|
|
3828
|
+
}
|
|
3829
|
+
return {
|
|
3830
|
+
mean: weighted / (255 * total),
|
|
3831
|
+
p5: percentile(histogram, total, 0.05),
|
|
3832
|
+
p50: percentile(histogram, total, 0.5),
|
|
3833
|
+
p95: percentile(histogram, total, 0.95),
|
|
3834
|
+
fractionAtLeastHalf: countInRange(histogram, HALF_BYTE, HISTOGRAM_BINS - 1) / total,
|
|
3835
|
+
fractionAtMostTenth: countInRange(histogram, 0, TENTH_BYTE) / total
|
|
3836
|
+
};
|
|
3837
|
+
}
|
|
3838
|
+
function isFiniteBox(min, max) {
|
|
3839
|
+
return min.every((value) => Number.isFinite(value)) && max.every((value) => Number.isFinite(value));
|
|
3840
|
+
}
|
|
3841
|
+
function mergeBounds(boxes) {
|
|
3842
|
+
const min = [Infinity, Infinity, Infinity];
|
|
3843
|
+
const max = [-Infinity, -Infinity, -Infinity];
|
|
3844
|
+
for (const box of boxes) {
|
|
3845
|
+
min[0] = Math.min(min[0], box.min[0]);
|
|
3846
|
+
min[1] = Math.min(min[1], box.min[1]);
|
|
3847
|
+
min[2] = Math.min(min[2], box.min[2]);
|
|
3848
|
+
max[0] = Math.max(max[0], box.max[0]);
|
|
3849
|
+
max[1] = Math.max(max[1], box.max[1]);
|
|
3850
|
+
max[2] = Math.max(max[2], box.max[2]);
|
|
3851
|
+
}
|
|
3852
|
+
return isFiniteBox(min, max) ? { min, max } : { min: [0, 0, 0], max: [0, 0, 0] };
|
|
3853
|
+
}
|
|
3854
|
+
function extentsOf(bounds) {
|
|
3855
|
+
return [
|
|
3856
|
+
bounds.max[0] - bounds.min[0],
|
|
3857
|
+
bounds.max[1] - bounds.min[1],
|
|
3858
|
+
bounds.max[2] - bounds.min[2]
|
|
3859
|
+
];
|
|
3860
|
+
}
|
|
3861
|
+
async function decodeImageRgba(image, sharpFactory) {
|
|
3862
|
+
const { data, info } = await sharpFactory(Buffer.from(image)).toColourspace("srgb").ensureAlpha().raw().toBuffer({ resolveWithObject: true });
|
|
3863
|
+
if (info.channels !== 4) {
|
|
3864
|
+
throw new Error(`Image decoded to ${info.channels} channels; expected 4 (RGBA).`);
|
|
3865
|
+
}
|
|
3866
|
+
return { pixels: new Uint8Array(data), width: info.width, height: info.height };
|
|
3867
|
+
}
|
|
3868
|
+
async function decodePixels(texture, sharp, cache) {
|
|
3869
|
+
const cached = cache.get(texture);
|
|
3870
|
+
if (cached !== undefined)
|
|
3871
|
+
return cached;
|
|
3872
|
+
const image = texture.getImage();
|
|
3873
|
+
if (image === null || image.length === 0) {
|
|
3874
|
+
throw new Error("A metallic-roughness texture has no embedded image.");
|
|
3875
|
+
}
|
|
3876
|
+
const { pixels } = await decodeImageRgba(image, sharp);
|
|
3877
|
+
cache.set(texture, pixels);
|
|
3878
|
+
return pixels;
|
|
3879
|
+
}
|
|
3880
|
+
async function describeMaterial(index, material, sharp, cache) {
|
|
3881
|
+
const texture = material.getMetallicRoughnessTexture();
|
|
3882
|
+
const base = {
|
|
3883
|
+
index,
|
|
3884
|
+
name: material.getName() || null,
|
|
3885
|
+
metallicFactor: material.getMetallicFactor(),
|
|
3886
|
+
roughnessFactor: material.getRoughnessFactor(),
|
|
3887
|
+
hasMetallicRoughnessTexture: texture !== null
|
|
3888
|
+
};
|
|
3889
|
+
if (texture === null)
|
|
3890
|
+
return { ...base, metal: null, roughness: null };
|
|
3891
|
+
if (!DECODABLE_IMAGE_MIME_TYPES.has(texture.getMimeType())) {
|
|
3892
|
+
return { ...base, metal: null, roughness: null };
|
|
3893
|
+
}
|
|
3894
|
+
const pixels = await decodePixels(texture, sharp, cache);
|
|
3895
|
+
return { ...base, metal: channelStats(pixels, 2), roughness: channelStats(pixels, 1) };
|
|
3896
|
+
}
|
|
3897
|
+
async function analyseDocument(doc) {
|
|
3898
|
+
const [{ getBounds }, { default: sharp }] = await Promise.all([
|
|
3899
|
+
import("@gltf-transform/functions"),
|
|
3900
|
+
import("sharp")
|
|
3901
|
+
]);
|
|
3902
|
+
const bounds = mergeBounds(doc.getRoot().listScenes().map((scene) => getBounds(scene)));
|
|
3903
|
+
const cache = new Map;
|
|
3904
|
+
const materials = [];
|
|
3905
|
+
for (const [index, material] of doc.getRoot().listMaterials().entries()) {
|
|
3906
|
+
materials.push(await describeMaterial(index, material, sharp, cache));
|
|
3907
|
+
}
|
|
3908
|
+
return { bounds, extents: extentsOf(bounds), materials };
|
|
3909
|
+
}
|
|
3910
|
+
var CHANNELS_PER_TEXEL = 4, HALF_BYTE = 128, TENTH_BYTE = 25, HISTOGRAM_BINS = 256, EMPTY_STATS, DECODABLE_IMAGE_MIME_TYPES;
|
|
3911
|
+
var init_asset_analysis = __esm(() => {
|
|
3912
|
+
EMPTY_STATS = {
|
|
3913
|
+
mean: 0,
|
|
3914
|
+
p5: 0,
|
|
3915
|
+
p50: 0,
|
|
3916
|
+
p95: 0,
|
|
3917
|
+
fractionAtLeastHalf: 0,
|
|
3918
|
+
fractionAtMostTenth: 0
|
|
3919
|
+
};
|
|
3920
|
+
DECODABLE_IMAGE_MIME_TYPES = new Set([
|
|
3921
|
+
"image/jpeg",
|
|
3922
|
+
"image/png",
|
|
3923
|
+
"image/webp"
|
|
3924
|
+
]);
|
|
3925
|
+
});
|
|
3926
|
+
|
|
3927
|
+
// src/commands/generate-3d/fit.ts
|
|
3928
|
+
async function currentBounds(doc, getBounds) {
|
|
3929
|
+
return mergeBounds(doc.getRoot().listScenes().map((scene) => getBounds(scene)));
|
|
3930
|
+
}
|
|
3931
|
+
function originOffset(bounds, origin) {
|
|
3932
|
+
if (origin === "as-is")
|
|
3933
|
+
return [0, 0, 0];
|
|
3934
|
+
const midX = (bounds.min[0] + bounds.max[0]) / 2;
|
|
3935
|
+
const midZ = (bounds.min[2] + bounds.max[2]) / 2;
|
|
3936
|
+
const y = origin === "feet" ? bounds.min[1] : (bounds.min[1] + bounds.max[1]) / 2;
|
|
3937
|
+
return [-midX, -y, -midZ];
|
|
3938
|
+
}
|
|
3939
|
+
function scaleForHeight(bounds, targetHeight) {
|
|
3940
|
+
const height = bounds.max[1] - bounds.min[1];
|
|
3941
|
+
if (!Number.isFinite(height) || height <= 0) {
|
|
3942
|
+
throw new Error("Cannot fit the model: its scene height is 0.");
|
|
3943
|
+
}
|
|
3944
|
+
return targetHeight / height;
|
|
3945
|
+
}
|
|
3946
|
+
function addWrapper(doc, translation, scale) {
|
|
3947
|
+
for (const scene of doc.getRoot().listScenes()) {
|
|
3948
|
+
const roots = [...scene.listChildren()];
|
|
3949
|
+
const wrapper = doc.createNode("Fit").setTranslation(translation).setScale([scale, scale, scale]);
|
|
3950
|
+
for (const root of roots)
|
|
3951
|
+
wrapper.addChild(root);
|
|
3952
|
+
scene.addChild(wrapper);
|
|
3953
|
+
}
|
|
3954
|
+
}
|
|
3955
|
+
function isIdentity(fit) {
|
|
3956
|
+
return fit.scale === 1 && fit.translation[0] === 0 && fit.translation[1] === 0 && fit.translation[2] === 0;
|
|
3957
|
+
}
|
|
3958
|
+
function applyFitTransform(doc, fit) {
|
|
3959
|
+
if (isIdentity(fit))
|
|
3960
|
+
return;
|
|
3961
|
+
addWrapper(doc, fit.translation, fit.scale);
|
|
3962
|
+
}
|
|
3963
|
+
function fitTransform(bounds, options) {
|
|
3964
|
+
const offset = originOffset(bounds, options.origin);
|
|
3965
|
+
const scale = options.targetHeight === undefined ? 1 : scaleForHeight(bounds, options.targetHeight);
|
|
3966
|
+
return {
|
|
3967
|
+
scale,
|
|
3968
|
+
translation: [offset[0] * scale, offset[1] * scale, offset[2] * scale]
|
|
3969
|
+
};
|
|
3970
|
+
}
|
|
3971
|
+
async function applyFit(doc, analysis, options) {
|
|
3972
|
+
if (options.origin === "as-is" && options.targetHeight === undefined) {
|
|
3973
|
+
return {
|
|
3974
|
+
origin: "as-is",
|
|
3975
|
+
targetHeight: null,
|
|
3976
|
+
scale: 1,
|
|
3977
|
+
translation: [0, 0, 0],
|
|
3978
|
+
bounds: analysis.bounds
|
|
3979
|
+
};
|
|
3980
|
+
}
|
|
3981
|
+
const { scale, translation } = fitTransform(analysis.bounds, options);
|
|
3982
|
+
addWrapper(doc, translation, scale);
|
|
3983
|
+
const { getBounds } = await import("@gltf-transform/functions");
|
|
3984
|
+
const bounds = await currentBounds(doc, getBounds);
|
|
3985
|
+
return {
|
|
3986
|
+
origin: options.origin,
|
|
3987
|
+
targetHeight: options.targetHeight ?? null,
|
|
3988
|
+
scale,
|
|
3989
|
+
translation,
|
|
3990
|
+
bounds: {
|
|
3991
|
+
min: [bounds.min[0], bounds.min[1], bounds.min[2]],
|
|
3992
|
+
max: [bounds.max[0], bounds.max[1], bounds.max[2]]
|
|
3993
|
+
}
|
|
3994
|
+
};
|
|
3995
|
+
}
|
|
3996
|
+
var init_fit = __esm(() => {
|
|
3997
|
+
init_asset_analysis();
|
|
3998
|
+
});
|
|
3999
|
+
|
|
4000
|
+
// src/commands/generate-3d/material-normalise.ts
|
|
4001
|
+
function materialName(material) {
|
|
4002
|
+
return material.getName() || null;
|
|
4003
|
+
}
|
|
4004
|
+
function untexturedDecision(index, material) {
|
|
4005
|
+
const name = materialName(material);
|
|
4006
|
+
if (material.getMetallicFactor() !== 1) {
|
|
4007
|
+
return { index, name, decision: "unchanged", reason: "explicit-factor" };
|
|
4008
|
+
}
|
|
4009
|
+
material.setMetallicFactor(0);
|
|
4010
|
+
return { index, name, decision: "non-metal", metalFraction: 0 };
|
|
4011
|
+
}
|
|
4012
|
+
function requireImage(texture) {
|
|
4013
|
+
const image = texture.getImage();
|
|
4014
|
+
if (image === null || image.length === 0) {
|
|
4015
|
+
throw new Error("A metallic-roughness texture has no embedded image.");
|
|
4016
|
+
}
|
|
4017
|
+
return image;
|
|
4018
|
+
}
|
|
4019
|
+
function isWeakMetal(value) {
|
|
4020
|
+
return value < METAL_MASK_THRESHOLD;
|
|
4021
|
+
}
|
|
4022
|
+
function isPartlyMetal(value) {
|
|
4023
|
+
return value > NON_METAL_TENTH_BYTE && value < METAL_MASK_THRESHOLD;
|
|
4024
|
+
}
|
|
4025
|
+
async function maskBlueChannel(texture, sharpFactory) {
|
|
4026
|
+
const { pixels, width, height } = await decodeImageRgba(requireImage(texture), sharpFactory);
|
|
4027
|
+
let masked = 0;
|
|
4028
|
+
for (let index = 2;index < pixels.length; index += 4) {
|
|
4029
|
+
const blue = pixels[index];
|
|
4030
|
+
if (!isWeakMetal(blue))
|
|
4031
|
+
continue;
|
|
4032
|
+
if (isPartlyMetal(blue))
|
|
4033
|
+
masked += 1;
|
|
4034
|
+
pixels[index] = 0;
|
|
4035
|
+
}
|
|
4036
|
+
const png = await sharpFactory(Buffer.from(pixels), {
|
|
4037
|
+
raw: { width, height, channels: 4 }
|
|
4038
|
+
}).png().toBuffer();
|
|
4039
|
+
texture.setImage(new Uint8Array(png)).setMimeType("image/png");
|
|
4040
|
+
return masked / (pixels.length / 4);
|
|
4041
|
+
}
|
|
4042
|
+
function hasUsableImage(texture, stats) {
|
|
4043
|
+
return DECODABLE_IMAGE_MIME_TYPES.has(texture.getMimeType()) && stats.metal !== null && stats.roughness !== null;
|
|
4044
|
+
}
|
|
4045
|
+
function canMask(texture, stats) {
|
|
4046
|
+
if (!hasUsableImage(texture, stats))
|
|
4047
|
+
return false;
|
|
4048
|
+
return stats.metal.fractionAtLeastHalf >= NON_METAL_FRACTION_MAX;
|
|
4049
|
+
}
|
|
4050
|
+
function isMaskCandidate(material, stats) {
|
|
4051
|
+
if (stats === undefined || material.getMetallicFactor() !== 1)
|
|
4052
|
+
return false;
|
|
4053
|
+
const texture = material.getMetallicRoughnessTexture();
|
|
4054
|
+
if (texture === null)
|
|
4055
|
+
return false;
|
|
4056
|
+
return canMask(texture, stats);
|
|
4057
|
+
}
|
|
4058
|
+
function texturedNonMaskedDecision(index, material, texture, stats) {
|
|
4059
|
+
const name = materialName(material);
|
|
4060
|
+
if (!hasUsableImage(texture, stats)) {
|
|
4061
|
+
return { index, name, decision: "unchanged", reason: "unsupported-image" };
|
|
4062
|
+
}
|
|
4063
|
+
if (material.getMetallicFactor() !== 1) {
|
|
4064
|
+
return { index, name, decision: "unchanged", reason: "explicit-factor" };
|
|
4065
|
+
}
|
|
4066
|
+
material.setMetallicFactor(0);
|
|
4067
|
+
return {
|
|
4068
|
+
index,
|
|
4069
|
+
name,
|
|
4070
|
+
decision: "non-metal",
|
|
4071
|
+
metalFraction: stats.metal.fractionAtLeastHalf
|
|
4072
|
+
};
|
|
4073
|
+
}
|
|
4074
|
+
function nonMaskedDecision(index, material, stats) {
|
|
4075
|
+
if (stats === undefined) {
|
|
4076
|
+
return {
|
|
4077
|
+
index,
|
|
4078
|
+
name: materialName(material),
|
|
4079
|
+
decision: "unchanged",
|
|
4080
|
+
reason: "missing-analysis"
|
|
4081
|
+
};
|
|
4082
|
+
}
|
|
4083
|
+
const texture = material.getMetallicRoughnessTexture();
|
|
4084
|
+
if (texture === null)
|
|
4085
|
+
return untexturedDecision(index, material);
|
|
4086
|
+
return texturedNonMaskedDecision(index, material, texture, stats);
|
|
4087
|
+
}
|
|
4088
|
+
function textureUsers(materials, texture) {
|
|
4089
|
+
const users = [];
|
|
4090
|
+
for (const [index, material] of materials.entries()) {
|
|
4091
|
+
if (material.getMetallicRoughnessTexture() === texture)
|
|
4092
|
+
users.push(index);
|
|
4093
|
+
}
|
|
4094
|
+
return users;
|
|
4095
|
+
}
|
|
4096
|
+
function needsClone(texture, users, masked) {
|
|
4097
|
+
const parents = texture.listParents().filter((parent) => parent.propertyType !== "Root").length;
|
|
4098
|
+
return users.length > masked.length || parents > users.length;
|
|
4099
|
+
}
|
|
4100
|
+
function maskedUserFor(index, material, stats) {
|
|
4101
|
+
if (!isMaskCandidate(material, stats))
|
|
4102
|
+
return null;
|
|
4103
|
+
if (stats === undefined || stats.metal === null)
|
|
4104
|
+
return null;
|
|
4105
|
+
return { index, material, metalFraction: stats.metal.fractionAtLeastHalf };
|
|
4106
|
+
}
|
|
4107
|
+
async function maskTextureGroup(args) {
|
|
4108
|
+
const { texture, masked, users, sharpFactory, decisions } = args;
|
|
4109
|
+
const clone = needsClone(texture, users, masked.map((user) => user.index));
|
|
4110
|
+
const target = clone ? texture.clone() : texture;
|
|
4111
|
+
const maskedFraction = await maskBlueChannel(target, sharpFactory);
|
|
4112
|
+
for (const user of masked) {
|
|
4113
|
+
user.material.setMetallicFactor(1);
|
|
4114
|
+
if (clone)
|
|
4115
|
+
user.material.setMetallicRoughnessTexture(target);
|
|
4116
|
+
decisions.set(user.index, {
|
|
4117
|
+
index: user.index,
|
|
4118
|
+
name: materialName(user.material),
|
|
4119
|
+
decision: "metal-masked",
|
|
4120
|
+
metalFraction: user.metalFraction,
|
|
4121
|
+
maskedFraction
|
|
4122
|
+
});
|
|
4123
|
+
}
|
|
4124
|
+
}
|
|
4125
|
+
function maskedEntryFor(index, material, stats) {
|
|
4126
|
+
const user = maskedUserFor(index, material, stats);
|
|
4127
|
+
if (user === null)
|
|
4128
|
+
return null;
|
|
4129
|
+
const texture = material.getMetallicRoughnessTexture();
|
|
4130
|
+
return texture === null ? null : { texture, user };
|
|
4131
|
+
}
|
|
4132
|
+
function maskedGroups(materials, analysis) {
|
|
4133
|
+
const groups = new Map;
|
|
4134
|
+
for (const [index, material] of materials.entries()) {
|
|
4135
|
+
const entry = maskedEntryFor(index, material, analysis.materials[index]);
|
|
4136
|
+
if (entry === null)
|
|
4137
|
+
continue;
|
|
4138
|
+
const group = groups.get(entry.texture) ?? [];
|
|
4139
|
+
group.push(entry.user);
|
|
4140
|
+
groups.set(entry.texture, group);
|
|
4141
|
+
}
|
|
4142
|
+
return groups;
|
|
4143
|
+
}
|
|
4144
|
+
function fillNonMasked(materials, analysis, decisions) {
|
|
4145
|
+
for (const [index, material] of materials.entries()) {
|
|
4146
|
+
if (decisions.has(index))
|
|
4147
|
+
continue;
|
|
4148
|
+
decisions.set(index, nonMaskedDecision(index, material, analysis.materials[index]));
|
|
4149
|
+
}
|
|
4150
|
+
}
|
|
4151
|
+
async function normaliseMaterials(doc, analysis) {
|
|
4152
|
+
const { default: sharpFactory } = await import("sharp");
|
|
4153
|
+
const materials = doc.getRoot().listMaterials();
|
|
4154
|
+
const decisions = new Map;
|
|
4155
|
+
for (const [texture, masked] of maskedGroups(materials, analysis)) {
|
|
4156
|
+
await maskTextureGroup({
|
|
4157
|
+
texture,
|
|
4158
|
+
masked,
|
|
4159
|
+
users: textureUsers(materials, texture),
|
|
4160
|
+
sharpFactory,
|
|
4161
|
+
decisions
|
|
4162
|
+
});
|
|
4163
|
+
}
|
|
4164
|
+
fillNonMasked(materials, analysis, decisions);
|
|
4165
|
+
return materials.map((_material, index) => decisions.get(index) ?? {
|
|
4166
|
+
index,
|
|
4167
|
+
name: null,
|
|
4168
|
+
decision: "unchanged",
|
|
4169
|
+
reason: "missing-analysis"
|
|
4170
|
+
});
|
|
4171
|
+
}
|
|
4172
|
+
var NON_METAL_FRACTION_MAX = 0.01, METAL_MASK_THRESHOLD = 128, NON_METAL_TENTH_BYTE = 25;
|
|
4173
|
+
var init_material_normalise = __esm(() => {
|
|
4174
|
+
init_asset_analysis();
|
|
4175
|
+
});
|
|
4176
|
+
|
|
3798
4177
|
// src/commands/generate-3d/web-variant.ts
|
|
3799
4178
|
import {
|
|
3800
4179
|
NodeIO,
|
|
@@ -3925,6 +4304,16 @@ async function createWebVariant(glb, opts) {
|
|
|
3925
4304
|
weld: () => weld(),
|
|
3926
4305
|
simplifyAt: (ratio) => simplify({ simplifier: MeshoptSimplifier, ratio, error: 0.01, lockBorder: true })
|
|
3927
4306
|
});
|
|
4307
|
+
let materials;
|
|
4308
|
+
let fit;
|
|
4309
|
+
if (opts.processed !== undefined) {
|
|
4310
|
+
materials = opts.processed.materials;
|
|
4311
|
+
fit = opts.processed.fit;
|
|
4312
|
+
} else {
|
|
4313
|
+
const analysis = await analyseDocument(document2);
|
|
4314
|
+
materials = await normaliseMaterials(document2, analysis);
|
|
4315
|
+
fit = await applyFit(document2, analysis, opts.fit ?? { origin: "as-is" });
|
|
4316
|
+
}
|
|
3928
4317
|
await compressTextures({
|
|
3929
4318
|
document: document2,
|
|
3930
4319
|
compressTexture,
|
|
@@ -3939,12 +4328,17 @@ async function createWebVariant(glb, opts) {
|
|
|
3939
4328
|
...describeDocument(document2),
|
|
3940
4329
|
simplified: geometry.simplified,
|
|
3941
4330
|
skinnedPath: geometry.skinnedPath,
|
|
3942
|
-
source
|
|
4331
|
+
source,
|
|
4332
|
+
materials,
|
|
4333
|
+
fit
|
|
3943
4334
|
};
|
|
3944
4335
|
}
|
|
3945
4336
|
var SILENT_LOGGER, COMPRESSIBLE_MIME_TYPES, WEBP_EXTENSION = "EXT_texture_webp", DRACO_EXTENSION = "KHR_draco_mesh_compression", MESHOPT_EXTENSION = "EXT_meshopt_compression";
|
|
3946
4337
|
var init_web_variant = __esm(() => {
|
|
3947
4338
|
init_meshoptimizer();
|
|
4339
|
+
init_asset_analysis();
|
|
4340
|
+
init_fit();
|
|
4341
|
+
init_material_normalise();
|
|
3948
4342
|
init_model_registry();
|
|
3949
4343
|
SILENT_LOGGER = {
|
|
3950
4344
|
debug: () => {},
|
|
@@ -3964,6 +4358,9 @@ import { createRequire as createRequire2 } from "module";
|
|
|
3964
4358
|
function deflateSync(data, opts) {
|
|
3965
4359
|
return dopt(data, opts || {}, 0, 0);
|
|
3966
4360
|
}
|
|
4361
|
+
function inflateSync(data, opts) {
|
|
4362
|
+
return inflt(data, { i: 2 }, opts && opts.out, opts && opts.dictionary);
|
|
4363
|
+
}
|
|
3967
4364
|
function strToU8(str, latin1) {
|
|
3968
4365
|
if (latin1) {
|
|
3969
4366
|
var ar_1 = new u8(str.length);
|
|
@@ -3997,6 +4394,21 @@ function strToU8(str, latin1) {
|
|
|
3997
4394
|
}
|
|
3998
4395
|
return slc(ar, 0, ai);
|
|
3999
4396
|
}
|
|
4397
|
+
function strFromU8(dat, latin1) {
|
|
4398
|
+
if (latin1) {
|
|
4399
|
+
var r = "";
|
|
4400
|
+
for (var i2 = 0;i2 < dat.length; i2 += 16384)
|
|
4401
|
+
r += String.fromCharCode.apply(null, dat.subarray(i2, i2 + 16384));
|
|
4402
|
+
return r;
|
|
4403
|
+
} else if (td) {
|
|
4404
|
+
return td.decode(dat);
|
|
4405
|
+
} else {
|
|
4406
|
+
var _a2 = dutf8(dat), s = _a2.s, r = _a2.r;
|
|
4407
|
+
if (r.length)
|
|
4408
|
+
err(8);
|
|
4409
|
+
return s;
|
|
4410
|
+
}
|
|
4411
|
+
}
|
|
4000
4412
|
function zipSync(data, opts) {
|
|
4001
4413
|
if (!opts)
|
|
4002
4414
|
opts = {};
|
|
@@ -4040,6 +4452,46 @@ function zipSync(data, opts) {
|
|
|
4040
4452
|
wzf(out, o, files.length, cdl, oe);
|
|
4041
4453
|
return out;
|
|
4042
4454
|
}
|
|
4455
|
+
function unzipSync(data, opts) {
|
|
4456
|
+
var files = {};
|
|
4457
|
+
var e = data.length - 22;
|
|
4458
|
+
for (;b4(data, e) != 101010256; --e) {
|
|
4459
|
+
if (!e || data.length - e > 65558)
|
|
4460
|
+
err(13);
|
|
4461
|
+
}
|
|
4462
|
+
var c = b2(data, e + 8);
|
|
4463
|
+
if (!c)
|
|
4464
|
+
return {};
|
|
4465
|
+
var o = b4(data, e + 16);
|
|
4466
|
+
var z = b4(data, e - 20) == 117853008;
|
|
4467
|
+
if (z) {
|
|
4468
|
+
var ze = b4(data, e - 12);
|
|
4469
|
+
z = b4(data, ze) == 101075792;
|
|
4470
|
+
if (z) {
|
|
4471
|
+
c = b4(data, ze + 32);
|
|
4472
|
+
o = b4(data, ze + 48);
|
|
4473
|
+
}
|
|
4474
|
+
}
|
|
4475
|
+
var fltr = opts && opts.filter;
|
|
4476
|
+
for (var i2 = 0;i2 < c; ++i2) {
|
|
4477
|
+
var _a2 = zh(data, o, z), c_2 = _a2[0], sc = _a2[1], su = _a2[2], fn = _a2[3], no = _a2[4], off = _a2[5], b = slzh(data, off);
|
|
4478
|
+
o = no;
|
|
4479
|
+
if (!fltr || fltr({
|
|
4480
|
+
name: fn,
|
|
4481
|
+
size: sc,
|
|
4482
|
+
originalSize: su,
|
|
4483
|
+
compression: c_2
|
|
4484
|
+
})) {
|
|
4485
|
+
if (!c_2)
|
|
4486
|
+
files[fn] = slc(data, b, b + sc);
|
|
4487
|
+
else if (c_2 == 8)
|
|
4488
|
+
files[fn] = inflateSync(data.subarray(b, b + sc), { out: new u8(su) });
|
|
4489
|
+
else
|
|
4490
|
+
err(14, "unknown compression type " + c_2);
|
|
4491
|
+
}
|
|
4492
|
+
}
|
|
4493
|
+
return files;
|
|
4494
|
+
}
|
|
4043
4495
|
var require2, _a, Worker2, isMarkedAsUntransferable, u8, u16, i32, fleb, fdeb, clim, freb = function(eb, start) {
|
|
4044
4496
|
var b = new u16(31);
|
|
4045
4497
|
for (var i = 0;i < 31; ++i) {
|
|
@@ -4087,7 +4539,20 @@ var require2, _a, Worker2, isMarkedAsUntransferable, u8, u16, i32, fleb, fdeb, c
|
|
|
4087
4539
|
}
|
|
4088
4540
|
}
|
|
4089
4541
|
return co;
|
|
4090
|
-
}, flt, i, i, i, i, fdt, i, flm, fdm,
|
|
4542
|
+
}, flt, i, i, i, i, fdt, i, flm, flrm, fdm, fdrm, max = function(a) {
|
|
4543
|
+
var m = a[0];
|
|
4544
|
+
for (var i2 = 1;i2 < a.length; ++i2) {
|
|
4545
|
+
if (a[i2] > m)
|
|
4546
|
+
m = a[i2];
|
|
4547
|
+
}
|
|
4548
|
+
return m;
|
|
4549
|
+
}, bits = function(d, p, m) {
|
|
4550
|
+
var o = p / 8 | 0;
|
|
4551
|
+
return (d[o] | d[o + 1] << 8) >> (p & 7) & m;
|
|
4552
|
+
}, bits16 = function(d, p) {
|
|
4553
|
+
var o = p / 8 | 0;
|
|
4554
|
+
return (d[o] | d[o + 1] << 8 | d[o + 2] << 16) >> (p & 7);
|
|
4555
|
+
}, shft = function(p) {
|
|
4091
4556
|
return (p + 7) / 8 | 0;
|
|
4092
4557
|
}, slc = function(v, s, e) {
|
|
4093
4558
|
if (s == null || s < 0)
|
|
@@ -4103,6 +4568,146 @@ var require2, _a, Worker2, isMarkedAsUntransferable, u8, u16, i32, fleb, fdeb, c
|
|
|
4103
4568
|
if (!nt)
|
|
4104
4569
|
throw e;
|
|
4105
4570
|
return e;
|
|
4571
|
+
}, inflt = function(dat, st, buf, dict) {
|
|
4572
|
+
var sl = dat.length, dl = dict ? dict.length : 0;
|
|
4573
|
+
if (!sl || st.f && !st.l)
|
|
4574
|
+
return buf || new u8(0);
|
|
4575
|
+
var noBuf = !buf;
|
|
4576
|
+
var resize = noBuf || st.i != 2;
|
|
4577
|
+
var noSt = st.i;
|
|
4578
|
+
if (noBuf)
|
|
4579
|
+
buf = new u8(sl * 3);
|
|
4580
|
+
var cbuf = function(l2) {
|
|
4581
|
+
var bl = buf.length;
|
|
4582
|
+
if (l2 > bl) {
|
|
4583
|
+
var nbuf = new u8(Math.max(bl * 2, l2));
|
|
4584
|
+
nbuf.set(buf);
|
|
4585
|
+
buf = nbuf;
|
|
4586
|
+
}
|
|
4587
|
+
};
|
|
4588
|
+
var final = st.f || 0, pos = st.p || 0, bt = st.b || 0, lm = st.l, dm = st.d, lbt = st.m, dbt = st.n;
|
|
4589
|
+
var tbts = sl * 8;
|
|
4590
|
+
do {
|
|
4591
|
+
if (!lm) {
|
|
4592
|
+
final = bits(dat, pos, 1);
|
|
4593
|
+
var type = bits(dat, pos + 1, 3);
|
|
4594
|
+
pos += 3;
|
|
4595
|
+
if (!type) {
|
|
4596
|
+
var s = shft(pos) + 4, l = dat[s - 4] | dat[s - 3] << 8, t = s + l;
|
|
4597
|
+
if (t > sl) {
|
|
4598
|
+
if (noSt)
|
|
4599
|
+
err(0);
|
|
4600
|
+
break;
|
|
4601
|
+
}
|
|
4602
|
+
if (resize)
|
|
4603
|
+
cbuf(bt + l);
|
|
4604
|
+
buf.set(dat.subarray(s, t), bt);
|
|
4605
|
+
st.b = bt += l, st.p = pos = t * 8, st.f = final;
|
|
4606
|
+
continue;
|
|
4607
|
+
} else if (type == 1)
|
|
4608
|
+
lm = flrm, dm = fdrm, lbt = 9, dbt = 5;
|
|
4609
|
+
else if (type == 2) {
|
|
4610
|
+
var hLit = bits(dat, pos, 31) + 257, hcLen = bits(dat, pos + 10, 15) + 4;
|
|
4611
|
+
var tl = hLit + bits(dat, pos + 5, 31) + 1;
|
|
4612
|
+
pos += 14;
|
|
4613
|
+
var ldt = new u8(tl);
|
|
4614
|
+
var clt = new u8(19);
|
|
4615
|
+
for (var i2 = 0;i2 < hcLen; ++i2) {
|
|
4616
|
+
clt[clim[i2]] = bits(dat, pos + i2 * 3, 7);
|
|
4617
|
+
}
|
|
4618
|
+
pos += hcLen * 3;
|
|
4619
|
+
var clb = max(clt), clbmsk = (1 << clb) - 1;
|
|
4620
|
+
var clm = hMap(clt, clb, 1);
|
|
4621
|
+
for (var i2 = 0;i2 < tl; ) {
|
|
4622
|
+
var r = clm[bits(dat, pos, clbmsk)];
|
|
4623
|
+
pos += r & 15;
|
|
4624
|
+
var s = r >> 4;
|
|
4625
|
+
if (s < 16) {
|
|
4626
|
+
ldt[i2++] = s;
|
|
4627
|
+
} else {
|
|
4628
|
+
var c = 0, n = 0;
|
|
4629
|
+
if (s == 16)
|
|
4630
|
+
n = 3 + bits(dat, pos, 3), pos += 2, c = ldt[i2 - 1];
|
|
4631
|
+
else if (s == 17)
|
|
4632
|
+
n = 3 + bits(dat, pos, 7), pos += 3;
|
|
4633
|
+
else if (s == 18)
|
|
4634
|
+
n = 11 + bits(dat, pos, 127), pos += 7;
|
|
4635
|
+
while (n--)
|
|
4636
|
+
ldt[i2++] = c;
|
|
4637
|
+
}
|
|
4638
|
+
}
|
|
4639
|
+
var lt = ldt.subarray(0, hLit), dt = ldt.subarray(hLit);
|
|
4640
|
+
lbt = max(lt);
|
|
4641
|
+
dbt = max(dt);
|
|
4642
|
+
lm = hMap(lt, lbt, 1);
|
|
4643
|
+
dm = hMap(dt, dbt, 1);
|
|
4644
|
+
} else
|
|
4645
|
+
err(1);
|
|
4646
|
+
if (pos > tbts) {
|
|
4647
|
+
if (noSt)
|
|
4648
|
+
err(0);
|
|
4649
|
+
break;
|
|
4650
|
+
}
|
|
4651
|
+
}
|
|
4652
|
+
if (resize)
|
|
4653
|
+
cbuf(bt + 131072);
|
|
4654
|
+
var lms = (1 << lbt) - 1, dms = (1 << dbt) - 1;
|
|
4655
|
+
var lpos = pos;
|
|
4656
|
+
for (;; lpos = pos) {
|
|
4657
|
+
var c = lm[bits16(dat, pos) & lms], sym = c >> 4;
|
|
4658
|
+
pos += c & 15;
|
|
4659
|
+
if (pos > tbts) {
|
|
4660
|
+
if (noSt)
|
|
4661
|
+
err(0);
|
|
4662
|
+
break;
|
|
4663
|
+
}
|
|
4664
|
+
if (!c)
|
|
4665
|
+
err(2);
|
|
4666
|
+
if (sym < 256)
|
|
4667
|
+
buf[bt++] = sym;
|
|
4668
|
+
else if (sym == 256) {
|
|
4669
|
+
lpos = pos, lm = null;
|
|
4670
|
+
break;
|
|
4671
|
+
} else {
|
|
4672
|
+
var add = sym - 254;
|
|
4673
|
+
if (sym > 264) {
|
|
4674
|
+
var i2 = sym - 257, b = fleb[i2];
|
|
4675
|
+
add = bits(dat, pos, (1 << b) - 1) + fl[i2];
|
|
4676
|
+
pos += b;
|
|
4677
|
+
}
|
|
4678
|
+
var d = dm[bits16(dat, pos) & dms], dsym = d >> 4;
|
|
4679
|
+
if (!d)
|
|
4680
|
+
err(3);
|
|
4681
|
+
pos += d & 15;
|
|
4682
|
+
var dt = fd[dsym];
|
|
4683
|
+
if (dsym > 3) {
|
|
4684
|
+
var b = fdeb[dsym];
|
|
4685
|
+
dt += bits16(dat, pos) & (1 << b) - 1, pos += b;
|
|
4686
|
+
}
|
|
4687
|
+
if (pos > tbts) {
|
|
4688
|
+
if (noSt)
|
|
4689
|
+
err(0);
|
|
4690
|
+
break;
|
|
4691
|
+
}
|
|
4692
|
+
if (resize)
|
|
4693
|
+
cbuf(bt + 131072);
|
|
4694
|
+
var end = bt + add;
|
|
4695
|
+
if (bt < dt) {
|
|
4696
|
+
var shift = dl - dt, dend = Math.min(dt, end);
|
|
4697
|
+
if (shift + bt < 0)
|
|
4698
|
+
err(3);
|
|
4699
|
+
for (;bt < dend; ++bt)
|
|
4700
|
+
buf[bt] = dict[shift + bt];
|
|
4701
|
+
}
|
|
4702
|
+
for (;bt < end; ++bt)
|
|
4703
|
+
buf[bt] = buf[bt - dt];
|
|
4704
|
+
}
|
|
4705
|
+
}
|
|
4706
|
+
st.l = lm, st.p = lpos, st.b = bt, st.f = final;
|
|
4707
|
+
if (lm)
|
|
4708
|
+
final = 1, st.m = lbt, st.d = dm, st.n = dbt;
|
|
4709
|
+
} while (!final);
|
|
4710
|
+
return bt != buf.length && noBuf ? slc(buf, 0, bt) : buf.subarray(0, bt);
|
|
4106
4711
|
}, wbits = function(d, p, v) {
|
|
4107
4712
|
v <<= p & 7;
|
|
4108
4713
|
var o = p / 8 | 0;
|
|
@@ -4426,6 +5031,12 @@ var require2, _a, Worker2, isMarkedAsUntransferable, u8, u16, i32, fleb, fdeb, c
|
|
|
4426
5031
|
for (var k in b)
|
|
4427
5032
|
o[k] = b[k];
|
|
4428
5033
|
return o;
|
|
5034
|
+
}, b2 = function(d, b) {
|
|
5035
|
+
return d[b] | d[b + 1] << 8;
|
|
5036
|
+
}, b4 = function(d, b) {
|
|
5037
|
+
return (d[b] | d[b + 1] << 8 | d[b + 2] << 16 | d[b + 3] << 24) >>> 0;
|
|
5038
|
+
}, b8 = function(d, b) {
|
|
5039
|
+
return b4(d, b) + b4(d, b + 4) * 4294967296;
|
|
4429
5040
|
}, wbytes = function(d, b, v) {
|
|
4430
5041
|
for (;v; ++b)
|
|
4431
5042
|
d[b] = v, v >>>= 8;
|
|
@@ -4441,7 +5052,46 @@ var require2, _a, Worker2, isMarkedAsUntransferable, u8, u16, i32, fleb, fdeb, c
|
|
|
4441
5052
|
fltn(val, n, t, o);
|
|
4442
5053
|
}
|
|
4443
5054
|
}
|
|
4444
|
-
}, te, td, tds = 0,
|
|
5055
|
+
}, te, td, tds = 0, dutf8 = function(d) {
|
|
5056
|
+
for (var r = "", i2 = 0;; ) {
|
|
5057
|
+
var c = d[i2++];
|
|
5058
|
+
var eb = (c > 127) + (c > 223) + (c > 239);
|
|
5059
|
+
if (i2 + eb > d.length)
|
|
5060
|
+
return { s: r, r: slc(d, i2 - 1) };
|
|
5061
|
+
if (!eb)
|
|
5062
|
+
r += String.fromCharCode(c);
|
|
5063
|
+
else if (eb == 3) {
|
|
5064
|
+
c = ((c & 15) << 18 | (d[i2++] & 63) << 12 | (d[i2++] & 63) << 6 | d[i2++] & 63) - 65536, r += String.fromCharCode(55296 | c >> 10, 56320 | c & 1023);
|
|
5065
|
+
} else if (eb & 1)
|
|
5066
|
+
r += String.fromCharCode((c & 31) << 6 | d[i2++] & 63);
|
|
5067
|
+
else
|
|
5068
|
+
r += String.fromCharCode((c & 15) << 12 | (d[i2++] & 63) << 6 | d[i2++] & 63);
|
|
5069
|
+
}
|
|
5070
|
+
}, slzh = function(d, b) {
|
|
5071
|
+
return b + 30 + b2(d, b + 26) + b2(d, b + 28);
|
|
5072
|
+
}, zh = function(d, b, z) {
|
|
5073
|
+
var fnl = b2(d, b + 28), efl = b2(d, b + 30), fn = strFromU8(d.subarray(b + 46, b + 46 + fnl), !(b2(d, b + 8) & 2048)), es = b + 46 + fnl;
|
|
5074
|
+
var _a2 = z64hs(d, es, efl, z, b4(d, b + 20), b4(d, b + 24), b4(d, b + 42)), sc = _a2[0], su = _a2[1], off = _a2[2];
|
|
5075
|
+
return [b2(d, b + 10), sc, su, fn, es + efl + b2(d, b + 32), off];
|
|
5076
|
+
}, z64hs = function(d, b, l, z, sc, su, off) {
|
|
5077
|
+
var nsc = sc == 4294967295, nsu = su == 4294967295, noff = off == 4294967295, e = b + l;
|
|
5078
|
+
var nf = nsc + nsu + noff;
|
|
5079
|
+
if (z && nf) {
|
|
5080
|
+
for (;b + 4 < e; b += 4 + b2(d, b + 2)) {
|
|
5081
|
+
if (b2(d, b) == 1) {
|
|
5082
|
+
return [
|
|
5083
|
+
nsc ? b8(d, b + 4 + 8 * nsu) : sc,
|
|
5084
|
+
nsu ? b8(d, b + 4) : su,
|
|
5085
|
+
noff ? b8(d, b + 4 + 8 * (nsu + nsc)) : off,
|
|
5086
|
+
1
|
|
5087
|
+
];
|
|
5088
|
+
}
|
|
5089
|
+
}
|
|
5090
|
+
if (z < 2)
|
|
5091
|
+
err(13);
|
|
5092
|
+
}
|
|
5093
|
+
return [sc, su, off, 0];
|
|
5094
|
+
}, exfl = function(ex) {
|
|
4445
5095
|
var le = 0;
|
|
4446
5096
|
if (ex) {
|
|
4447
5097
|
for (var k in ex) {
|
|
@@ -4535,7 +5185,9 @@ var init_esm = __esm(() => {
|
|
|
4535
5185
|
for (i = 0;i < 32; ++i)
|
|
4536
5186
|
fdt[i] = 5;
|
|
4537
5187
|
flm = /* @__PURE__ */ hMap(flt, 9, 0);
|
|
5188
|
+
flrm = /* @__PURE__ */ hMap(flt, 9, 1);
|
|
4538
5189
|
fdm = /* @__PURE__ */ hMap(fdt, 5, 0);
|
|
5190
|
+
fdrm = /* @__PURE__ */ hMap(fdt, 5, 1);
|
|
4539
5191
|
ec = [
|
|
4540
5192
|
"unexpected EOF",
|
|
4541
5193
|
"invalid block type",
|
|
@@ -9083,7 +9735,7 @@ function validateInputOption(opts) {
|
|
|
9083
9735
|
}
|
|
9084
9736
|
validateInputObject(opts.input);
|
|
9085
9737
|
}
|
|
9086
|
-
function
|
|
9738
|
+
function requireImage2(images, model) {
|
|
9087
9739
|
const image = images[0];
|
|
9088
9740
|
if (!image?.url) {
|
|
9089
9741
|
throw new GenerateImageError(`fal returned no image for model ${model}`);
|
|
@@ -9425,7 +10077,7 @@ async function generateAndSave(deps, model, input, outPath) {
|
|
|
9425
10077
|
if (result.data.images.length > 1) {
|
|
9426
10078
|
deps.warn(`⚠️ fal returned ${result.data.images.length} images; only the first is saved.`);
|
|
9427
10079
|
}
|
|
9428
|
-
const image =
|
|
10080
|
+
const image = requireImage2(result.data.images, model);
|
|
9429
10081
|
const bytes = await downloadImage(deps, result.requestId, image.url);
|
|
9430
10082
|
await saveImage(deps, outPath, bytes, result.requestId, image.url);
|
|
9431
10083
|
return {
|
|
@@ -9870,6 +10522,109 @@ var init_deps2 = __esm(() => {
|
|
|
9870
10522
|
GLB_MAGIC = [103, 108, 84, 70];
|
|
9871
10523
|
});
|
|
9872
10524
|
|
|
10525
|
+
// src/commands/generate-3d/checks.ts
|
|
10526
|
+
function formatMean(mean) {
|
|
10527
|
+
return mean.toFixed(2);
|
|
10528
|
+
}
|
|
10529
|
+
function isWholeTextureMetal(material) {
|
|
10530
|
+
if (material.metal === null) {
|
|
10531
|
+
return !material.hasMetallicRoughnessTexture && material.metallicFactor >= CHECK_THRESHOLDS.wholeTextureMetalFraction;
|
|
10532
|
+
}
|
|
10533
|
+
return material.metallicFactor > 0 && material.metal.fractionAtLeastHalf >= CHECK_THRESHOLDS.wholeTextureMetalFraction;
|
|
10534
|
+
}
|
|
10535
|
+
function metalWholeTextureFor(material) {
|
|
10536
|
+
if (!isWholeTextureMetal(material))
|
|
10537
|
+
return null;
|
|
10538
|
+
return {
|
|
10539
|
+
id: "metal-whole-texture",
|
|
10540
|
+
severity: "warning",
|
|
10541
|
+
materialIndex: material.index,
|
|
10542
|
+
message: `Material ${material.index} looks metal across its whole surface; check that the surface really is metal.`
|
|
10543
|
+
};
|
|
10544
|
+
}
|
|
10545
|
+
function flatChecks(analysis) {
|
|
10546
|
+
const largest = Math.max(...analysis.extents);
|
|
10547
|
+
if (largest <= 0)
|
|
10548
|
+
return [];
|
|
10549
|
+
const ratio = Math.min(...analysis.extents) / largest;
|
|
10550
|
+
if (ratio >= CHECK_THRESHOLDS.flatRatio)
|
|
10551
|
+
return [];
|
|
10552
|
+
return [
|
|
10553
|
+
{
|
|
10554
|
+
id: "flat",
|
|
10555
|
+
severity: "warning",
|
|
10556
|
+
materialIndex: null,
|
|
10557
|
+
message: "Model is flat (thickness is under 5% of its width); a flat model may disappear from some angles."
|
|
10558
|
+
}
|
|
10559
|
+
];
|
|
10560
|
+
}
|
|
10561
|
+
function feetChecks(analysis) {
|
|
10562
|
+
const height = analysis.bounds.max[1] - analysis.bounds.min[1];
|
|
10563
|
+
const offset = Math.abs(analysis.bounds.min[1]);
|
|
10564
|
+
if (offset <= CHECK_THRESHOLDS.feetShare * height)
|
|
10565
|
+
return [];
|
|
10566
|
+
return [
|
|
10567
|
+
{
|
|
10568
|
+
id: "not-on-feet",
|
|
10569
|
+
severity: "warning",
|
|
10570
|
+
materialIndex: null,
|
|
10571
|
+
message: `Model's base is not at the origin. Use --origin feet to move the base to the origin.`
|
|
10572
|
+
}
|
|
10573
|
+
];
|
|
10574
|
+
}
|
|
10575
|
+
function hasChannels(material) {
|
|
10576
|
+
return material.metal !== null && material.roughness !== null;
|
|
10577
|
+
}
|
|
10578
|
+
function texturedGlossy(material) {
|
|
10579
|
+
if (!hasChannels(material))
|
|
10580
|
+
return null;
|
|
10581
|
+
if (material.metal.fractionAtLeastHalf >= NON_METAL_FRACTION_MAX)
|
|
10582
|
+
return null;
|
|
10583
|
+
const value = material.roughness.mean * material.roughnessFactor;
|
|
10584
|
+
return value < CHECK_THRESHOLDS.glossyRoughnessMean ? { value, label: "mean" } : null;
|
|
10585
|
+
}
|
|
10586
|
+
function untexturedGlossy(material) {
|
|
10587
|
+
if (material.metallicFactor >= NON_METAL_FACTOR_MAX)
|
|
10588
|
+
return null;
|
|
10589
|
+
return material.roughnessFactor < CHECK_THRESHOLDS.glossyRoughnessMean ? { value: material.roughnessFactor, label: "factor" } : null;
|
|
10590
|
+
}
|
|
10591
|
+
function glossyValue(material) {
|
|
10592
|
+
return material.hasMetallicRoughnessTexture ? texturedGlossy(material) : untexturedGlossy(material);
|
|
10593
|
+
}
|
|
10594
|
+
function glossyFor(material) {
|
|
10595
|
+
const glossy = glossyValue(material);
|
|
10596
|
+
if (glossy === null)
|
|
10597
|
+
return null;
|
|
10598
|
+
return {
|
|
10599
|
+
id: "glossy-non-metal",
|
|
10600
|
+
severity: "warning",
|
|
10601
|
+
materialIndex: material.index,
|
|
10602
|
+
message: `Material ${material.index} is non-metal with low roughness (${glossy.label} ${formatMean(glossy.value)}); it may look glossy or metallic under light.`
|
|
10603
|
+
};
|
|
10604
|
+
}
|
|
10605
|
+
function computeChecks(analysis) {
|
|
10606
|
+
const checks = [...flatChecks(analysis), ...feetChecks(analysis)];
|
|
10607
|
+
for (const material of analysis.materials) {
|
|
10608
|
+
const metal = metalWholeTextureFor(material);
|
|
10609
|
+
if (metal !== null)
|
|
10610
|
+
checks.push(metal);
|
|
10611
|
+
const glossy = glossyFor(material);
|
|
10612
|
+
if (glossy !== null)
|
|
10613
|
+
checks.push(glossy);
|
|
10614
|
+
}
|
|
10615
|
+
return checks;
|
|
10616
|
+
}
|
|
10617
|
+
var CHECK_THRESHOLDS, NON_METAL_FACTOR_MAX = 0.5;
|
|
10618
|
+
var init_checks = __esm(() => {
|
|
10619
|
+
init_material_normalise();
|
|
10620
|
+
CHECK_THRESHOLDS = {
|
|
10621
|
+
wholeTextureMetalFraction: 0.5,
|
|
10622
|
+
flatRatio: 0.05,
|
|
10623
|
+
feetShare: 0.01,
|
|
10624
|
+
glossyRoughnessMean: 0.35
|
|
10625
|
+
};
|
|
10626
|
+
});
|
|
10627
|
+
|
|
9873
10628
|
// src/commands/generate-3d/package-name.ts
|
|
9874
10629
|
function sanitizeNamePart(value) {
|
|
9875
10630
|
return value.replace(/[^A-Za-z0-9._-]+/g, "-").replace(/^[^A-Za-z0-9]+/, "");
|
|
@@ -9910,10 +10665,59 @@ function formatCount(count) {
|
|
|
9910
10665
|
function captionRow(label, value) {
|
|
9911
10666
|
return ` <dt>${label}</dt><dd>${value}</dd>`;
|
|
9912
10667
|
}
|
|
10668
|
+
function variantButton(variant, pressed, label) {
|
|
10669
|
+
return ` <button type="button" class="variant" data-variant="${variant}" aria-pressed="${pressed}">${label}</button>`;
|
|
10670
|
+
}
|
|
10671
|
+
function lightingButton(mode, pressed) {
|
|
10672
|
+
const label = mode === "studio" ? "Studio" : mode === "directional" ? "Directional" : "Unlit";
|
|
10673
|
+
return ` <button type="button" class="lighting-option" data-lighting="${mode}" aria-pressed="${pressed}">${label}</button>`;
|
|
10674
|
+
}
|
|
10675
|
+
function checksPanel(checks, note) {
|
|
10676
|
+
if (note !== undefined && note !== null) {
|
|
10677
|
+
return ` <p class="ok">${escapeHtml(note)}</p>`;
|
|
10678
|
+
}
|
|
10679
|
+
if (checks.length === 0) {
|
|
10680
|
+
return ` <p class="ok">No issues found.</p>`;
|
|
10681
|
+
}
|
|
10682
|
+
const items = checks.map((check) => ` <li data-check="${escapeHtml(check.id)}">${escapeHtml(check.message)}</li>`).join(`
|
|
10683
|
+
`);
|
|
10684
|
+
return ` <ul>
|
|
10685
|
+
${items}
|
|
10686
|
+
</ul>`;
|
|
10687
|
+
}
|
|
10688
|
+
function glbDataUri(glb) {
|
|
10689
|
+
return `data:model/gltf-binary;base64,${Buffer.from(glb).toString("base64")}`;
|
|
10690
|
+
}
|
|
10691
|
+
function isSunTexel(x2, y) {
|
|
10692
|
+
const dx = x2 - Math.round(ENVIRONMENT_WIDTH * 0.75);
|
|
10693
|
+
const dy = y - Math.round(ENVIRONMENT_HEIGHT * 0.7);
|
|
10694
|
+
return dx * dx + dy * dy <= SUN_RADIUS_PX * SUN_RADIUS_PX;
|
|
10695
|
+
}
|
|
10696
|
+
async function directionalEnvironmentPng() {
|
|
10697
|
+
const { default: sharp } = await import("sharp");
|
|
10698
|
+
const pixels = new Uint8Array(ENVIRONMENT_WIDTH * ENVIRONMENT_HEIGHT * 4);
|
|
10699
|
+
for (let index = 0;index < pixels.length; index += 4) {
|
|
10700
|
+
pixels[index + 3] = 255;
|
|
10701
|
+
const texel = index / 4;
|
|
10702
|
+
const x2 = texel % ENVIRONMENT_WIDTH;
|
|
10703
|
+
const y = Math.floor(texel / ENVIRONMENT_WIDTH);
|
|
10704
|
+
if (!isSunTexel(x2, y))
|
|
10705
|
+
continue;
|
|
10706
|
+
pixels[index] = 255;
|
|
10707
|
+
pixels[index + 1] = 255;
|
|
10708
|
+
pixels[index + 2] = 255;
|
|
10709
|
+
}
|
|
10710
|
+
const png = await sharp(Buffer.from(pixels), {
|
|
10711
|
+
raw: { width: ENVIRONMENT_WIDTH, height: ENVIRONMENT_HEIGHT, channels: 4 }
|
|
10712
|
+
}).png().toBuffer();
|
|
10713
|
+
return new Uint8Array(png);
|
|
10714
|
+
}
|
|
9913
10715
|
function renderPreviewHtml(input) {
|
|
9914
10716
|
const title = escapeHtml(input.title);
|
|
9915
10717
|
const prompt = input.prompt === null ? "Not specified." : escapeHtml(input.prompt);
|
|
9916
|
-
const
|
|
10718
|
+
const masterDataUri = glbDataUri(input.masterGlb);
|
|
10719
|
+
const webDataUri = glbDataUri(input.webGlb);
|
|
10720
|
+
const directionalEnvironment = `data:image/png;base64,${Buffer.from(input.directionalEnvironmentPng).toString("base64")}`;
|
|
9917
10721
|
const rows = [
|
|
9918
10722
|
captionRow("Model id", escapeHtml(input.modelId)),
|
|
9919
10723
|
captionRow("Prompt", prompt),
|
|
@@ -9924,6 +10728,20 @@ function renderPreviewHtml(input) {
|
|
|
9924
10728
|
captionRow("Master file", `${escapeHtml(input.masterZipEntry)} (in ${escapeHtml(input.zipName)})`)
|
|
9925
10729
|
].join(`
|
|
9926
10730
|
`);
|
|
10731
|
+
const masterLabel = `Full resolution (master, ${formatBytes(input.masterBytes)}, ${formatCount(input.masterTriangles)} triangles)`;
|
|
10732
|
+
const webLabel = `Scaled down (web, ${formatBytes(input.webBytes)}, ${formatCount(input.webTriangles)} triangles)`;
|
|
10733
|
+
const variantButtons = [
|
|
10734
|
+
variantButton("master", false, masterLabel),
|
|
10735
|
+
variantButton("web", true, webLabel)
|
|
10736
|
+
].join(`
|
|
10737
|
+
`);
|
|
10738
|
+
const lightingButtons = [
|
|
10739
|
+
lightingButton("studio", true),
|
|
10740
|
+
lightingButton("directional", false),
|
|
10741
|
+
lightingButton("unlit", false)
|
|
10742
|
+
].join(`
|
|
10743
|
+
`);
|
|
10744
|
+
const checks = checksPanel(input.checks, input.checksNote);
|
|
9927
10745
|
return `<!DOCTYPE html>
|
|
9928
10746
|
<html lang="en">
|
|
9929
10747
|
<head>
|
|
@@ -9939,15 +10757,109 @@ function renderPreviewHtml(input) {
|
|
|
9939
10757
|
${rows}
|
|
9940
10758
|
</dl>
|
|
9941
10759
|
</div>
|
|
10760
|
+
<section class="checks">
|
|
10761
|
+
<h2>Checks</h2>
|
|
10762
|
+
${checks}
|
|
10763
|
+
</section>
|
|
10764
|
+
<div class="variants" role="group" aria-label="Variant">
|
|
10765
|
+
${variantButtons}
|
|
10766
|
+
</div>
|
|
10767
|
+
<div class="lighting" role="group" aria-label="Lighting">
|
|
10768
|
+
${lightingButtons}
|
|
10769
|
+
</div>
|
|
9942
10770
|
<model-viewer
|
|
9943
|
-
src="${
|
|
10771
|
+
src="${webDataUri}"
|
|
10772
|
+
data-master-src="${masterDataUri}"
|
|
10773
|
+
data-directional-environment="${directionalEnvironment}"
|
|
9944
10774
|
alt="${title} preview"
|
|
9945
10775
|
camera-controls
|
|
9946
10776
|
auto-rotate
|
|
9947
10777
|
shadow-intensity="1"
|
|
9948
10778
|
exposure="1"
|
|
9949
10779
|
touch-action="pan-y"></model-viewer>
|
|
9950
|
-
<p class="note">
|
|
10780
|
+
<p class="note">Switch between the full-resolution master and the scaled-down web variant, and between Studio, Directional, and Unlit lighting. Drag to orbit, scroll to zoom.</p>
|
|
10781
|
+
<script>
|
|
10782
|
+
const viewer = document.querySelector('model-viewer');
|
|
10783
|
+
const variants = {
|
|
10784
|
+
master: viewer.getAttribute('data-master-src'),
|
|
10785
|
+
web: viewer.getAttribute('src'),
|
|
10786
|
+
};
|
|
10787
|
+
const directionalEnvironment = viewer.getAttribute('data-directional-environment');
|
|
10788
|
+
let lighting = 'studio';
|
|
10789
|
+
|
|
10790
|
+
const unlitState = new WeakMap();
|
|
10791
|
+
|
|
10792
|
+
function materialsOf() {
|
|
10793
|
+
const model = viewer.model;
|
|
10794
|
+
return model && model.materials ? model.materials : [];
|
|
10795
|
+
}
|
|
10796
|
+
|
|
10797
|
+
function setUnlit(enabled) {
|
|
10798
|
+
for (const material of materialsOf()) {
|
|
10799
|
+
const pbr = material.pbrMetallicRoughness;
|
|
10800
|
+
if (!pbr || !material.emissiveTexture) continue;
|
|
10801
|
+
const saved = unlitState.get(material);
|
|
10802
|
+
if (enabled) {
|
|
10803
|
+
const state = saved || {
|
|
10804
|
+
baseColorFactor: [...pbr.baseColorFactor],
|
|
10805
|
+
metallicFactor: pbr.metallicFactor,
|
|
10806
|
+
roughnessFactor: pbr.roughnessFactor,
|
|
10807
|
+
emissiveFactor: [...material.emissiveFactor],
|
|
10808
|
+
emissiveStrength: material.emissiveStrength,
|
|
10809
|
+
emissiveTexture: material.emissiveTexture.texture,
|
|
10810
|
+
};
|
|
10811
|
+
unlitState.set(material, state);
|
|
10812
|
+
const base = pbr.baseColorTexture ? pbr.baseColorTexture.texture : null;
|
|
10813
|
+
pbr.setBaseColorFactor([0, 0, 0, 1]);
|
|
10814
|
+
pbr.setMetallicFactor(0);
|
|
10815
|
+
pbr.setRoughnessFactor(1);
|
|
10816
|
+
material.setEmissiveStrength(1);
|
|
10817
|
+
material.emissiveTexture.setTexture(base);
|
|
10818
|
+
material.setEmissiveFactor(state.baseColorFactor.slice(0, 3));
|
|
10819
|
+
} else if (saved) {
|
|
10820
|
+
pbr.setBaseColorFactor(saved.baseColorFactor);
|
|
10821
|
+
pbr.setMetallicFactor(saved.metallicFactor);
|
|
10822
|
+
pbr.setRoughnessFactor(saved.roughnessFactor);
|
|
10823
|
+
material.setEmissiveFactor(saved.emissiveFactor);
|
|
10824
|
+
material.setEmissiveStrength(saved.emissiveStrength);
|
|
10825
|
+
material.emissiveTexture.setTexture(saved.emissiveTexture);
|
|
10826
|
+
unlitState.delete(material);
|
|
10827
|
+
}
|
|
10828
|
+
}
|
|
10829
|
+
}
|
|
10830
|
+
|
|
10831
|
+
function applyLighting() {
|
|
10832
|
+
if (lighting === 'directional') {
|
|
10833
|
+
viewer.setAttribute('environment-image', directionalEnvironment);
|
|
10834
|
+
viewer.setAttribute('exposure', '20');
|
|
10835
|
+
} else {
|
|
10836
|
+
viewer.removeAttribute('environment-image');
|
|
10837
|
+
viewer.setAttribute('exposure', '1');
|
|
10838
|
+
}
|
|
10839
|
+
setUnlit(lighting === 'unlit');
|
|
10840
|
+
}
|
|
10841
|
+
|
|
10842
|
+
for (const button of document.querySelectorAll('button[data-variant]')) {
|
|
10843
|
+
button.addEventListener('click', () => {
|
|
10844
|
+
const name = button.getAttribute('data-variant');
|
|
10845
|
+
viewer.setAttribute('src', variants[name]);
|
|
10846
|
+
for (const other of document.querySelectorAll('button[data-variant]')) {
|
|
10847
|
+
other.setAttribute('aria-pressed', String(other === button));
|
|
10848
|
+
}
|
|
10849
|
+
});
|
|
10850
|
+
}
|
|
10851
|
+
for (const button of document.querySelectorAll('button[data-lighting]')) {
|
|
10852
|
+
button.addEventListener('click', () => {
|
|
10853
|
+
lighting = button.getAttribute('data-lighting');
|
|
10854
|
+
for (const other of document.querySelectorAll('button[data-lighting]')) {
|
|
10855
|
+
other.setAttribute('aria-pressed', String(other === button));
|
|
10856
|
+
}
|
|
10857
|
+
applyLighting();
|
|
10858
|
+
});
|
|
10859
|
+
}
|
|
10860
|
+
viewer.addEventListener('load', applyLighting);
|
|
10861
|
+
applyLighting();
|
|
10862
|
+
</script>
|
|
9951
10863
|
<script
|
|
9952
10864
|
type="module"
|
|
9953
10865
|
src="${MODEL_VIEWER_URL}"
|
|
@@ -9957,18 +10869,31 @@ ${rows}
|
|
|
9957
10869
|
</html>
|
|
9958
10870
|
`;
|
|
9959
10871
|
}
|
|
9960
|
-
var MODEL_VIEWER_URL = "https://cdn.jsdelivr.net/npm/@google/model-viewer@3.5.0/dist/model-viewer.min.js", MODEL_VIEWER_SRI = "sha384-Ftcjj/GNLxPvzNDftO/oryXB9aGxsGZY9JGqsXG0uUKgQDl9RfDgsx9NJ/4IVNPe", PANEL_STYLE = `
|
|
10872
|
+
var MODEL_VIEWER_URL = "https://cdn.jsdelivr.net/npm/@google/model-viewer@3.5.0/dist/model-viewer.min.js", MODEL_VIEWER_SRI = "sha384-Ftcjj/GNLxPvzNDftO/oryXB9aGxsGZY9JGqsXG0uUKgQDl9RfDgsx9NJ/4IVNPe", ENVIRONMENT_WIDTH = 512, ENVIRONMENT_HEIGHT = 256, SUN_RADIUS_PX = 10, PANEL_STYLE = `
|
|
9961
10873
|
:root { color-scheme: dark; }
|
|
9962
10874
|
body { margin: 0; padding: 24px; background: #111318; color: #e6e8ec;
|
|
9963
10875
|
font: 14px/1.5 ui-sans-serif, system-ui, -apple-system, sans-serif; }
|
|
9964
10876
|
h1 { margin: 0 0 16px; font-size: 18px; font-weight: 600; }
|
|
9965
|
-
.caption { margin: 0 0 16px; padding: 12px 16px; border: 1px solid #2a2f3a;
|
|
10877
|
+
.caption, .checks { margin: 0 0 16px; padding: 12px 16px; border: 1px solid #2a2f3a;
|
|
9966
10878
|
border-radius: 8px; background: #171a21; }
|
|
9967
10879
|
.caption dl { display: grid; grid-template-columns: max-content 1fr;
|
|
9968
10880
|
gap: 4px 16px; margin: 0; }
|
|
9969
10881
|
.caption dt { color: #9aa3b2; }
|
|
9970
10882
|
.caption dd { margin: 0; font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
|
|
9971
10883
|
font-size: 12px; word-break: break-word; }
|
|
10884
|
+
.checks h2 { margin: 0 0 8px; font-size: 14px; font-weight: 600; }
|
|
10885
|
+
.checks ul { margin: 0; padding-left: 20px; }
|
|
10886
|
+
.checks li { color: #f0c674; }
|
|
10887
|
+
.checks .ok { margin: 0; color: #9aa3b2; }
|
|
10888
|
+
.variants, .lighting { display: flex; flex-wrap: wrap; gap: 8px; margin: 0 0 16px; }
|
|
10889
|
+
.variants { margin-bottom: 8px; }
|
|
10890
|
+
.variant, .lighting-option { padding: 8px 12px; border: 1px solid #2a2f3a;
|
|
10891
|
+
border-radius: 8px; background: #171a21; color: #e6e8ec;
|
|
10892
|
+
font: inherit; cursor: pointer; }
|
|
10893
|
+
.variant[aria-pressed="true"], .lighting-option[aria-pressed="true"] {
|
|
10894
|
+
border-color: #6b8afd; background: #1d2436; }
|
|
10895
|
+
.variant:focus-visible, .lighting-option:focus-visible {
|
|
10896
|
+
outline: 2px solid #6b8afd; outline-offset: 2px; }
|
|
9972
10897
|
model-viewer { width: 100%; height: 70vh; min-height: 420px;
|
|
9973
10898
|
background: #0b0d11; border: 1px solid #2a2f3a; border-radius: 8px; }
|
|
9974
10899
|
.note { color: #9aa3b2; font-size: 12px; }
|
|
@@ -10095,6 +11020,8 @@ __export(exports_generate_3d, {
|
|
|
10095
11020
|
});
|
|
10096
11021
|
import { createHash as createHash3 } from "node:crypto";
|
|
10097
11022
|
import { basename, dirname as dirname4, extname as extname2, join as join2, resolve as resolve2 } from "node:path";
|
|
11023
|
+
import { NodeIO as NodeIO2 } from "@gltf-transform/core";
|
|
11024
|
+
import { ALL_EXTENSIONS as ALL_EXTENSIONS2 } from "@gltf-transform/extensions";
|
|
10098
11025
|
function outputStem(outPath) {
|
|
10099
11026
|
return outPath.slice(0, -GLB_EXTENSION.length);
|
|
10100
11027
|
}
|
|
@@ -10329,13 +11256,21 @@ function inputParts(ctx, capabilities) {
|
|
|
10329
11256
|
function rigParts(ctx) {
|
|
10330
11257
|
return passedFlags(ctx).filter((entry) => !INPUT_FLAG_NAMES.includes(entry.flag)).filter((entry) => isAllowed(entry.flag, ctx.model)).map(formatForCommand);
|
|
10331
11258
|
}
|
|
11259
|
+
function fitParts(fit) {
|
|
11260
|
+
if (fit === undefined)
|
|
11261
|
+
return [];
|
|
11262
|
+
return [
|
|
11263
|
+
...fit.targetHeight === undefined ? [] : [`--target-height ${fit.targetHeight}`],
|
|
11264
|
+
...fit.origin === "as-is" ? [] : [`--origin ${fit.origin}`]
|
|
11265
|
+
];
|
|
11266
|
+
}
|
|
10332
11267
|
function outputParts(ctx) {
|
|
10333
|
-
|
|
10334
|
-
|
|
10335
|
-
|
|
10336
|
-
|
|
10337
|
-
|
|
10338
|
-
|
|
11268
|
+
return [
|
|
11269
|
+
`--out ${shellQuote(ctx.out)}`,
|
|
11270
|
+
...ctx.force === true ? ["--force"] : [],
|
|
11271
|
+
...ctx.packageDir === undefined ? [] : [`--package-dir ${shellQuote(ctx.packageDir)}`],
|
|
11272
|
+
...fitParts(ctx.fit)
|
|
11273
|
+
];
|
|
10339
11274
|
}
|
|
10340
11275
|
function repeatParts(ctx) {
|
|
10341
11276
|
const dryRun = ctx.dryRun === true ? ["--dry-run"] : [];
|
|
@@ -10538,6 +11473,7 @@ function resolvePlanTarget(opts) {
|
|
|
10538
11473
|
out: opts.out,
|
|
10539
11474
|
force: opts.force,
|
|
10540
11475
|
packageDir: opts.packageDir,
|
|
11476
|
+
fit: opts.fit,
|
|
10541
11477
|
dryRun: opts.dryRun
|
|
10542
11478
|
};
|
|
10543
11479
|
validateRigging(flagContext);
|
|
@@ -10588,6 +11524,7 @@ async function planGenerate3d(opts, deps) {
|
|
|
10588
11524
|
inputKeys: Object.keys(opts.extraInput ?? {}),
|
|
10589
11525
|
modelWarning: modelWarningFor(model),
|
|
10590
11526
|
confirmCost: opts.confirmCost === true,
|
|
11527
|
+
fit: opts.fit,
|
|
10591
11528
|
...naming
|
|
10592
11529
|
};
|
|
10593
11530
|
}
|
|
@@ -10649,6 +11586,12 @@ function inputNoteLines(plan) {
|
|
|
10649
11586
|
function confirmationLines(plan) {
|
|
10650
11587
|
return plan.riggingRequest !== null && !plan.confirmCost ? ["Add --confirm-cost to run."] : [];
|
|
10651
11588
|
}
|
|
11589
|
+
function fitLines(plan) {
|
|
11590
|
+
if (plan.fit === undefined)
|
|
11591
|
+
return [];
|
|
11592
|
+
const height = plan.fit.targetHeight === undefined ? "no scale" : `target height ${plan.fit.targetHeight} m`;
|
|
11593
|
+
return [`Fit: ${height}, origin ${plan.fit.origin} (master, web, and rig outputs)`];
|
|
11594
|
+
}
|
|
10652
11595
|
function formatGenerate3dPlan(plan) {
|
|
10653
11596
|
return [
|
|
10654
11597
|
`Would generate ${plan.outPath}`,
|
|
@@ -10657,6 +11600,7 @@ function formatGenerate3dPlan(plan) {
|
|
|
10657
11600
|
`Preview ${plan.htmlPath}`,
|
|
10658
11601
|
...planModelLines(plan),
|
|
10659
11602
|
...modelWarningLines(plan),
|
|
11603
|
+
...fitLines(plan),
|
|
10660
11604
|
...formatReferencePlan(plan),
|
|
10661
11605
|
"Request:",
|
|
10662
11606
|
JSON.stringify(plan.input, null, 2),
|
|
@@ -10702,6 +11646,7 @@ function buildManifest2(args) {
|
|
|
10702
11646
|
output: {
|
|
10703
11647
|
path: args.outPath,
|
|
10704
11648
|
sha256: args.sha256,
|
|
11649
|
+
sourceSha256: args.sourceSha256,
|
|
10705
11650
|
bytes: args.byteLength,
|
|
10706
11651
|
contentType: GLB_CONTENT_TYPE
|
|
10707
11652
|
},
|
|
@@ -10725,21 +11670,29 @@ function riggingFailure(args) {
|
|
|
10725
11670
|
const request = args.requestId === null ? "" : ` for request ${args.requestId}`;
|
|
10726
11671
|
return new Generate3dError(`Rigging failed${request} (${args.endpoint}): ${args.detail}. The generated mesh and manifest are kept: ${args.meshPath}.`);
|
|
10727
11672
|
}
|
|
11673
|
+
async function prepareRigGlb(args) {
|
|
11674
|
+
return normaliseMasterGlb(args.downloaded, args.fit, args.sharedFit);
|
|
11675
|
+
}
|
|
10728
11676
|
async function downloadAndSaveGlb(args) {
|
|
10729
|
-
let
|
|
11677
|
+
let downloaded;
|
|
10730
11678
|
try {
|
|
10731
|
-
|
|
11679
|
+
downloaded = await args.deps.fetchGlb(args.url);
|
|
10732
11680
|
} catch (err2) {
|
|
10733
11681
|
throw args.fail(`Failed to download ${args.label} (${args.url}): ${describeError(err2)}`);
|
|
10734
11682
|
}
|
|
11683
|
+
const prepared = await prepareRigGlb({
|
|
11684
|
+
downloaded,
|
|
11685
|
+
fit: args.fit,
|
|
11686
|
+
sharedFit: args.sharedFit
|
|
11687
|
+
});
|
|
10735
11688
|
try {
|
|
10736
|
-
await args.deps.writeFile(args.path, bytes);
|
|
11689
|
+
await args.deps.writeFile(args.path, prepared.bytes);
|
|
10737
11690
|
} catch (err2) {
|
|
10738
11691
|
throw args.fail(`Failed to save ${args.label} ${args.path}: ${describeError(err2)}`);
|
|
10739
11692
|
}
|
|
10740
|
-
return
|
|
11693
|
+
return prepared;
|
|
10741
11694
|
}
|
|
10742
|
-
async function downloadAnimations(plan, deps, output, fail) {
|
|
11695
|
+
async function downloadAnimations(plan, deps, output, fail, sharedFit) {
|
|
10743
11696
|
const animations = [];
|
|
10744
11697
|
const files = [];
|
|
10745
11698
|
for (const [index, animation] of output.animations.entries()) {
|
|
@@ -10747,14 +11700,23 @@ async function downloadAnimations(plan, deps, output, fail) {
|
|
|
10747
11700
|
if (planned === undefined || planned.actionId !== animation.actionId) {
|
|
10748
11701
|
throw fail(`No planned output path for animation clip ${animation.actionId}.`);
|
|
10749
11702
|
}
|
|
10750
|
-
const
|
|
11703
|
+
const prepared = await downloadAndSaveGlb({
|
|
10751
11704
|
deps,
|
|
10752
11705
|
url: animation.glbUrl,
|
|
10753
11706
|
path: planned.path,
|
|
10754
11707
|
label: `animation clip ${animation.actionId}`,
|
|
10755
|
-
fail
|
|
11708
|
+
fail,
|
|
11709
|
+
fit: undefined,
|
|
11710
|
+
sharedFit
|
|
11711
|
+
});
|
|
11712
|
+
files.push({
|
|
11713
|
+
actionId: animation.actionId,
|
|
11714
|
+
path: planned.path,
|
|
11715
|
+
bytes: prepared.bytes,
|
|
11716
|
+
materials: prepared.materials,
|
|
11717
|
+
fit: prepared.fit,
|
|
11718
|
+
...definedErrors(prepared.normaliseError, prepared.fitError)
|
|
10756
11719
|
});
|
|
10757
|
-
files.push({ actionId: animation.actionId, path: planned.path, bytes });
|
|
10758
11720
|
animations.push({
|
|
10759
11721
|
actionId: animation.actionId,
|
|
10760
11722
|
path: planned.path,
|
|
@@ -10791,14 +11753,15 @@ async function runRigging(plan, deps, modelGlbUrl) {
|
|
|
10791
11753
|
} catch (err2) {
|
|
10792
11754
|
throw fail(describeError(err2));
|
|
10793
11755
|
}
|
|
10794
|
-
const
|
|
11756
|
+
const rigged = await downloadAndSaveGlb({
|
|
10795
11757
|
deps,
|
|
10796
11758
|
url: output.riggedGlbUrl,
|
|
10797
11759
|
path: riggedGlbPath,
|
|
10798
11760
|
label: "rigged GLB",
|
|
10799
|
-
fail
|
|
11761
|
+
fail,
|
|
11762
|
+
fit: plan.fit
|
|
10800
11763
|
});
|
|
10801
|
-
const animations = await downloadAnimations(plan, deps, output, fail);
|
|
11764
|
+
const animations = await downloadAnimations(plan, deps, output, fail, rigged.fit);
|
|
10802
11765
|
return {
|
|
10803
11766
|
section: {
|
|
10804
11767
|
endpoint: request.endpoint,
|
|
@@ -10812,7 +11775,10 @@ async function runRigging(plan, deps, modelGlbUrl) {
|
|
|
10812
11775
|
files: [],
|
|
10813
11776
|
costLines: riggingCostLines(plan.animationActionIds.length)
|
|
10814
11777
|
},
|
|
10815
|
-
riggedBytes,
|
|
11778
|
+
riggedBytes: rigged.bytes,
|
|
11779
|
+
riggedMaterials: rigged.materials,
|
|
11780
|
+
riggedFit: rigged.fit,
|
|
11781
|
+
...riggedErrorFields(rigged),
|
|
10816
11782
|
animations: animations.bytes
|
|
10817
11783
|
};
|
|
10818
11784
|
}
|
|
@@ -10828,7 +11794,10 @@ function rigEntryNames(stem, kind, actionId) {
|
|
|
10828
11794
|
async function buildOneRigFile(plan, deps, file) {
|
|
10829
11795
|
const names = rigEntryNames(plan.stem, file.kind, file.actionId);
|
|
10830
11796
|
try {
|
|
10831
|
-
const web = await deps.createWebVariant(file.bytes,
|
|
11797
|
+
const web = await deps.createWebVariant(file.bytes, webVariantOptions(plan, {
|
|
11798
|
+
materials: file.materials,
|
|
11799
|
+
fit: file.fit
|
|
11800
|
+
}));
|
|
10832
11801
|
return { packaged: { ...file, ...names, web, webError: null }, message: null };
|
|
10833
11802
|
} catch (err2) {
|
|
10834
11803
|
const message = describeError(err2);
|
|
@@ -10844,13 +11813,19 @@ function rigFileInputs(plan, rig) {
|
|
|
10844
11813
|
kind: "rigged",
|
|
10845
11814
|
actionId: null,
|
|
10846
11815
|
path: plan.riggedOutPath ?? "",
|
|
10847
|
-
bytes: rig.riggedBytes
|
|
11816
|
+
bytes: rig.riggedBytes,
|
|
11817
|
+
materials: rig.riggedMaterials,
|
|
11818
|
+
fit: rig.riggedFit,
|
|
11819
|
+
...definedErrors(rig.riggedNormaliseError, rig.riggedFitError)
|
|
10848
11820
|
},
|
|
10849
11821
|
...rig.animations.map((animation) => ({
|
|
10850
11822
|
kind: "animation",
|
|
10851
11823
|
actionId: animation.actionId,
|
|
10852
11824
|
path: animation.path,
|
|
10853
|
-
bytes: animation.bytes
|
|
11825
|
+
bytes: animation.bytes,
|
|
11826
|
+
materials: animation.materials,
|
|
11827
|
+
fit: animation.fit,
|
|
11828
|
+
...definedErrors(animation.normaliseError, animation.fitError)
|
|
10854
11829
|
}))
|
|
10855
11830
|
];
|
|
10856
11831
|
}
|
|
@@ -10878,6 +11853,9 @@ function rigFileManifestEntry(file) {
|
|
|
10878
11853
|
actionId: file.actionId,
|
|
10879
11854
|
path: file.path,
|
|
10880
11855
|
bytes: file.bytes.byteLength,
|
|
11856
|
+
materials: file.materials,
|
|
11857
|
+
fit: file.fit,
|
|
11858
|
+
...definedErrors(file.normaliseError, file.fitError),
|
|
10881
11859
|
webError: file.webError
|
|
10882
11860
|
};
|
|
10883
11861
|
if (file.web === null) {
|
|
@@ -10929,6 +11907,12 @@ function buildMasterVariant(args) {
|
|
|
10929
11907
|
file: `${args.stem}.glb`,
|
|
10930
11908
|
bytes: args.masterBytes.byteLength,
|
|
10931
11909
|
sha256: args.masterSha256,
|
|
11910
|
+
sourceSha256: args.sourceSha256,
|
|
11911
|
+
materials: args.materials,
|
|
11912
|
+
fit: args.fit,
|
|
11913
|
+
...args.normaliseError === undefined ? {} : { normaliseError: args.normaliseError },
|
|
11914
|
+
...args.fitError === undefined ? {} : { fitError: args.fitError },
|
|
11915
|
+
checks: args.checks,
|
|
10932
11916
|
triangles: args.source.triangles,
|
|
10933
11917
|
textures: args.source.textures,
|
|
10934
11918
|
extensionsUsed: args.source.extensionsUsed
|
|
@@ -10937,7 +11921,7 @@ function buildMasterVariant(args) {
|
|
|
10937
11921
|
function rigWebFailures(files) {
|
|
10938
11922
|
return files.filter((file) => file.webError !== null).map((file) => ({ file: file.entry, message: file.webError ?? "" }));
|
|
10939
11923
|
}
|
|
10940
|
-
function webSettings(web) {
|
|
11924
|
+
function webSettings(web, checks) {
|
|
10941
11925
|
return {
|
|
10942
11926
|
maxTexturePx: WEB_VARIANT_MAX_TEXTURE_PX,
|
|
10943
11927
|
textureFormat: "jpeg",
|
|
@@ -10945,7 +11929,10 @@ function webSettings(web) {
|
|
|
10945
11929
|
dataQuality: WEB_VARIANT_DATA_TEXTURE_QUALITY,
|
|
10946
11930
|
triangleTarget: WEB_VARIANT_TRIANGLE_TARGET,
|
|
10947
11931
|
simplified: web.simplified,
|
|
10948
|
-
skinnedPath: web.skinnedPath
|
|
11932
|
+
skinnedPath: web.skinnedPath,
|
|
11933
|
+
materials: web.materials,
|
|
11934
|
+
fit: web.fit,
|
|
11935
|
+
...checks === undefined ? {} : { checks }
|
|
10949
11936
|
};
|
|
10950
11937
|
}
|
|
10951
11938
|
function variantEntry(args) {
|
|
@@ -10962,14 +11949,14 @@ function variantEntry(args) {
|
|
|
10962
11949
|
...args.settings === undefined ? {} : { settings: args.settings }
|
|
10963
11950
|
};
|
|
10964
11951
|
}
|
|
10965
|
-
function buildWebVariantEntry(stem, web, webSha256) {
|
|
11952
|
+
function buildWebVariantEntry(stem, web, webSha256, checks) {
|
|
10966
11953
|
return {
|
|
10967
11954
|
...variantEntry({
|
|
10968
11955
|
name: "web",
|
|
10969
11956
|
file: `web/${stem}.web.glb`,
|
|
10970
11957
|
bytes: web.bytes,
|
|
10971
11958
|
stats: web,
|
|
10972
|
-
settings: webSettings(web)
|
|
11959
|
+
settings: webSettings(web, checks)
|
|
10973
11960
|
}),
|
|
10974
11961
|
sha256: webSha256
|
|
10975
11962
|
};
|
|
@@ -10997,9 +11984,14 @@ function buildPackageManifest(args) {
|
|
|
10997
11984
|
stem: args.stem,
|
|
10998
11985
|
masterBytes: args.masterBytes,
|
|
10999
11986
|
masterSha256: args.masterSha256,
|
|
11987
|
+
sourceSha256: args.masterSourceSha256,
|
|
11988
|
+
materials: args.masterMaterials,
|
|
11989
|
+
fit: args.masterFit,
|
|
11990
|
+
...args.masterErrors,
|
|
11991
|
+
checks: args.masterChecks,
|
|
11000
11992
|
source: args.web.source
|
|
11001
11993
|
}),
|
|
11002
|
-
buildWebVariantEntry(args.stem, args.web, args.webSha256),
|
|
11994
|
+
buildWebVariantEntry(args.stem, args.web, args.webSha256, args.webChecks),
|
|
11003
11995
|
...args.rigVariants
|
|
11004
11996
|
],
|
|
11005
11997
|
referenceImage: args.reference,
|
|
@@ -11027,9 +12019,16 @@ function buildPackageEntries(args) {
|
|
|
11027
12019
|
function packageFailure(plan, step, err2) {
|
|
11028
12020
|
return new Generate3dError(`Failed to ${step}: ${describeError(err2)}. The master mesh and manifest are kept: ${plan.outPath}.`);
|
|
11029
12021
|
}
|
|
11030
|
-
|
|
12022
|
+
function webVariantOptions(plan, processed) {
|
|
12023
|
+
return {
|
|
12024
|
+
...WEB_VARIANT_OPTIONS,
|
|
12025
|
+
...plan.fit === undefined ? {} : { fit: plan.fit },
|
|
12026
|
+
processed
|
|
12027
|
+
};
|
|
12028
|
+
}
|
|
12029
|
+
async function buildWebVariant(plan, deps, masterBytes, processed) {
|
|
11031
12030
|
try {
|
|
11032
|
-
return await deps.createWebVariant(masterBytes,
|
|
12031
|
+
return await deps.createWebVariant(masterBytes, webVariantOptions(plan, processed));
|
|
11033
12032
|
} catch (err2) {
|
|
11034
12033
|
throw packageFailure(plan, "build the web variant", err2);
|
|
11035
12034
|
}
|
|
@@ -11077,8 +12076,13 @@ async function writeZipAndPreview(plan, deps, files) {
|
|
|
11077
12076
|
}
|
|
11078
12077
|
async function writePackage(args) {
|
|
11079
12078
|
const { plan, deps, master, paths, reference } = args;
|
|
11080
|
-
const web = await buildWebVariant(plan, deps, master.bytes
|
|
12079
|
+
const web = await buildWebVariant(plan, deps, master.bytes, {
|
|
12080
|
+
materials: master.materials,
|
|
12081
|
+
fit: master.fit
|
|
12082
|
+
});
|
|
11081
12083
|
const webSha256 = createHash3("sha256").update(web.bytes).digest("hex");
|
|
12084
|
+
const webChecks = await checksForGlb(web.bytes);
|
|
12085
|
+
const directionalEnvironment = await directionalEnvironmentPng();
|
|
11082
12086
|
const packageManifest = buildPackageManifest({
|
|
11083
12087
|
packageName: args.packageName,
|
|
11084
12088
|
createdAt: deps.now().toISOString(),
|
|
@@ -11088,6 +12092,12 @@ async function writePackage(args) {
|
|
|
11088
12092
|
inputImage: master.inputImage,
|
|
11089
12093
|
masterBytes: master.bytes,
|
|
11090
12094
|
masterSha256: master.sha256,
|
|
12095
|
+
masterSourceSha256: master.sourceSha256,
|
|
12096
|
+
masterMaterials: master.materials,
|
|
12097
|
+
masterFit: master.fit,
|
|
12098
|
+
masterErrors: definedErrors(master.normaliseError, master.fitError),
|
|
12099
|
+
masterChecks: args.masterChecks,
|
|
12100
|
+
webChecks,
|
|
11091
12101
|
web,
|
|
11092
12102
|
webSha256,
|
|
11093
12103
|
stem: plan.stem,
|
|
@@ -11108,6 +12118,7 @@ async function writePackage(args) {
|
|
|
11108
12118
|
modelId: plan.model.id,
|
|
11109
12119
|
prompt: args.prompt?.trim() ?? null,
|
|
11110
12120
|
requestId: master.requestId,
|
|
12121
|
+
masterGlb: master.bytes,
|
|
11111
12122
|
webGlb: web.bytes,
|
|
11112
12123
|
webSha256,
|
|
11113
12124
|
webTriangles: web.triangles,
|
|
@@ -11115,7 +12126,9 @@ async function writePackage(args) {
|
|
|
11115
12126
|
masterBytes: master.bytes.byteLength,
|
|
11116
12127
|
webBytes: web.bytes.byteLength,
|
|
11117
12128
|
masterZipEntry: `${plan.stem}.glb`,
|
|
11118
|
-
zipName: `${args.packageName}.zip
|
|
12129
|
+
zipName: `${args.packageName}.zip`,
|
|
12130
|
+
checks: args.masterChecks,
|
|
12131
|
+
directionalEnvironmentPng: directionalEnvironment
|
|
11119
12132
|
});
|
|
11120
12133
|
await writeZipAndPreview(plan, deps, { ...paths, zipBytes, html, force: args.force });
|
|
11121
12134
|
return paths;
|
|
@@ -11168,6 +12181,112 @@ async function ensureOutputDirs(plan, deps) {
|
|
|
11168
12181
|
await deps.ensureParentDir(plan.outPath);
|
|
11169
12182
|
await deps.ensureParentDir(plan.zipPath);
|
|
11170
12183
|
}
|
|
12184
|
+
function glbIo() {
|
|
12185
|
+
return new NodeIO2().registerExtensions(ALL_EXTENSIONS2).registerDependencies({ "meshopt.decoder": MeshoptDecoder });
|
|
12186
|
+
}
|
|
12187
|
+
async function analyseGlb(glb) {
|
|
12188
|
+
return analyseDocument(await glbIo().readBinary(glb));
|
|
12189
|
+
}
|
|
12190
|
+
async function checksForGlb(glb) {
|
|
12191
|
+
try {
|
|
12192
|
+
return computeChecks(await analyseGlb(glb));
|
|
12193
|
+
} catch {
|
|
12194
|
+
return [];
|
|
12195
|
+
}
|
|
12196
|
+
}
|
|
12197
|
+
function sourceFallback(glb, errors) {
|
|
12198
|
+
return { bytes: glb, materials: [], fit: null, ...errors };
|
|
12199
|
+
}
|
|
12200
|
+
function dropMeshoptExtension(document2) {
|
|
12201
|
+
document2.getRoot().listExtensionsUsed().find((extension) => extension.extensionName === "EXT_meshopt_compression")?.dispose();
|
|
12202
|
+
}
|
|
12203
|
+
function definedErrors(normaliseError, fitError) {
|
|
12204
|
+
return {
|
|
12205
|
+
...normaliseError === undefined ? {} : { normaliseError },
|
|
12206
|
+
...fitError === undefined ? {} : { fitError }
|
|
12207
|
+
};
|
|
12208
|
+
}
|
|
12209
|
+
function riggedErrorFields(prepared) {
|
|
12210
|
+
return {
|
|
12211
|
+
...prepared.normaliseError === undefined ? {} : { riggedNormaliseError: prepared.normaliseError },
|
|
12212
|
+
...prepared.fitError === undefined ? {} : { riggedFitError: prepared.fitError }
|
|
12213
|
+
};
|
|
12214
|
+
}
|
|
12215
|
+
async function readGlbDocument(glb) {
|
|
12216
|
+
try {
|
|
12217
|
+
return { document: await glbIo().readBinary(glb) };
|
|
12218
|
+
} catch (err2) {
|
|
12219
|
+
return { normaliseError: `Normalisation failed: ${describeError(err2)}` };
|
|
12220
|
+
}
|
|
12221
|
+
}
|
|
12222
|
+
function defaultFitResult(analysis) {
|
|
12223
|
+
return {
|
|
12224
|
+
origin: "as-is",
|
|
12225
|
+
targetHeight: null,
|
|
12226
|
+
scale: 1,
|
|
12227
|
+
translation: [0, 0, 0],
|
|
12228
|
+
bounds: analysis.bounds
|
|
12229
|
+
};
|
|
12230
|
+
}
|
|
12231
|
+
function applySharedFit(document2, sharedFit) {
|
|
12232
|
+
if (sharedFit !== null)
|
|
12233
|
+
applyFitTransform(document2, sharedFit);
|
|
12234
|
+
return { fit: sharedFit };
|
|
12235
|
+
}
|
|
12236
|
+
async function fitByOptions(document2, analysis, fit) {
|
|
12237
|
+
if (fit === undefined)
|
|
12238
|
+
return { fit: defaultFitResult(analysis) };
|
|
12239
|
+
try {
|
|
12240
|
+
return { fit: await applyFit(document2, analysis, fit) };
|
|
12241
|
+
} catch (err2) {
|
|
12242
|
+
return { fitError: `Fit failed: ${describeError(err2)}` };
|
|
12243
|
+
}
|
|
12244
|
+
}
|
|
12245
|
+
async function prepareFit(document2, analysis, fit, sharedFit) {
|
|
12246
|
+
if (sharedFit !== undefined)
|
|
12247
|
+
return applySharedFit(document2, sharedFit);
|
|
12248
|
+
return fitByOptions(document2, analysis, fit);
|
|
12249
|
+
}
|
|
12250
|
+
async function prepareDocument(document2, fit, sharedFit) {
|
|
12251
|
+
let analysis;
|
|
12252
|
+
let materials;
|
|
12253
|
+
try {
|
|
12254
|
+
analysis = await analyseDocument(document2);
|
|
12255
|
+
materials = await normaliseMaterials(document2, analysis);
|
|
12256
|
+
} catch (err2) {
|
|
12257
|
+
return { normaliseError: `Normalisation failed: ${describeError(err2)}` };
|
|
12258
|
+
}
|
|
12259
|
+
const preparedFit = await prepareFit(document2, analysis, fit, sharedFit);
|
|
12260
|
+
if (!("fit" in preparedFit))
|
|
12261
|
+
return preparedFit;
|
|
12262
|
+
return { materials, fit: preparedFit.fit };
|
|
12263
|
+
}
|
|
12264
|
+
async function writePreparedDocument(io, document2) {
|
|
12265
|
+
try {
|
|
12266
|
+
return await io.writeBinary(document2);
|
|
12267
|
+
} catch {
|
|
12268
|
+
return null;
|
|
12269
|
+
}
|
|
12270
|
+
}
|
|
12271
|
+
async function normaliseMasterGlb(glb, fit, sharedFit) {
|
|
12272
|
+
const read = await readGlbDocument(glb);
|
|
12273
|
+
if ("normaliseError" in read)
|
|
12274
|
+
return sourceFallback(glb, read);
|
|
12275
|
+
dropMeshoptExtension(read.document);
|
|
12276
|
+
const prepared = await prepareDocument(read.document, fit, sharedFit);
|
|
12277
|
+
if (!("materials" in prepared))
|
|
12278
|
+
return sourceFallback(glb, prepared);
|
|
12279
|
+
const { prune } = await import("@gltf-transform/functions");
|
|
12280
|
+
read.document.setLogger(SILENT_LOGGER2);
|
|
12281
|
+
await read.document.transform(prune({ propertyTypes: ["Texture"], keepSolidTextures: true }));
|
|
12282
|
+
const bytes = await writePreparedDocument(glbIo(), read.document);
|
|
12283
|
+
if (bytes === null) {
|
|
12284
|
+
return sourceFallback(glb, {
|
|
12285
|
+
normaliseError: "Normalisation failed: the GLB could not be written back."
|
|
12286
|
+
});
|
|
12287
|
+
}
|
|
12288
|
+
return { bytes, materials: prepared.materials, fit: prepared.fit };
|
|
12289
|
+
}
|
|
11171
12290
|
async function generateMaster(plan, deps, opts, reference = null) {
|
|
11172
12291
|
const inputImage = reference?.inputImage ?? await uploadInputImage2(deps, plan.inputTarget);
|
|
11173
12292
|
const input = plan.model.buildInput({
|
|
@@ -11178,9 +12297,11 @@ async function generateMaster(plan, deps, opts, reference = null) {
|
|
|
11178
12297
|
const result = await deps.falSubscribe(plan.model.id, input);
|
|
11179
12298
|
const output = readModelOutput(plan.model, result.data, result.requestId);
|
|
11180
12299
|
const recovery = { requestId: result.requestId, url: output.glbUrl };
|
|
11181
|
-
const
|
|
11182
|
-
await
|
|
11183
|
-
|
|
12300
|
+
const sourceBytes = await withRecovery("download", recovery, () => deps.fetchGlb(output.glbUrl));
|
|
12301
|
+
const normalised = await normaliseMasterGlb(sourceBytes, plan.fit);
|
|
12302
|
+
await withRecovery("save", recovery, () => deps.writeFile(plan.outPath, normalised.bytes));
|
|
12303
|
+
const sourceSha256 = createHash3("sha256").update(sourceBytes).digest("hex");
|
|
12304
|
+
const sha2562 = createHash3("sha256").update(normalised.bytes).digest("hex");
|
|
11184
12305
|
const manifest = buildManifest2({
|
|
11185
12306
|
model: plan.model,
|
|
11186
12307
|
input,
|
|
@@ -11188,7 +12309,8 @@ async function generateMaster(plan, deps, opts, reference = null) {
|
|
|
11188
12309
|
requestId: result.requestId,
|
|
11189
12310
|
outPath: plan.outPath,
|
|
11190
12311
|
sha256: sha2562,
|
|
11191
|
-
|
|
12312
|
+
sourceSha256,
|
|
12313
|
+
byteLength: normalised.bytes.byteLength,
|
|
11192
12314
|
textureUrls: output.textureUrls,
|
|
11193
12315
|
referenceImage: buildReferenceManifest(plan, reference, inputImage),
|
|
11194
12316
|
generatedAt: deps.now().toISOString(),
|
|
@@ -11196,8 +12318,12 @@ async function generateMaster(plan, deps, opts, reference = null) {
|
|
|
11196
12318
|
});
|
|
11197
12319
|
await deps.writeJson(plan.manifestPath, manifest);
|
|
11198
12320
|
return {
|
|
11199
|
-
bytes,
|
|
12321
|
+
bytes: normalised.bytes,
|
|
11200
12322
|
sha256: sha2562,
|
|
12323
|
+
sourceSha256,
|
|
12324
|
+
materials: normalised.materials,
|
|
12325
|
+
fit: normalised.fit,
|
|
12326
|
+
...definedErrors(normalised.normaliseError, normalised.fitError),
|
|
11201
12327
|
requestId: result.requestId,
|
|
11202
12328
|
inputImage,
|
|
11203
12329
|
glbUrl: output.glbUrl,
|
|
@@ -11249,7 +12375,8 @@ async function packageOrError(args) {
|
|
|
11249
12375
|
prompt: args.prompt,
|
|
11250
12376
|
force: args.force,
|
|
11251
12377
|
reference: args.reference,
|
|
11252
|
-
rigFiles: args.rigFiles
|
|
12378
|
+
rigFiles: args.rigFiles,
|
|
12379
|
+
masterChecks: args.masterChecks
|
|
11253
12380
|
});
|
|
11254
12381
|
return null;
|
|
11255
12382
|
} catch (err2) {
|
|
@@ -11269,7 +12396,8 @@ async function packageRun(args) {
|
|
|
11269
12396
|
prompt: args.opts.prompt,
|
|
11270
12397
|
force: args.opts.force === true,
|
|
11271
12398
|
reference: args.reference,
|
|
11272
|
-
rigFiles: args.rigging.files
|
|
12399
|
+
rigFiles: args.rigging.files,
|
|
12400
|
+
masterChecks: args.masterChecks
|
|
11273
12401
|
});
|
|
11274
12402
|
if (packageError === null) {
|
|
11275
12403
|
await args.deps.writeJson(args.plan.manifestPath, packagedManifest(args.master, args.rigging, args.plan));
|
|
@@ -11286,6 +12414,8 @@ async function generate3d(opts, deps) {
|
|
|
11286
12414
|
const reference = await generateReferenceFile(plan, deps);
|
|
11287
12415
|
const bundledReference = await bundleReference(plan, deps, reference);
|
|
11288
12416
|
const master = await generateMaster(plan, deps, opts, reference);
|
|
12417
|
+
const masterChecks = await checksForGlb(master.bytes);
|
|
12418
|
+
const warnings = [master.normaliseError, master.fitError].filter((warning) => warning !== undefined);
|
|
11289
12419
|
const rigging = await rigOrError(plan, deps, master);
|
|
11290
12420
|
const built = await buildRigFilesOrEmpty(plan, deps, rigging);
|
|
11291
12421
|
rigging.files = built.files;
|
|
@@ -11293,19 +12423,34 @@ async function generate3d(opts, deps) {
|
|
|
11293
12423
|
const rigged = rigManifest(master, rigging);
|
|
11294
12424
|
if (rigged !== null)
|
|
11295
12425
|
await deps.writeJson(plan.manifestPath, rigged);
|
|
11296
|
-
await packageRun({
|
|
12426
|
+
await packageRun({
|
|
12427
|
+
plan,
|
|
12428
|
+
deps,
|
|
12429
|
+
master,
|
|
12430
|
+
opts,
|
|
12431
|
+
reference: bundledReference,
|
|
12432
|
+
rigging,
|
|
12433
|
+
masterChecks
|
|
12434
|
+
});
|
|
11297
12435
|
return {
|
|
11298
12436
|
outPath: plan.outPath,
|
|
11299
12437
|
manifestPath: plan.manifestPath,
|
|
11300
12438
|
zipPath: plan.zipPath,
|
|
11301
12439
|
htmlPath: plan.htmlPath,
|
|
11302
12440
|
sha256: master.sha256,
|
|
12441
|
+
checks: masterChecks,
|
|
12442
|
+
warnings,
|
|
11303
12443
|
costLines: formatGenerate3dCost(plan.costLines, plan.model.id, plan.generationCostKnown)
|
|
11304
12444
|
};
|
|
11305
12445
|
}
|
|
11306
|
-
var GLB_CONTENT_TYPE = "model/gltf-binary", GLB_EXTENSION = ".glb", PLANNED_MODEL_URL = "<generated mesh GLB URL>", RIGGING_HUMANOID_WARNING = "Rigging (Meshy) expects a humanoid mesh; non-humanoid meshes fail on fal.", WEB_VARIANT_TRIANGLE_TARGET = 30000, WEB_VARIANT_MAX_TEXTURE_PX = 1024, WEB_VARIANT_TEXTURE_QUALITY = 80, WEB_VARIANT_DATA_TEXTURE_QUALITY = 95, PACKAGE_MANIFEST_NAME = "manifest.json", PACKAGE_PRICING_NOTE = "list-price estimate, not a billed amount", HTTP_URL_PATTERN2, INPUT_IMAGE_CONTENT_TYPES2, INPUT_REQUIREMENTS, PACKAGE_COLLISION_HINT = "Another run used this name in the same second; wait a second, use a different --package-dir, or pass --force.", FLAG_CAPABILITY, INPUT_FLAG_NAMES, INPUT_PLACEHOLDERS, INPUT_CAPABILITY, RESERVED_INPUT_FLAGS, GENERATED_REFERENCE_URL = "<generated reference image URL>", WEB_VARIANT_OPTIONS;
|
|
12446
|
+
var GLB_CONTENT_TYPE = "model/gltf-binary", GLB_EXTENSION = ".glb", PLANNED_MODEL_URL = "<generated mesh GLB URL>", RIGGING_HUMANOID_WARNING = "Rigging (Meshy) expects a humanoid mesh; non-humanoid meshes fail on fal.", WEB_VARIANT_TRIANGLE_TARGET = 30000, WEB_VARIANT_MAX_TEXTURE_PX = 1024, WEB_VARIANT_TEXTURE_QUALITY = 80, WEB_VARIANT_DATA_TEXTURE_QUALITY = 95, PACKAGE_MANIFEST_NAME = "manifest.json", PACKAGE_PRICING_NOTE = "list-price estimate, not a billed amount", HTTP_URL_PATTERN2, INPUT_IMAGE_CONTENT_TYPES2, INPUT_REQUIREMENTS, PACKAGE_COLLISION_HINT = "Another run used this name in the same second; wait a second, use a different --package-dir, or pass --force.", FLAG_CAPABILITY, INPUT_FLAG_NAMES, INPUT_PLACEHOLDERS, INPUT_CAPABILITY, RESERVED_INPUT_FLAGS, GENERATED_REFERENCE_URL = "<generated reference image URL>", WEB_VARIANT_OPTIONS, SILENT_LOGGER2;
|
|
11307
12447
|
var init_generate_3d = __esm(() => {
|
|
12448
|
+
init_meshoptimizer();
|
|
12449
|
+
init_asset_analysis();
|
|
12450
|
+
init_checks();
|
|
11308
12451
|
init_deps2();
|
|
12452
|
+
init_fit();
|
|
12453
|
+
init_material_normalise();
|
|
11309
12454
|
init_model_registry();
|
|
11310
12455
|
init_package_name();
|
|
11311
12456
|
init_rigging();
|
|
@@ -11345,6 +12490,192 @@ var init_generate_3d = __esm(() => {
|
|
|
11345
12490
|
quality: WEB_VARIANT_TEXTURE_QUALITY,
|
|
11346
12491
|
dataQuality: WEB_VARIANT_DATA_TEXTURE_QUALITY
|
|
11347
12492
|
};
|
|
12493
|
+
SILENT_LOGGER2 = {
|
|
12494
|
+
debug: () => {},
|
|
12495
|
+
info: () => {},
|
|
12496
|
+
warn: () => {},
|
|
12497
|
+
error: () => {}
|
|
12498
|
+
};
|
|
12499
|
+
});
|
|
12500
|
+
|
|
12501
|
+
// src/commands/generate-3d/rebuild-preview.ts
|
|
12502
|
+
var exports_rebuild_preview = {};
|
|
12503
|
+
__export(exports_rebuild_preview, {
|
|
12504
|
+
rebuildPreviewFromZip: () => rebuildPreviewFromZip
|
|
12505
|
+
});
|
|
12506
|
+
import { readFile as readFile3, stat as stat2, writeFile as writeFile2 } from "node:fs/promises";
|
|
12507
|
+
import { basename as basename2, dirname as dirname5, join as join3 } from "node:path";
|
|
12508
|
+
import { NodeIO as NodeIO3 } from "@gltf-transform/core";
|
|
12509
|
+
import { ALL_EXTENSIONS as ALL_EXTENSIONS3 } from "@gltf-transform/extensions";
|
|
12510
|
+
function isRecord5(value) {
|
|
12511
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
12512
|
+
}
|
|
12513
|
+
function invalidPackage(zipPath, detail) {
|
|
12514
|
+
return new Error(`Cannot rebuild the preview from ${zipPath}: ${detail}`);
|
|
12515
|
+
}
|
|
12516
|
+
function requireString(record, field, zipPath) {
|
|
12517
|
+
const value = record[field];
|
|
12518
|
+
if (typeof value !== "string" || value.length === 0) {
|
|
12519
|
+
throw invalidPackage(zipPath, `manifest.json has no ${field}.`);
|
|
12520
|
+
}
|
|
12521
|
+
return value;
|
|
12522
|
+
}
|
|
12523
|
+
function requireCount(record, field, zipPath) {
|
|
12524
|
+
const value = record[field];
|
|
12525
|
+
if (typeof value !== "number" || !Number.isInteger(value) || value < 0) {
|
|
12526
|
+
throw invalidPackage(zipPath, `manifest.json has no valid ${field}.`);
|
|
12527
|
+
}
|
|
12528
|
+
return value;
|
|
12529
|
+
}
|
|
12530
|
+
function requireRecord(record, field, zipPath) {
|
|
12531
|
+
const value = record[field];
|
|
12532
|
+
if (!isRecord5(value)) {
|
|
12533
|
+
throw invalidPackage(zipPath, `manifest.json has no ${field} object.`);
|
|
12534
|
+
}
|
|
12535
|
+
return value;
|
|
12536
|
+
}
|
|
12537
|
+
function readPrompt(generator, zipPath) {
|
|
12538
|
+
const prompt = generator.prompt;
|
|
12539
|
+
if (prompt === null || typeof prompt === "string")
|
|
12540
|
+
return prompt;
|
|
12541
|
+
throw invalidPackage(zipPath, "manifest.json has no valid generator.prompt.");
|
|
12542
|
+
}
|
|
12543
|
+
function requireVariant(variants, name, zipPath) {
|
|
12544
|
+
const match = variants.find((variant) => isRecord5(variant) && variant.name === name);
|
|
12545
|
+
if (!isRecord5(match)) {
|
|
12546
|
+
throw invalidPackage(zipPath, `manifest.json has no "${name}" variant.`);
|
|
12547
|
+
}
|
|
12548
|
+
return {
|
|
12549
|
+
name,
|
|
12550
|
+
file: requireString(match, "file", zipPath),
|
|
12551
|
+
bytes: requireCount(match, "bytes", zipPath),
|
|
12552
|
+
triangles: requireCount(match, "triangles", zipPath),
|
|
12553
|
+
sha256: requireString(match, "sha256", zipPath)
|
|
12554
|
+
};
|
|
12555
|
+
}
|
|
12556
|
+
function parseManifest(bytes, zipPath) {
|
|
12557
|
+
let raw;
|
|
12558
|
+
try {
|
|
12559
|
+
raw = JSON.parse(new TextDecoder().decode(bytes));
|
|
12560
|
+
} catch {
|
|
12561
|
+
throw invalidPackage(zipPath, "manifest.json is not valid JSON.");
|
|
12562
|
+
}
|
|
12563
|
+
if (!isRecord5(raw)) {
|
|
12564
|
+
throw invalidPackage(zipPath, "manifest.json is not an object.");
|
|
12565
|
+
}
|
|
12566
|
+
const generator = requireRecord(raw, "generator", zipPath);
|
|
12567
|
+
const variants = raw.variants;
|
|
12568
|
+
if (!Array.isArray(variants)) {
|
|
12569
|
+
throw invalidPackage(zipPath, "manifest.json has no variants array.");
|
|
12570
|
+
}
|
|
12571
|
+
return {
|
|
12572
|
+
model: requireString(generator, "model", zipPath),
|
|
12573
|
+
requestId: requireString(generator, "requestId", zipPath),
|
|
12574
|
+
prompt: readPrompt(generator, zipPath),
|
|
12575
|
+
master: requireVariant(variants, "master", zipPath),
|
|
12576
|
+
web: requireVariant(variants, "web", zipPath)
|
|
12577
|
+
};
|
|
12578
|
+
}
|
|
12579
|
+
function requireEntry(files, variant, role, zipPath) {
|
|
12580
|
+
const bytes = files[variant.file];
|
|
12581
|
+
if (bytes === undefined) {
|
|
12582
|
+
throw invalidPackage(zipPath, `the ${role} GLB ${variant.file} is missing from the zip.`);
|
|
12583
|
+
}
|
|
12584
|
+
if (bytes.byteLength !== variant.bytes) {
|
|
12585
|
+
throw invalidPackage(zipPath, `${variant.file} is ${bytes.byteLength} bytes in the zip, but manifest.json says ${variant.bytes}.`);
|
|
12586
|
+
}
|
|
12587
|
+
return bytes;
|
|
12588
|
+
}
|
|
12589
|
+
async function readArchive(zipPath) {
|
|
12590
|
+
const archive = await readFile3(zipPath).catch((err2) => {
|
|
12591
|
+
throw new Error(`Cannot read the package ${zipPath}: ${err2 instanceof Error ? err2.message : String(err2)}`);
|
|
12592
|
+
});
|
|
12593
|
+
try {
|
|
12594
|
+
return unzipSync(archive);
|
|
12595
|
+
} catch (err2) {
|
|
12596
|
+
throw invalidPackage(zipPath, `not a readable zip archive (${err2 instanceof Error ? err2.message : String(err2)}).`);
|
|
12597
|
+
}
|
|
12598
|
+
}
|
|
12599
|
+
function loadPackage(zipPath, files) {
|
|
12600
|
+
const manifestBytes = files[PACKAGE_MANIFEST_NAME2];
|
|
12601
|
+
if (manifestBytes === undefined) {
|
|
12602
|
+
throw invalidPackage(zipPath, `${PACKAGE_MANIFEST_NAME2} is missing from the zip.`);
|
|
12603
|
+
}
|
|
12604
|
+
const manifest = parseManifest(manifestBytes, zipPath);
|
|
12605
|
+
return {
|
|
12606
|
+
manifest,
|
|
12607
|
+
masterGlb: requireEntry(files, manifest.master, "master", zipPath),
|
|
12608
|
+
webGlb: requireEntry(files, manifest.web, "web", zipPath)
|
|
12609
|
+
};
|
|
12610
|
+
}
|
|
12611
|
+
function packageBase(zipName, zipPath) {
|
|
12612
|
+
if (!zipName.endsWith(".zip") || zipName.length === ".zip".length) {
|
|
12613
|
+
throw invalidPackage(zipPath, "the package must be a non-empty .zip file.");
|
|
12614
|
+
}
|
|
12615
|
+
return zipName.slice(0, -".zip".length);
|
|
12616
|
+
}
|
|
12617
|
+
async function requireWritablePreview(htmlPath, force) {
|
|
12618
|
+
const stats = await stat2(htmlPath).catch(() => null);
|
|
12619
|
+
if (stats === null)
|
|
12620
|
+
return;
|
|
12621
|
+
if (stats.isDirectory()) {
|
|
12622
|
+
throw new Error(`Preview is a directory: ${htmlPath}. Pass a file path.`);
|
|
12623
|
+
}
|
|
12624
|
+
if (!force) {
|
|
12625
|
+
throw new Error(`Preview already exists: ${htmlPath}. Pass --force to overwrite.`);
|
|
12626
|
+
}
|
|
12627
|
+
}
|
|
12628
|
+
async function writePreview(htmlPath, html, force) {
|
|
12629
|
+
await requireWritablePreview(htmlPath, force);
|
|
12630
|
+
try {
|
|
12631
|
+
await writeFile2(htmlPath, new TextEncoder().encode(html), { flag: force ? "w" : "wx" });
|
|
12632
|
+
} catch (err2) {
|
|
12633
|
+
throw new Error(`Cannot write the preview ${htmlPath}: ${err2 instanceof Error ? err2.message : String(err2)}`);
|
|
12634
|
+
}
|
|
12635
|
+
}
|
|
12636
|
+
async function rebuildPreviewFromZip(zipPath, options) {
|
|
12637
|
+
const zipName = basename2(zipPath);
|
|
12638
|
+
const base = packageBase(zipName, zipPath);
|
|
12639
|
+
const htmlPath = join3(dirname5(zipPath), `${base}.html`);
|
|
12640
|
+
await requireWritablePreview(htmlPath, options.force);
|
|
12641
|
+
const { manifest, masterGlb, webGlb } = loadPackage(zipPath, await readArchive(zipPath));
|
|
12642
|
+
let checks = [];
|
|
12643
|
+
let checksNote = null;
|
|
12644
|
+
try {
|
|
12645
|
+
const io = new NodeIO3().registerExtensions(ALL_EXTENSIONS3).registerDependencies({ "meshopt.decoder": MeshoptDecoder });
|
|
12646
|
+
checks = computeChecks(await analyseDocument(await io.readBinary(masterGlb)));
|
|
12647
|
+
} catch (err2) {
|
|
12648
|
+
const detail = err2 instanceof Error ? err2.message : String(err2);
|
|
12649
|
+
checksNote = `Checks unavailable: ${detail}`;
|
|
12650
|
+
}
|
|
12651
|
+
const directionalEnvironment = await directionalEnvironmentPng();
|
|
12652
|
+
const html = renderPreviewHtml({
|
|
12653
|
+
title: base,
|
|
12654
|
+
modelId: manifest.model,
|
|
12655
|
+
prompt: manifest.prompt,
|
|
12656
|
+
requestId: manifest.requestId,
|
|
12657
|
+
masterGlb,
|
|
12658
|
+
webGlb,
|
|
12659
|
+
webSha256: manifest.web.sha256,
|
|
12660
|
+
webTriangles: manifest.web.triangles,
|
|
12661
|
+
masterTriangles: manifest.master.triangles,
|
|
12662
|
+
masterBytes: manifest.master.bytes,
|
|
12663
|
+
webBytes: manifest.web.bytes,
|
|
12664
|
+
masterZipEntry: manifest.master.file,
|
|
12665
|
+
zipName,
|
|
12666
|
+
checks,
|
|
12667
|
+
checksNote,
|
|
12668
|
+
directionalEnvironmentPng: directionalEnvironment
|
|
12669
|
+
});
|
|
12670
|
+
await writePreview(htmlPath, html, options.force);
|
|
12671
|
+
return htmlPath;
|
|
12672
|
+
}
|
|
12673
|
+
var PACKAGE_MANIFEST_NAME2 = "manifest.json";
|
|
12674
|
+
var init_rebuild_preview = __esm(() => {
|
|
12675
|
+
init_esm();
|
|
12676
|
+
init_meshoptimizer();
|
|
12677
|
+
init_asset_analysis();
|
|
12678
|
+
init_checks();
|
|
11348
12679
|
});
|
|
11349
12680
|
|
|
11350
12681
|
// ../../node_modules/.pnpm/pngjs@6.0.0/node_modules/pngjs/lib/chunkstream.js
|
|
@@ -12156,17 +13487,17 @@ var require_bitmapper = __commonJS((exports) => {
|
|
|
12156
13487
|
}
|
|
12157
13488
|
return rawPos;
|
|
12158
13489
|
}
|
|
12159
|
-
function mapImageCustomBit(image, pxData, getPxPos, bpp,
|
|
13490
|
+
function mapImageCustomBit(image, pxData, getPxPos, bpp, bits2, maxBit) {
|
|
12160
13491
|
let imageWidth = image.width;
|
|
12161
13492
|
let imageHeight = image.height;
|
|
12162
13493
|
let imagePass = image.index;
|
|
12163
13494
|
for (let y = 0;y < imageHeight; y++) {
|
|
12164
13495
|
for (let x2 = 0;x2 < imageWidth; x2++) {
|
|
12165
|
-
let pixelData =
|
|
13496
|
+
let pixelData = bits2.get(bpp);
|
|
12166
13497
|
let pxPos = getPxPos(x2, y, imagePass);
|
|
12167
13498
|
pixelBppCustomMapper[bpp](pxData, pixelData, pxPos, maxBit);
|
|
12168
13499
|
}
|
|
12169
|
-
|
|
13500
|
+
bits2.resetAfterLine();
|
|
12170
13501
|
}
|
|
12171
13502
|
}
|
|
12172
13503
|
exports.dataToBitMap = function(data, bitmapInfo) {
|
|
@@ -12175,9 +13506,9 @@ var require_bitmapper = __commonJS((exports) => {
|
|
|
12175
13506
|
let depth = bitmapInfo.depth;
|
|
12176
13507
|
let bpp = bitmapInfo.bpp;
|
|
12177
13508
|
let interlace = bitmapInfo.interlace;
|
|
12178
|
-
let
|
|
13509
|
+
let bits2;
|
|
12179
13510
|
if (depth !== 8) {
|
|
12180
|
-
|
|
13511
|
+
bits2 = bitRetriever(data, depth);
|
|
12181
13512
|
}
|
|
12182
13513
|
let pxData;
|
|
12183
13514
|
if (depth <= 8) {
|
|
@@ -12205,7 +13536,7 @@ var require_bitmapper = __commonJS((exports) => {
|
|
|
12205
13536
|
if (depth === 8) {
|
|
12206
13537
|
rawPos = mapImage8Bit(images[imageIndex], pxData, getPxPos, bpp, data, rawPos);
|
|
12207
13538
|
} else {
|
|
12208
|
-
mapImageCustomBit(images[imageIndex], pxData, getPxPos, bpp,
|
|
13539
|
+
mapImageCustomBit(images[imageIndex], pxData, getPxPos, bpp, bits2, maxBit);
|
|
12209
13540
|
}
|
|
12210
13541
|
}
|
|
12211
13542
|
if (depth === 8) {
|
|
@@ -12213,7 +13544,7 @@ var require_bitmapper = __commonJS((exports) => {
|
|
|
12213
13544
|
throw new Error("extra data found");
|
|
12214
13545
|
}
|
|
12215
13546
|
} else {
|
|
12216
|
-
|
|
13547
|
+
bits2.end();
|
|
12217
13548
|
}
|
|
12218
13549
|
return pxData;
|
|
12219
13550
|
};
|
|
@@ -12916,13 +14247,13 @@ var require_sync_inflate = __commonJS((exports, module) => {
|
|
|
12916
14247
|
}
|
|
12917
14248
|
return engine._processChunk(buffer, flushFlag);
|
|
12918
14249
|
}
|
|
12919
|
-
function
|
|
14250
|
+
function inflateSync2(buffer, opts) {
|
|
12920
14251
|
return zlibBufferSync(new Inflate(opts), buffer);
|
|
12921
14252
|
}
|
|
12922
|
-
module.exports = exports =
|
|
14253
|
+
module.exports = exports = inflateSync2;
|
|
12923
14254
|
exports.Inflate = Inflate;
|
|
12924
14255
|
exports.createInflate = createInflate;
|
|
12925
|
-
exports.inflateSync =
|
|
14256
|
+
exports.inflateSync = inflateSync2;
|
|
12926
14257
|
});
|
|
12927
14258
|
|
|
12928
14259
|
// ../../node_modules/.pnpm/pngjs@6.0.0/node_modules/pngjs/lib/sync-reader.js
|
|
@@ -12983,7 +14314,7 @@ var require_filter_parse_sync = __commonJS((exports) => {
|
|
|
12983
14314
|
var require_parser_sync = __commonJS((exports, module) => {
|
|
12984
14315
|
var hasSyncZlib = true;
|
|
12985
14316
|
var zlib = __require("zlib");
|
|
12986
|
-
var
|
|
14317
|
+
var inflateSync2 = require_sync_inflate();
|
|
12987
14318
|
if (!zlib.deflateSync) {
|
|
12988
14319
|
hasSyncZlib = false;
|
|
12989
14320
|
}
|
|
@@ -13045,7 +14376,7 @@ var require_parser_sync = __commonJS((exports, module) => {
|
|
|
13045
14376
|
} else {
|
|
13046
14377
|
let rowSize = (metaData.width * metaData.bpp * metaData.depth + 7 >> 3) + 1;
|
|
13047
14378
|
let imageSize = rowSize * metaData.height;
|
|
13048
|
-
inflatedData =
|
|
14379
|
+
inflatedData = inflateSync2(inflateData, {
|
|
13049
14380
|
chunkSize: imageSize,
|
|
13050
14381
|
maxLength: imageSize
|
|
13051
14382
|
});
|
|
@@ -13239,7 +14570,7 @@ var exports_slice_deps = {};
|
|
|
13239
14570
|
__export(exports_slice_deps, {
|
|
13240
14571
|
createDefaultSliceImageDeps: () => createDefaultSliceImageDeps
|
|
13241
14572
|
});
|
|
13242
|
-
import { lstat, mkdir as mkdir3, readFile as
|
|
14573
|
+
import { lstat, mkdir as mkdir3, readFile as readFile6, stat as stat5 } from "node:fs/promises";
|
|
13243
14574
|
function decodePng(bytes) {
|
|
13244
14575
|
const png = PNG.sync.read(Buffer.from(bytes));
|
|
13245
14576
|
return { width: png.width, height: png.height, data: png.data };
|
|
@@ -13258,7 +14589,7 @@ function classifyStat(stats) {
|
|
|
13258
14589
|
}
|
|
13259
14590
|
async function statInput(path) {
|
|
13260
14591
|
try {
|
|
13261
|
-
return classifyStat(await
|
|
14592
|
+
return classifyStat(await stat5(path));
|
|
13262
14593
|
} catch (err2) {
|
|
13263
14594
|
if (err2.code === "ENOENT") {
|
|
13264
14595
|
return { kind: "missing", size: 0 };
|
|
@@ -13269,7 +14600,7 @@ async function statInput(path) {
|
|
|
13269
14600
|
async function readJsonIfExists(path) {
|
|
13270
14601
|
let text;
|
|
13271
14602
|
try {
|
|
13272
|
-
text = await
|
|
14603
|
+
text = await readFile6(path, "utf8");
|
|
13273
14604
|
} catch (err2) {
|
|
13274
14605
|
if (err2.code === "ENOENT") {
|
|
13275
14606
|
return;
|
|
@@ -13280,7 +14611,7 @@ async function readJsonIfExists(path) {
|
|
|
13280
14611
|
}
|
|
13281
14612
|
async function fileIdentity(path) {
|
|
13282
14613
|
try {
|
|
13283
|
-
const stats = await
|
|
14614
|
+
const stats = await stat5(path);
|
|
13284
14615
|
return { dev: stats.dev, ino: stats.ino };
|
|
13285
14616
|
} catch (err2) {
|
|
13286
14617
|
if (err2.code === "ENOENT") {
|
|
@@ -13306,7 +14637,7 @@ function createDefaultSliceImageDeps() {
|
|
|
13306
14637
|
return {
|
|
13307
14638
|
pathStatus,
|
|
13308
14639
|
statInput,
|
|
13309
|
-
readFile:
|
|
14640
|
+
readFile: readFile6,
|
|
13310
14641
|
readJsonIfExists,
|
|
13311
14642
|
decodePng,
|
|
13312
14643
|
encodePng,
|
|
@@ -13344,7 +14675,7 @@ var init_remove_image_background_deps = __esm(() => {
|
|
|
13344
14675
|
});
|
|
13345
14676
|
|
|
13346
14677
|
// src/commands/remove-image-background/remove-image-background-fal.ts
|
|
13347
|
-
import { basename as
|
|
14678
|
+
import { basename as basename4, resolve as resolve4 } from "node:path";
|
|
13348
14679
|
function validateBackgroundResult(raw, model) {
|
|
13349
14680
|
const unexpected = new RemoveBackgroundFalError(`fal returned no image for ${model}`);
|
|
13350
14681
|
if (!isRecord2(raw))
|
|
@@ -13499,7 +14830,7 @@ async function removeBackgroundFal(options, deps) {
|
|
|
13499
14830
|
model: spec.model,
|
|
13500
14831
|
input: {
|
|
13501
14832
|
...engine === "birefnet" ? { mode: "Matting", output_format: "png" } : {},
|
|
13502
|
-
source:
|
|
14833
|
+
source: basename4(inPath),
|
|
13503
14834
|
sourceBytes: source.bytes.byteLength,
|
|
13504
14835
|
sourceSha256: sha256(source.bytes),
|
|
13505
14836
|
width: source.width,
|
|
@@ -13568,7 +14899,7 @@ var exports_remove_image_background_fal_deps = {};
|
|
|
13568
14899
|
__export(exports_remove_image_background_fal_deps, {
|
|
13569
14900
|
createDefaultRemoveBackgroundFalDeps: () => createDefaultRemoveBackgroundFalDeps
|
|
13570
14901
|
});
|
|
13571
|
-
import { dirname as
|
|
14902
|
+
import { dirname as dirname7 } from "node:path";
|
|
13572
14903
|
function mebibytes(bytes) {
|
|
13573
14904
|
return Math.round(bytes / (1024 * 1024));
|
|
13574
14905
|
}
|
|
@@ -13608,7 +14939,7 @@ function createDefaultRemoveBackgroundFalDeps() {
|
|
|
13608
14939
|
pathStatus: slice.pathStatus,
|
|
13609
14940
|
writeFile: slice.writeFile,
|
|
13610
14941
|
writeJson: slice.writeJson,
|
|
13611
|
-
ensureParentDir: (path) => slice.ensureDir(
|
|
14942
|
+
ensureParentDir: (path) => slice.ensureDir(dirname7(path)),
|
|
13612
14943
|
now: () => new Date,
|
|
13613
14944
|
sdkVersion: readInstalledPackageVersion("@fal-ai/client"),
|
|
13614
14945
|
log: (message) => console.log(message)
|
|
@@ -13711,15 +15042,15 @@ var init_stdin_heredoc = __esm(() => {
|
|
|
13711
15042
|
|
|
13712
15043
|
// src/version.ts
|
|
13713
15044
|
import { readFileSync as readFileSync3 } from "node:fs";
|
|
13714
|
-
import { dirname as
|
|
15045
|
+
import { dirname as dirname8, join as join6 } from "node:path";
|
|
13715
15046
|
import { fileURLToPath } from "node:url";
|
|
13716
15047
|
function getVersion() {
|
|
13717
15048
|
try {
|
|
13718
15049
|
const __filename2 = fileURLToPath(import.meta.url);
|
|
13719
|
-
const __dirname2 =
|
|
15050
|
+
const __dirname2 = dirname8(__filename2);
|
|
13720
15051
|
const possiblePaths = [
|
|
13721
|
-
|
|
13722
|
-
|
|
15052
|
+
join6(__dirname2, "..", "package.json"),
|
|
15053
|
+
join6(__dirname2, "..", "..", "package.json")
|
|
13723
15054
|
];
|
|
13724
15055
|
for (const packagePath of possiblePaths) {
|
|
13725
15056
|
try {
|
|
@@ -21221,12 +22552,12 @@ __export(exports_storage, {
|
|
|
21221
22552
|
});
|
|
21222
22553
|
import * as fs from "node:fs/promises";
|
|
21223
22554
|
import { homedir, hostname } from "node:os";
|
|
21224
|
-
import { join as
|
|
22555
|
+
import { join as join7 } from "node:path";
|
|
21225
22556
|
async function ensureConfigDir() {
|
|
21226
22557
|
await fs.mkdir(CHATROOM_DIR, { recursive: true, mode: 448 });
|
|
21227
22558
|
}
|
|
21228
22559
|
function getAuthFilePath() {
|
|
21229
|
-
return
|
|
22560
|
+
return join7(CHATROOM_DIR, AUTH_FILE);
|
|
21230
22561
|
}
|
|
21231
22562
|
function parseJsonc(content) {
|
|
21232
22563
|
const jsonContent = content.split(`
|
|
@@ -21394,7 +22725,7 @@ var CHATROOM_DIR, AUTH_FILE = "auth.jsonc", PRODUCTION_CONVEX_URL = "https://cha
|
|
|
21394
22725
|
var init_storage = __esm(() => {
|
|
21395
22726
|
init_client2();
|
|
21396
22727
|
init_version();
|
|
21397
|
-
CHATROOM_DIR =
|
|
22728
|
+
CHATROOM_DIR = join7(homedir(), ".chatroom");
|
|
21398
22729
|
});
|
|
21399
22730
|
|
|
21400
22731
|
// ../../node_modules/.pnpm/convex@1.45.0_react@19.2.7/node_modules/convex/dist/esm/server/pagination.js
|
|
@@ -22845,7 +24176,7 @@ function make(combine2) {
|
|
|
22845
24176
|
function min(order) {
|
|
22846
24177
|
return make((self2, that) => order(self2, that) === -1 ? self2 : that);
|
|
22847
24178
|
}
|
|
22848
|
-
function
|
|
24179
|
+
function max2(order) {
|
|
22849
24180
|
return make((self2, that) => order(self2, that) === 1 ? self2 : that);
|
|
22850
24181
|
}
|
|
22851
24182
|
|
|
@@ -23038,7 +24369,7 @@ var init_result = __esm(() => {
|
|
|
23038
24369
|
function make4(compare) {
|
|
23039
24370
|
return (self2, that) => self2 === that ? 0 : compare(self2, that);
|
|
23040
24371
|
}
|
|
23041
|
-
var Number2, mapInput, isLessThan = (O) => dual(2, (self2, that) => O(self2, that) === -1), isGreaterThan = (O) => dual(2, (self2, that) => O(self2, that) === 1), isLessThanOrEqualTo = (O) => dual(2, (self2, that) => O(self2, that) !== 1), isGreaterThanOrEqualTo = (O) => dual(2, (self2, that) => O(self2, that) !== -1), min2 = (O) => dual(2, (self2, that) => self2 === that || O(self2, that) < 1 ? self2 : that),
|
|
24372
|
+
var Number2, mapInput, isLessThan = (O) => dual(2, (self2, that) => O(self2, that) === -1), isGreaterThan = (O) => dual(2, (self2, that) => O(self2, that) === 1), isLessThanOrEqualTo = (O) => dual(2, (self2, that) => O(self2, that) !== 1), isGreaterThanOrEqualTo = (O) => dual(2, (self2, that) => O(self2, that) !== -1), min2 = (O) => dual(2, (self2, that) => self2 === that || O(self2, that) < 1 ? self2 : that), max3 = (O) => dual(2, (self2, that) => self2 === that || O(self2, that) > -1 ? self2 : that), clamp = (O) => dual(2, (self2, options) => min2(O)(options.maximum, max3(O)(options.minimum, self2))), isBetween = (O) => dual(2, (self2, options) => !isLessThan(O)(self2, options.minimum) && !isGreaterThan(O)(self2, options.maximum));
|
|
23042
24373
|
var init_Order = __esm(() => {
|
|
23043
24374
|
init_Function();
|
|
23044
24375
|
Number2 = /* @__PURE__ */ make4((self2, that) => {
|
|
@@ -23050,7 +24381,7 @@ var init_Order = __esm(() => {
|
|
|
23050
24381
|
return 1;
|
|
23051
24382
|
return self2 < that ? -1 : 1;
|
|
23052
24383
|
});
|
|
23053
|
-
mapInput = /* @__PURE__ */ dual(2, (self2, f) => make4((b1,
|
|
24384
|
+
mapInput = /* @__PURE__ */ dual(2, (self2, f) => make4((b1, b22) => self2(f(b1), f(b22))));
|
|
23054
24385
|
});
|
|
23055
24386
|
|
|
23056
24387
|
// ../../node_modules/.pnpm/effect@4.0.1/node_modules/effect/dist/Option.js
|
|
@@ -23462,7 +24793,7 @@ __export(exports_Duration, {
|
|
|
23462
24793
|
min: () => min3,
|
|
23463
24794
|
millis: () => millis,
|
|
23464
24795
|
micros: () => micros,
|
|
23465
|
-
max: () =>
|
|
24796
|
+
max: () => max4,
|
|
23466
24797
|
matchPair: () => matchPair,
|
|
23467
24798
|
match: () => match2,
|
|
23468
24799
|
isZero: () => isZero,
|
|
@@ -23731,7 +25062,7 @@ var TypeId4 = "~effect/Duration", bigint0, bigint1, bigint2, bigint10, bigint24,
|
|
|
23731
25062
|
onMillis: (self3, that2) => self3 === that2,
|
|
23732
25063
|
onNanos: (self3, that2) => self3 === that2,
|
|
23733
25064
|
onInfinity: (self3, that2) => self3.value._tag === that2.value._tag
|
|
23734
|
-
}), min3,
|
|
25065
|
+
}), min3, max4, clamp2, divide, divideUnsafe, times, subtract, sum, isLessThan2, isLessThanOrEqualTo2, isGreaterThan2, isGreaterThanOrEqualTo2, equals2, parts = (self2) => {
|
|
23735
25066
|
if (self2.value._tag === "Infinity") {
|
|
23736
25067
|
return {
|
|
23737
25068
|
days: Infinity,
|
|
@@ -23938,7 +25269,7 @@ var init_Duration = __esm(() => {
|
|
|
23938
25269
|
}));
|
|
23939
25270
|
between = /* @__PURE__ */ isBetween(Order);
|
|
23940
25271
|
min3 = /* @__PURE__ */ min2(Order);
|
|
23941
|
-
|
|
25272
|
+
max4 = /* @__PURE__ */ max3(Order);
|
|
23942
25273
|
clamp2 = /* @__PURE__ */ clamp(Order);
|
|
23943
25274
|
divide = /* @__PURE__ */ dual(2, (self2, by) => {
|
|
23944
25275
|
if (!Number.isFinite(by))
|
|
@@ -24023,7 +25354,7 @@ var init_Duration = __esm(() => {
|
|
|
24023
25354
|
isGreaterThanOrEqualTo2 = /* @__PURE__ */ isGreaterThanOrEqualTo(Order);
|
|
24024
25355
|
equals2 = /* @__PURE__ */ dual(2, (self2, that) => Equivalence(self2, that));
|
|
24025
25356
|
ReducerSum = /* @__PURE__ */ make2(sum, zero);
|
|
24026
|
-
CombinerMax = /* @__PURE__ */
|
|
25357
|
+
CombinerMax = /* @__PURE__ */ max2(Order);
|
|
24027
25358
|
CombinerMin = /* @__PURE__ */ min(Order);
|
|
24028
25359
|
});
|
|
24029
25360
|
|
|
@@ -25120,7 +26451,7 @@ ${prefix}}`;
|
|
|
25120
26451
|
let expiresAt = 0;
|
|
25121
26452
|
let exit2;
|
|
25122
26453
|
let current;
|
|
25123
|
-
const
|
|
26454
|
+
const join8 = (fiber2, run) => {
|
|
25124
26455
|
run.awaiters++;
|
|
25125
26456
|
onExitUnsafe(fiber2, () => {
|
|
25126
26457
|
if (--run.awaiters > 0 || current !== run)
|
|
@@ -25132,7 +26463,7 @@ ${prefix}}`;
|
|
|
25132
26463
|
};
|
|
25133
26464
|
return [withFiber((fiber2) => {
|
|
25134
26465
|
if (current !== undefined)
|
|
25135
|
-
return
|
|
26466
|
+
return join8(fiber2, current);
|
|
25136
26467
|
if (exit2 !== undefined && (expiresAt === Infinity || fiber2.getRef(ClockRef).currentTimeMillisUnsafe() < expiresAt)) {
|
|
25137
26468
|
return exit2;
|
|
25138
26469
|
}
|
|
@@ -25153,7 +26484,7 @@ ${prefix}}`;
|
|
|
25153
26484
|
expiresAt = duration === Infinity ? Infinity : clock.currentTimeMillisUnsafe() + duration;
|
|
25154
26485
|
exit2 = exit_;
|
|
25155
26486
|
}), true, true);
|
|
25156
|
-
return run.fiber._exit ??
|
|
26487
|
+
return run.fiber._exit ?? join8(fiber2, run);
|
|
25157
26488
|
}), sync(() => {
|
|
25158
26489
|
exit2 = undefined;
|
|
25159
26490
|
})];
|
|
@@ -27863,11 +29194,11 @@ var TypeId10 = "~effect/Cron", CronProto, isCron = (u) => hasProperty(u, TypeId1
|
|
|
27863
29194
|
weekday: lookup3.prev.weekday(weekdays)
|
|
27864
29195
|
};
|
|
27865
29196
|
return o;
|
|
27866
|
-
}, makeRestrictions = (field, min4,
|
|
29197
|
+
}, makeRestrictions = (field, min4, max5, normalize2 = (value) => value) => (values) => {
|
|
27867
29198
|
const restrictions = [];
|
|
27868
29199
|
for (const value of values) {
|
|
27869
|
-
if (!Number.isInteger(value) || value < min4 || value >
|
|
27870
|
-
throw new RangeError(`${field} must contain only integers between ${min4} and ${
|
|
29200
|
+
if (!Number.isInteger(value) || value < min4 || value > max5) {
|
|
29201
|
+
throw new RangeError(`${field} must contain only integers between ${min4} and ${max5}`);
|
|
27871
29202
|
}
|
|
27872
29203
|
restrictions.push(normalize2(value));
|
|
27873
29204
|
}
|
|
@@ -28386,7 +29717,7 @@ __export(exports_Schedule, {
|
|
|
28386
29717
|
once: () => once,
|
|
28387
29718
|
modifyDelay: () => modifyDelay,
|
|
28388
29719
|
min: () => min4,
|
|
28389
|
-
max: () =>
|
|
29720
|
+
max: () => max5,
|
|
28390
29721
|
map: () => map6,
|
|
28391
29722
|
jittered: () => jittered,
|
|
28392
29723
|
isSchedule: () => isSchedule,
|
|
@@ -28442,7 +29773,7 @@ var TypeId11 = "~effect/Schedule", randomNext, CurrentMetadata2, ScheduleProto,
|
|
|
28442
29773
|
return as(sleep(duration), meta);
|
|
28443
29774
|
});
|
|
28444
29775
|
});
|
|
28445
|
-
})), toStepWithSleep = (schedule) => map3(toStepWithMetadata(schedule), (step) => (input) => map3(step(input), (meta) => meta.output)), addDelay, concat, concatResult,
|
|
29776
|
+
})), toStepWithSleep = (schedule) => map3(toStepWithMetadata(schedule), (step) => (input) => map3(step(input), (meta) => meta.output)), addDelay, concat, concatResult, max5 = (schedules) => fromStep(map3(all2(schedules.map(toStep)), (steps) => (now, input) => flatMap(forEach(steps, (step) => matchEffect2(step(now, input), {
|
|
28446
29777
|
onSuccess: (result2) => succeed3(result2[1]),
|
|
28447
29778
|
onDone: () => undefined_,
|
|
28448
29779
|
onFailure: failCause
|
|
@@ -28453,13 +29784,13 @@ var TypeId11 = "~effect/Schedule", randomNext, CurrentMetadata2, ScheduleProto,
|
|
|
28453
29784
|
}
|
|
28454
29785
|
return succeed3([duration, duration]);
|
|
28455
29786
|
}))), maxDuration = (results2) => {
|
|
28456
|
-
let
|
|
29787
|
+
let max6 = results2[0];
|
|
28457
29788
|
for (let i3 = 1;i3 < results2.length; i3++) {
|
|
28458
|
-
|
|
28459
|
-
if (
|
|
29789
|
+
max6 = results2[i3] && max6 && max4(max6, results2[i3]);
|
|
29790
|
+
if (max6 === undefined)
|
|
28460
29791
|
break;
|
|
28461
29792
|
}
|
|
28462
|
-
return
|
|
29793
|
+
return max6;
|
|
28463
29794
|
}, cron = (expression, tz) => {
|
|
28464
29795
|
const parsed = isCron(expression) ? succeed2(expression) : parse(expression, tz);
|
|
28465
29796
|
return fromStep(map3(fromResult(parsed), (cron2) => (now, _) => {
|
|
@@ -29213,7 +30544,7 @@ var init_Metric = __esm(() => {
|
|
|
29213
30544
|
let count = 0;
|
|
29214
30545
|
let sum2 = 0;
|
|
29215
30546
|
let min5 = Number.MAX_VALUE;
|
|
29216
|
-
let
|
|
30547
|
+
let max6 = -Number.MAX_VALUE;
|
|
29217
30548
|
map2(sort(bounds, Number2), (n, i3) => {
|
|
29218
30549
|
boundaries[i3] = n;
|
|
29219
30550
|
});
|
|
@@ -29242,8 +30573,8 @@ var init_Metric = __esm(() => {
|
|
|
29242
30573
|
if (value < min5) {
|
|
29243
30574
|
min5 = value;
|
|
29244
30575
|
}
|
|
29245
|
-
if (value >
|
|
29246
|
-
|
|
30576
|
+
if (value > max6) {
|
|
30577
|
+
max6 = value;
|
|
29247
30578
|
}
|
|
29248
30579
|
};
|
|
29249
30580
|
const getBuckets = () => {
|
|
@@ -29261,7 +30592,7 @@ var init_Metric = __esm(() => {
|
|
|
29261
30592
|
buckets: getBuckets(),
|
|
29262
30593
|
count,
|
|
29263
30594
|
min: min5,
|
|
29264
|
-
max:
|
|
30595
|
+
max: max6,
|
|
29265
30596
|
sum: sum2
|
|
29266
30597
|
}), update);
|
|
29267
30598
|
}
|
|
@@ -29289,7 +30620,7 @@ var init_Metric = __esm(() => {
|
|
|
29289
30620
|
let count = 0;
|
|
29290
30621
|
let sum2 = 0;
|
|
29291
30622
|
let min5 = Number.MAX_VALUE;
|
|
29292
|
-
let
|
|
30623
|
+
let max6 = -Number.MAX_VALUE;
|
|
29293
30624
|
const snapshot = (now) => {
|
|
29294
30625
|
const builder = [];
|
|
29295
30626
|
let i3 = 0;
|
|
@@ -29329,8 +30660,8 @@ var init_Metric = __esm(() => {
|
|
|
29329
30660
|
if (value < min5) {
|
|
29330
30661
|
min5 = value;
|
|
29331
30662
|
}
|
|
29332
|
-
if (value >
|
|
29333
|
-
|
|
30663
|
+
if (value > max6) {
|
|
30664
|
+
max6 = value;
|
|
29334
30665
|
}
|
|
29335
30666
|
};
|
|
29336
30667
|
const get2 = (context2) => {
|
|
@@ -29340,7 +30671,7 @@ var init_Metric = __esm(() => {
|
|
|
29340
30671
|
quantiles,
|
|
29341
30672
|
count,
|
|
29342
30673
|
min: min5,
|
|
29343
|
-
max:
|
|
30674
|
+
max: max6,
|
|
29344
30675
|
sum: sum2
|
|
29345
30676
|
};
|
|
29346
30677
|
};
|
|
@@ -29959,7 +31290,7 @@ var exports_Fiber = {};
|
|
|
29959
31290
|
__export(exports_Fiber, {
|
|
29960
31291
|
runIn: () => runIn,
|
|
29961
31292
|
joinAll: () => joinAll,
|
|
29962
|
-
join: () =>
|
|
31293
|
+
join: () => join8,
|
|
29963
31294
|
isFiber: () => isFiber,
|
|
29964
31295
|
interruptAs: () => interruptAs,
|
|
29965
31296
|
interruptAllAs: () => interruptAllAs,
|
|
@@ -29969,13 +31300,13 @@ __export(exports_Fiber, {
|
|
|
29969
31300
|
awaitAll: () => awaitAll,
|
|
29970
31301
|
await: () => await_
|
|
29971
31302
|
});
|
|
29972
|
-
var await_, awaitAll,
|
|
31303
|
+
var await_, awaitAll, join8, joinAll, interrupt4, interruptAs, interruptAll, interruptAllAs, isFiber = (u) => hasProperty(u, FiberTypeId), getCurrent, runIn;
|
|
29973
31304
|
var init_Fiber = __esm(() => {
|
|
29974
31305
|
init_effect();
|
|
29975
31306
|
init_Predicate();
|
|
29976
31307
|
await_ = fiberAwait;
|
|
29977
31308
|
awaitAll = fiberAwaitAll;
|
|
29978
|
-
|
|
31309
|
+
join8 = fiberJoin;
|
|
29979
31310
|
joinAll = fiberJoinAll;
|
|
29980
31311
|
interrupt4 = fiberInterrupt;
|
|
29981
31312
|
interruptAs = fiberInterruptAs;
|
|
@@ -33161,7 +34492,7 @@ function handleCheckPropertyResult(result3, payload, property) {
|
|
|
33161
34492
|
}
|
|
33162
34493
|
}
|
|
33163
34494
|
var $ZodCheck, numericOriginMap, $ZodCheckLessThan, $ZodCheckGreaterThan, $ZodCheckMultipleOf, $ZodCheckNumberFormat, $ZodCheckBigIntFormat, $ZodCheckMaxSize, $ZodCheckMinSize, $ZodCheckSizeEquals, $ZodCheckMaxLength, $ZodCheckMinLength, $ZodCheckLengthEquals, $ZodCheckStringFormat, $ZodCheckRegex, $ZodCheckLowerCase, $ZodCheckUpperCase, $ZodCheckIncludes, $ZodCheckStartsWith, $ZodCheckEndsWith, $ZodCheckProperty, $ZodCheckMimeType, $ZodCheckOverwrite;
|
|
33164
|
-
var
|
|
34495
|
+
var init_checks2 = __esm(() => {
|
|
33165
34496
|
init_core2();
|
|
33166
34497
|
init_regexes();
|
|
33167
34498
|
init_util();
|
|
@@ -34158,7 +35489,7 @@ function handleRefineResult(result3, payload, input, inst) {
|
|
|
34158
35489
|
}
|
|
34159
35490
|
var $ZodType, $ZodString, $ZodStringFormat, $ZodGUID, $ZodUUID, $ZodEmail, $ZodURL, $ZodEmoji, $ZodNanoID, $ZodCUID, $ZodCUID2, $ZodULID, $ZodXID, $ZodKSUID, $ZodISODateTime, $ZodISODate, $ZodISOTime, $ZodISODuration, $ZodIPv4, $ZodIPv6, $ZodMAC, $ZodCIDRv4, $ZodCIDRv6, $ZodBase64, $ZodBase64URL, $ZodE164, $ZodJWT, $ZodCustomStringFormat, $ZodNumber, $ZodNumberFormat, $ZodBoolean, $ZodBigInt, $ZodBigIntFormat, $ZodSymbol, $ZodUndefined, $ZodNull, $ZodAny, $ZodUnknown, $ZodNever, $ZodVoid, $ZodDate, $ZodArray, $ZodObject, $ZodObjectJIT, $ZodUnion, $ZodXor, $ZodDiscriminatedUnion, $ZodIntersection, $ZodTuple, $ZodRecord, $ZodMap, $ZodSet, $ZodEnum, $ZodLiteral, $ZodFile, $ZodTransform, $ZodOptional, $ZodExactOptional, $ZodNullable, $ZodDefault, $ZodPrefault, $ZodNonOptional, $ZodSuccess, $ZodCatch, $ZodNaN, $ZodPipe, $ZodCodec, $ZodPreprocess, $ZodReadonly, $ZodTemplateLiteral, $ZodFunction, $ZodPromise, $ZodLazy, $ZodCustom;
|
|
34160
35491
|
var init_schemas = __esm(() => {
|
|
34161
|
-
|
|
35492
|
+
init_checks2();
|
|
34162
35493
|
init_core2();
|
|
34163
35494
|
init_parse();
|
|
34164
35495
|
init_regexes();
|
|
@@ -42977,7 +44308,7 @@ function _stringFormat(Class2, format3, fnOrRegex, _params = {}) {
|
|
|
42977
44308
|
}
|
|
42978
44309
|
var TimePrecision;
|
|
42979
44310
|
var init_api4 = __esm(() => {
|
|
42980
|
-
|
|
44311
|
+
init_checks2();
|
|
42981
44312
|
init_registries();
|
|
42982
44313
|
init_schemas();
|
|
42983
44314
|
init_util();
|
|
@@ -44207,7 +45538,7 @@ var init_core3 = __esm(() => {
|
|
|
44207
45538
|
init_parse();
|
|
44208
45539
|
init_errors2();
|
|
44209
45540
|
init_schemas();
|
|
44210
|
-
|
|
45541
|
+
init_checks2();
|
|
44211
45542
|
init_versions();
|
|
44212
45543
|
init_registries();
|
|
44213
45544
|
init_api4();
|
|
@@ -44247,7 +45578,7 @@ __export(exports_checks2, {
|
|
|
44247
45578
|
gt: () => _gt,
|
|
44248
45579
|
endsWith: () => _endsWith
|
|
44249
45580
|
});
|
|
44250
|
-
var
|
|
45581
|
+
var init_checks3 = __esm(() => {
|
|
44251
45582
|
init_core3();
|
|
44252
45583
|
});
|
|
44253
45584
|
|
|
@@ -45046,7 +46377,7 @@ var init_schemas2 = __esm(() => {
|
|
|
45046
46377
|
init_core3();
|
|
45047
46378
|
init_json_schema_processors();
|
|
45048
46379
|
init_to_json_schema();
|
|
45049
|
-
|
|
46380
|
+
init_checks3();
|
|
45050
46381
|
init_iso();
|
|
45051
46382
|
init_parse2();
|
|
45052
46383
|
_installedGroups = /* @__PURE__ */ new WeakMap;
|
|
@@ -46256,7 +47587,7 @@ function fromJSONSchema(schema, params) {
|
|
|
46256
47587
|
var z, RECOGNIZED_KEYS;
|
|
46257
47588
|
var init_from_json_schema = __esm(() => {
|
|
46258
47589
|
init_registries();
|
|
46259
|
-
|
|
47590
|
+
init_checks3();
|
|
46260
47591
|
init_iso();
|
|
46261
47592
|
init_schemas2();
|
|
46262
47593
|
z = {
|
|
@@ -46608,7 +47939,7 @@ var init_external = __esm(() => {
|
|
|
46608
47939
|
init_iso();
|
|
46609
47940
|
init_coerce();
|
|
46610
47941
|
init_schemas2();
|
|
46611
|
-
|
|
47942
|
+
init_checks3();
|
|
46612
47943
|
init_errors3();
|
|
46613
47944
|
init_parse2();
|
|
46614
47945
|
init_compat();
|
|
@@ -47853,7 +49184,7 @@ var init_conversation_mode = __esm(() => {
|
|
|
47853
49184
|
});
|
|
47854
49185
|
|
|
47855
49186
|
// ../shared/src/domain/task-envelope.ts
|
|
47856
|
-
function
|
|
49187
|
+
function isRecord6(value) {
|
|
47857
49188
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
47858
49189
|
}
|
|
47859
49190
|
function isConversationMode(value) {
|
|
@@ -47899,10 +49230,10 @@ function copyTaskEnvelope(envelope) {
|
|
|
47899
49230
|
};
|
|
47900
49231
|
}
|
|
47901
49232
|
function isEnvelopeRecordAndVersion(value) {
|
|
47902
|
-
return
|
|
49233
|
+
return isRecord6(value) && value.version === TASK_ENVELOPE_VERSION;
|
|
47903
49234
|
}
|
|
47904
49235
|
function isWorkflowShape(workflow) {
|
|
47905
|
-
return
|
|
49236
|
+
return isRecord6(workflow) && isHandoffPreset(workflow.preset) && isHandoffPhase(workflow.phase);
|
|
47906
49237
|
}
|
|
47907
49238
|
function isPresetChoice(workflow, mode) {
|
|
47908
49239
|
return workflow.preset === workflowPresetForMode(mode);
|
|
@@ -49792,17 +51123,17 @@ import {
|
|
|
49792
51123
|
writeFileSync
|
|
49793
51124
|
} from "node:fs";
|
|
49794
51125
|
import { homedir as homedir2 } from "node:os";
|
|
49795
|
-
import { join as
|
|
51126
|
+
import { join as join9 } from "node:path";
|
|
49796
51127
|
function getUrlHash() {
|
|
49797
51128
|
const url2 = getConvexUrl();
|
|
49798
51129
|
return createHash4("sha256").update(url2).digest("hex").substring(0, 8);
|
|
49799
51130
|
}
|
|
49800
51131
|
function getChildPidsFilePath() {
|
|
49801
|
-
const dir =
|
|
49802
|
-
return
|
|
51132
|
+
const dir = join9(homedir2(), ".chatroom");
|
|
51133
|
+
return join9(dir, `daemon-children-${getUrlHash()}.pids`);
|
|
49803
51134
|
}
|
|
49804
51135
|
function ensureChatroomDir() {
|
|
49805
|
-
const dir =
|
|
51136
|
+
const dir = join9(homedir2(), ".chatroom");
|
|
49806
51137
|
if (!existsSync(dir)) {
|
|
49807
51138
|
mkdirSync(dir, { recursive: true, mode: 448 });
|
|
49808
51139
|
}
|
|
@@ -53131,7 +54462,7 @@ var init_task_service = __esm(() => {
|
|
|
53131
54462
|
|
|
53132
54463
|
// src/daemon/services/task-service/infrastructure/repository/task-handoff-repository.ts
|
|
53133
54464
|
import { mkdirSync as mkdirSync2 } from "node:fs";
|
|
53134
|
-
import { dirname as
|
|
54465
|
+
import { dirname as dirname9 } from "node:path";
|
|
53135
54466
|
import { DatabaseSync } from "node:sqlite";
|
|
53136
54467
|
function normalizeRole(role) {
|
|
53137
54468
|
return role.toLowerCase();
|
|
@@ -53151,7 +54482,7 @@ function mapRow(row) {
|
|
|
53151
54482
|
};
|
|
53152
54483
|
}
|
|
53153
54484
|
function createTaskHandoffRepository(dbPath) {
|
|
53154
|
-
mkdirSync2(
|
|
54485
|
+
mkdirSync2(dirname9(dbPath), { recursive: true });
|
|
53155
54486
|
const db = new DatabaseSync(dbPath);
|
|
53156
54487
|
db.exec(`
|
|
53157
54488
|
CREATE TABLE IF NOT EXISTS task_handoffs (
|
|
@@ -55709,7 +57040,7 @@ function createAgentLogWriter(prefix, options) {
|
|
|
55709
57040
|
var BASH_TOOL_KIND = "tool: bash", BASH_RUNNING_PREFIX = "running:";
|
|
55710
57041
|
|
|
55711
57042
|
// src/daemon/infrastructure/local/harness/services/pi/pi-agent-service.ts
|
|
55712
|
-
import { join as
|
|
57043
|
+
import { join as join10 } from "node:path";
|
|
55713
57044
|
function isExplicitToolError(result3) {
|
|
55714
57045
|
if (result3 === null || typeof result3 !== "object")
|
|
55715
57046
|
return false;
|
|
@@ -55719,7 +57050,7 @@ function isExplicitToolError(result3) {
|
|
|
55719
57050
|
return "error" in obj && obj.error !== undefined;
|
|
55720
57051
|
}
|
|
55721
57052
|
function getPiSessionDir(workingDir) {
|
|
55722
|
-
return
|
|
57053
|
+
return join10(workingDir, ".chatroom", "pi-sessions");
|
|
55723
57054
|
}
|
|
55724
57055
|
var PI_COMMAND = "pi", GET_STATE_TIMEOUT_MS = 5000, PiAgentService;
|
|
55725
57056
|
var init_pi_agent_service = __esm(() => {
|
|
@@ -56176,25 +57507,25 @@ var init_model_provider = () => {};
|
|
|
56176
57507
|
// src/daemon/infrastructure/local/harness/services/cursor-sdk/cursor-sdk-package.ts
|
|
56177
57508
|
import { existsSync as existsSync2, readFileSync as readFileSync5 } from "node:fs";
|
|
56178
57509
|
import { createRequire as createRequire5 } from "node:module";
|
|
56179
|
-
import { dirname as
|
|
57510
|
+
import { dirname as dirname10, join as join11 } from "node:path";
|
|
56180
57511
|
import { fileURLToPath as fileURLToPath2, pathToFileURL } from "node:url";
|
|
56181
57512
|
function resolveChatroomCliRoot(moduleRef = import.meta.url) {
|
|
56182
57513
|
const filePath = moduleRef.startsWith("file:") ? fileURLToPath2(moduleRef) : moduleRef;
|
|
56183
|
-
let dir =
|
|
56184
|
-
while (dir !==
|
|
56185
|
-
const packageJsonPath =
|
|
57514
|
+
let dir = dirname10(filePath);
|
|
57515
|
+
while (dir !== dirname10(dir)) {
|
|
57516
|
+
const packageJsonPath = join11(dir, "package.json");
|
|
56186
57517
|
if (existsSync2(packageJsonPath)) {
|
|
56187
57518
|
const pkg = JSON.parse(readFileSync5(packageJsonPath, "utf8"));
|
|
56188
57519
|
if (pkg.name === "chatroom-cli") {
|
|
56189
57520
|
return dir;
|
|
56190
57521
|
}
|
|
56191
57522
|
}
|
|
56192
|
-
dir =
|
|
57523
|
+
dir = dirname10(dir);
|
|
56193
57524
|
}
|
|
56194
57525
|
throw new CursorSdkPackageError(`Could not locate chatroom-cli package root while resolving @cursor/sdk. ${REINSTALL_HINT}`);
|
|
56195
57526
|
}
|
|
56196
57527
|
function readPinnedSdkVersion(chatroomCliRoot) {
|
|
56197
|
-
const pkg = JSON.parse(readFileSync5(
|
|
57528
|
+
const pkg = JSON.parse(readFileSync5(join11(chatroomCliRoot, "package.json"), "utf8"));
|
|
56198
57529
|
const specifier = pkg.dependencies?.["@cursor/sdk"];
|
|
56199
57530
|
const pinned = specifier?.replace(/^[\^~>=<]+/, "").trim() ?? "";
|
|
56200
57531
|
const match5 = pinned.match(/^(\d+\.\d+\.\d+)/);
|
|
@@ -56204,7 +57535,7 @@ function readPinnedSdkVersion(chatroomCliRoot) {
|
|
|
56204
57535
|
return match5[1];
|
|
56205
57536
|
}
|
|
56206
57537
|
function readInstalledSdkVersion(entryPath) {
|
|
56207
|
-
const packageJsonPath =
|
|
57538
|
+
const packageJsonPath = join11(dirname10(entryPath), "..", "..", "package.json");
|
|
56208
57539
|
const pkg = JSON.parse(readFileSync5(packageJsonPath, "utf8"));
|
|
56209
57540
|
return pkg.version;
|
|
56210
57541
|
}
|
|
@@ -56217,7 +57548,7 @@ function resolveSdkEsmImportPath(cjsEntryPath) {
|
|
|
56217
57548
|
}
|
|
56218
57549
|
async function importBundledCursorSdk(moduleRef = import.meta.url) {
|
|
56219
57550
|
const chatroomCliRoot = resolveChatroomCliRoot(moduleRef);
|
|
56220
|
-
const require4 = createRequire5(
|
|
57551
|
+
const require4 = createRequire5(join11(chatroomCliRoot, "package.json"));
|
|
56221
57552
|
const pinnedVersion = readPinnedSdkVersion(chatroomCliRoot);
|
|
56222
57553
|
const entryPath = require4.resolve("@cursor/sdk", { paths: [chatroomCliRoot] });
|
|
56223
57554
|
const installedVersion = readInstalledSdkVersion(entryPath);
|
|
@@ -56233,7 +57564,7 @@ async function importBundledCursorSdk(moduleRef = import.meta.url) {
|
|
|
56233
57564
|
}
|
|
56234
57565
|
function getBundledCursorSdkVersion(moduleRef = import.meta.url) {
|
|
56235
57566
|
const chatroomCliRoot = resolveChatroomCliRoot(moduleRef);
|
|
56236
|
-
const require4 = createRequire5(
|
|
57567
|
+
const require4 = createRequire5(join11(chatroomCliRoot, "package.json"));
|
|
56237
57568
|
const entryPath = require4.resolve("@cursor/sdk", { paths: [chatroomCliRoot] });
|
|
56238
57569
|
return readInstalledSdkVersion(entryPath);
|
|
56239
57570
|
}
|
|
@@ -57125,25 +58456,25 @@ import {
|
|
|
57125
58456
|
} from "node:fs";
|
|
57126
58457
|
import { createRequire as createRequire6 } from "node:module";
|
|
57127
58458
|
import { homedir as homedir3 } from "node:os";
|
|
57128
|
-
import { basename as
|
|
58459
|
+
import { basename as basename6, dirname as dirname11, join as join12 } from "node:path";
|
|
57129
58460
|
import { fileURLToPath as fileURLToPath3, pathToFileURL as pathToFileURL2 } from "node:url";
|
|
57130
58461
|
function resolveChatroomCliRoot2(moduleRef = import.meta.url) {
|
|
57131
58462
|
const filePath = moduleRef.startsWith("file:") ? fileURLToPath3(moduleRef) : moduleRef;
|
|
57132
|
-
let dir =
|
|
57133
|
-
while (dir !==
|
|
57134
|
-
const packageJsonPath =
|
|
58463
|
+
let dir = dirname11(filePath);
|
|
58464
|
+
while (dir !== dirname11(dir)) {
|
|
58465
|
+
const packageJsonPath = join12(dir, "package.json");
|
|
57135
58466
|
if (existsSync3(packageJsonPath)) {
|
|
57136
58467
|
const pkg = JSON.parse(readFileSync6(packageJsonPath, "utf8"));
|
|
57137
58468
|
if (pkg.name === "chatroom-cli") {
|
|
57138
58469
|
return realpathSync(dir);
|
|
57139
58470
|
}
|
|
57140
58471
|
}
|
|
57141
|
-
dir =
|
|
58472
|
+
dir = dirname11(dir);
|
|
57142
58473
|
}
|
|
57143
58474
|
throw new ClaudeSdkPackageError(`Could not locate chatroom-cli package root while resolving ${CLAUDE_AGENT_SDK_PKG}. ${REINSTALL_HINT2}`);
|
|
57144
58475
|
}
|
|
57145
58476
|
function readPinnedSdkVersion2(chatroomCliRoot) {
|
|
57146
|
-
const pkg = JSON.parse(readFileSync6(
|
|
58477
|
+
const pkg = JSON.parse(readFileSync6(join12(chatroomCliRoot, "package.json"), "utf8"));
|
|
57147
58478
|
const specifier = pkg.dependencies?.[CLAUDE_AGENT_SDK_PKG];
|
|
57148
58479
|
const pinned = specifier?.replace(/^[\^~>=<]+/, "").trim() ?? "";
|
|
57149
58480
|
const match5 = pinned.match(/^(\d+\.\d+\.\d+)/);
|
|
@@ -57153,7 +58484,7 @@ function readPinnedSdkVersion2(chatroomCliRoot) {
|
|
|
57153
58484
|
return match5[1];
|
|
57154
58485
|
}
|
|
57155
58486
|
function readInstalledSdkVersion2(entryPath) {
|
|
57156
|
-
const packageJsonPath =
|
|
58487
|
+
const packageJsonPath = join12(dirname11(entryPath), "package.json");
|
|
57157
58488
|
const pkg = JSON.parse(readFileSync6(packageJsonPath, "utf8"));
|
|
57158
58489
|
return pkg.version;
|
|
57159
58490
|
}
|
|
@@ -57179,19 +58510,19 @@ function resolveNativeCliBinaryPath(sdkEntryPath) {
|
|
|
57179
58510
|
const binaryName = process.platform === "win32" ? "claude.exe" : "claude";
|
|
57180
58511
|
let pkgDir;
|
|
57181
58512
|
try {
|
|
57182
|
-
pkgDir =
|
|
58513
|
+
pkgDir = dirname11(require4.resolve(`${platformPkg}/package.json`));
|
|
57183
58514
|
} catch {
|
|
57184
58515
|
throw new ClaudeSdkPackageError(`Native CLI binary package ${platformPkg} is not installed. ${REINSTALL_HINT2}`);
|
|
57185
58516
|
}
|
|
57186
|
-
const binaryPath =
|
|
58517
|
+
const binaryPath = join12(pkgDir, binaryName);
|
|
57187
58518
|
if (!existsSync3(binaryPath)) {
|
|
57188
58519
|
throw new ClaudeSdkPackageError(`Native CLI binary is missing: ${binaryPath}. ${REINSTALL_HINT2}`);
|
|
57189
58520
|
}
|
|
57190
58521
|
return binaryPath;
|
|
57191
58522
|
}
|
|
57192
58523
|
function pinNativeBinary(sourcePath, sdkVersion, pinRoot) {
|
|
57193
|
-
const dir =
|
|
57194
|
-
const pinnedPath =
|
|
58524
|
+
const dir = join12(pinRoot, sdkVersion);
|
|
58525
|
+
const pinnedPath = join12(dir, basename6(sourcePath));
|
|
57195
58526
|
if (existsSync3(pinnedPath))
|
|
57196
58527
|
return pinnedPath;
|
|
57197
58528
|
mkdirSync3(dir, { recursive: true, mode: 448 });
|
|
@@ -57205,7 +58536,7 @@ async function resolvePathToClaudeCodeExecutable(moduleRef = import.meta.url) {
|
|
|
57205
58536
|
if (cachedExecutablePath)
|
|
57206
58537
|
return cachedExecutablePath;
|
|
57207
58538
|
const chatroomCliRoot = resolveChatroomCliRoot2(moduleRef);
|
|
57208
|
-
const require4 = createRequire6(
|
|
58539
|
+
const require4 = createRequire6(join12(chatroomCliRoot, "package.json"));
|
|
57209
58540
|
const sdkEntryPath = require4.resolve(CLAUDE_AGENT_SDK_PKG, { paths: [chatroomCliRoot] });
|
|
57210
58541
|
const embeddedPath = resolveNativeCliBinaryPath(sdkEntryPath);
|
|
57211
58542
|
const { extractFromBunfs } = await import("@anthropic-ai/claude-agent-sdk/extract");
|
|
@@ -57215,7 +58546,7 @@ async function resolvePathToClaudeCodeExecutable(moduleRef = import.meta.url) {
|
|
|
57215
58546
|
}
|
|
57216
58547
|
async function importBundledClaudeSdk(moduleRef = import.meta.url) {
|
|
57217
58548
|
const chatroomCliRoot = resolveChatroomCliRoot2(moduleRef);
|
|
57218
|
-
const require4 = createRequire6(
|
|
58549
|
+
const require4 = createRequire6(join12(chatroomCliRoot, "package.json"));
|
|
57219
58550
|
const pinnedVersion = readPinnedSdkVersion2(chatroomCliRoot);
|
|
57220
58551
|
const entryPath = require4.resolve(CLAUDE_AGENT_SDK_PKG, { paths: [chatroomCliRoot] });
|
|
57221
58552
|
const installedVersion = readInstalledSdkVersion2(entryPath);
|
|
@@ -57229,7 +58560,7 @@ async function importBundledClaudeSdk(moduleRef = import.meta.url) {
|
|
|
57229
58560
|
}
|
|
57230
58561
|
function getBundledClaudeSdkVersion(moduleRef = import.meta.url) {
|
|
57231
58562
|
const chatroomCliRoot = resolveChatroomCliRoot2(moduleRef);
|
|
57232
|
-
const require4 = createRequire6(
|
|
58563
|
+
const require4 = createRequire6(join12(chatroomCliRoot, "package.json"));
|
|
57233
58564
|
const entryPath = require4.resolve(CLAUDE_AGENT_SDK_PKG, { paths: [chatroomCliRoot] });
|
|
57234
58565
|
return readInstalledSdkVersion2(entryPath);
|
|
57235
58566
|
}
|
|
@@ -57252,7 +58583,7 @@ var init_claude_sdk_package = __esm(() => {
|
|
|
57252
58583
|
this.name = "ClaudeSdkPackageError";
|
|
57253
58584
|
}
|
|
57254
58585
|
};
|
|
57255
|
-
PINNED_BINARY_ROOT =
|
|
58586
|
+
PINNED_BINARY_ROOT = join12(homedir3(), ".chatroom", "claude-native");
|
|
57256
58587
|
});
|
|
57257
58588
|
|
|
57258
58589
|
// src/daemon/infrastructure/local/harness/services/assistant-text-capture.ts
|
|
@@ -58113,25 +59444,25 @@ var init_codex_sdk_model_variants = __esm(() => {
|
|
|
58113
59444
|
// src/daemon/infrastructure/local/harness/services/codex-sdk/codex-sdk-package.ts
|
|
58114
59445
|
import { existsSync as existsSync4, readFileSync as readFileSync7, realpathSync as realpathSync2, statSync } from "node:fs";
|
|
58115
59446
|
import { createRequire as createRequire7 } from "node:module";
|
|
58116
|
-
import { dirname as
|
|
59447
|
+
import { dirname as dirname12, join as join13 } from "node:path";
|
|
58117
59448
|
import { fileURLToPath as fileURLToPath4, pathToFileURL as pathToFileURL3 } from "node:url";
|
|
58118
59449
|
function resolveChatroomCliRoot3(moduleRef = import.meta.url) {
|
|
58119
59450
|
const filePath = moduleRef.startsWith("file:") ? fileURLToPath4(moduleRef) : moduleRef;
|
|
58120
|
-
let dir =
|
|
58121
|
-
while (dir !==
|
|
58122
|
-
const packageJsonPath =
|
|
59451
|
+
let dir = dirname12(filePath);
|
|
59452
|
+
while (dir !== dirname12(dir)) {
|
|
59453
|
+
const packageJsonPath = join13(dir, "package.json");
|
|
58123
59454
|
if (existsSync4(packageJsonPath)) {
|
|
58124
59455
|
const pkg = JSON.parse(readFileSync7(packageJsonPath, "utf8"));
|
|
58125
59456
|
if (pkg.name === "chatroom-cli") {
|
|
58126
59457
|
return dir;
|
|
58127
59458
|
}
|
|
58128
59459
|
}
|
|
58129
|
-
dir =
|
|
59460
|
+
dir = dirname12(dir);
|
|
58130
59461
|
}
|
|
58131
59462
|
throw new CodexSdkPackageError(`Could not locate chatroom-cli package root while resolving @openai/codex-sdk. ${REINSTALL_HINT3}`);
|
|
58132
59463
|
}
|
|
58133
59464
|
function readPinnedSdkVersion3(chatroomCliRoot) {
|
|
58134
|
-
const pkg = JSON.parse(readFileSync7(
|
|
59465
|
+
const pkg = JSON.parse(readFileSync7(join13(chatroomCliRoot, "package.json"), "utf8"));
|
|
58135
59466
|
const specifier = pkg.dependencies?.["@openai/codex-sdk"];
|
|
58136
59467
|
const pinned = specifier?.replace(/^[\^~>=<]+/, "").trim() ?? "";
|
|
58137
59468
|
const match5 = pinned.match(/^(\d+\.\d+\.\d+)/);
|
|
@@ -58145,11 +59476,11 @@ function readInstalledSdkVersion3(packageJsonPath) {
|
|
|
58145
59476
|
return pkg.version;
|
|
58146
59477
|
}
|
|
58147
59478
|
function resolveCodexSdkPackageJson(chatroomCliRoot) {
|
|
58148
|
-
const require4 = createRequire7(
|
|
59479
|
+
const require4 = createRequire7(join13(chatroomCliRoot, "package.json"));
|
|
58149
59480
|
try {
|
|
58150
59481
|
return require4.resolve("@openai/codex-sdk/package.json", { paths: [chatroomCliRoot] });
|
|
58151
59482
|
} catch {
|
|
58152
|
-
const candidate =
|
|
59483
|
+
const candidate = join13(chatroomCliRoot, "node_modules", "@openai", "codex-sdk", "package.json");
|
|
58153
59484
|
if (existsSync4(candidate)) {
|
|
58154
59485
|
return candidate;
|
|
58155
59486
|
}
|
|
@@ -58193,7 +59524,7 @@ function addPlatformPackageJsonCandidate(candidates, candidate) {
|
|
|
58193
59524
|
}
|
|
58194
59525
|
function resolvePlatformPackageJsonCandidates(platformPkg, chatroomCliRoot, codexPackageJson, chatroomRequire, codexRequire) {
|
|
58195
59526
|
const candidates = [];
|
|
58196
|
-
const codexPackageDir = realpathSync2(
|
|
59527
|
+
const codexPackageDir = realpathSync2(dirname12(codexPackageJson));
|
|
58197
59528
|
const platformPkgBaseName = platformPkg.includes("/") ? platformPkg.slice(platformPkg.indexOf("/") + 1) : platformPkg;
|
|
58198
59529
|
try {
|
|
58199
59530
|
addPlatformPackageJsonCandidate(candidates, codexRequire.resolve(`${platformPkg}/package.json`));
|
|
@@ -58201,17 +59532,17 @@ function resolvePlatformPackageJsonCandidates(platformPkg, chatroomCliRoot, code
|
|
|
58201
59532
|
try {
|
|
58202
59533
|
addPlatformPackageJsonCandidate(candidates, chatroomRequire.resolve(`${platformPkg}/package.json`, { paths: [chatroomCliRoot] }));
|
|
58203
59534
|
} catch {}
|
|
58204
|
-
addPlatformPackageJsonCandidate(candidates,
|
|
58205
|
-
addPlatformPackageJsonCandidate(candidates,
|
|
59535
|
+
addPlatformPackageJsonCandidate(candidates, join13(codexPackageDir, "..", platformPkgBaseName, "package.json"));
|
|
59536
|
+
addPlatformPackageJsonCandidate(candidates, join13(codexPackageDir, "node_modules", platformPkg, "package.json"));
|
|
58206
59537
|
return candidates;
|
|
58207
59538
|
}
|
|
58208
59539
|
function resolveNativeCodexBinary(vendorRoot, targetTriple, codexBinaryName) {
|
|
58209
|
-
const packageRoot =
|
|
58210
|
-
const packageBinaryPath =
|
|
58211
|
-
if (isRegularFile(packageBinaryPath) && isRegularFile(
|
|
59540
|
+
const packageRoot = join13(vendorRoot, targetTriple);
|
|
59541
|
+
const packageBinaryPath = join13(packageRoot, "bin", codexBinaryName);
|
|
59542
|
+
if (isRegularFile(packageBinaryPath) && isRegularFile(join13(packageRoot, "codex-package.json"))) {
|
|
58212
59543
|
return packageBinaryPath;
|
|
58213
59544
|
}
|
|
58214
|
-
const legacyBinaryPath =
|
|
59545
|
+
const legacyBinaryPath = join13(packageRoot, "codex", codexBinaryName);
|
|
58215
59546
|
if (isRegularFile(legacyBinaryPath)) {
|
|
58216
59547
|
return legacyBinaryPath;
|
|
58217
59548
|
}
|
|
@@ -58219,7 +59550,7 @@ function resolveNativeCodexBinary(vendorRoot, targetTriple, codexBinaryName) {
|
|
|
58219
59550
|
}
|
|
58220
59551
|
function resolveCodexExecutablePath(moduleRef = import.meta.url) {
|
|
58221
59552
|
const chatroomCliRoot = resolveChatroomCliRoot3(moduleRef);
|
|
58222
|
-
const require4 = createRequire7(
|
|
59553
|
+
const require4 = createRequire7(join13(chatroomCliRoot, "package.json"));
|
|
58223
59554
|
let codexPackageJson;
|
|
58224
59555
|
try {
|
|
58225
59556
|
codexPackageJson = require4.resolve(`${CODEX_NPM_NAME}/package.json`, {
|
|
@@ -58237,7 +59568,7 @@ function resolveCodexExecutablePath(moduleRef = import.meta.url) {
|
|
|
58237
59568
|
throw new CodexSdkPackageError(`Native Codex CLI package ${platformPkg} is not installed. Ensure ${CODEX_NPM_NAME} is installed with optional dependencies. ${REINSTALL_HINT3}`);
|
|
58238
59569
|
}
|
|
58239
59570
|
for (const platformPackageJson of platformPackageJsonCandidates) {
|
|
58240
|
-
const vendorRoot =
|
|
59571
|
+
const vendorRoot = join13(dirname12(platformPackageJson), "vendor");
|
|
58241
59572
|
const binaryPath = resolveNativeCodexBinary(vendorRoot, targetTriple, codexBinaryName);
|
|
58242
59573
|
if (binaryPath) {
|
|
58243
59574
|
return binaryPath;
|
|
@@ -58253,7 +59584,7 @@ async function importBundledCodexSdk(moduleRef = import.meta.url) {
|
|
|
58253
59584
|
if (installedVersion !== pinnedVersion) {
|
|
58254
59585
|
throw new CodexSdkPackageError(`@openai/codex-sdk@${installedVersion} does not match chatroom-cli pin (${pinnedVersion}). ${REINSTALL_HINT3}`);
|
|
58255
59586
|
}
|
|
58256
|
-
const distEntryPath =
|
|
59587
|
+
const distEntryPath = join13(dirname12(packageJsonPath), "dist", "index.js");
|
|
58257
59588
|
if (!existsSync4(distEntryPath)) {
|
|
58258
59589
|
throw new CodexSdkPackageError(`@openai/codex-sdk entry file is missing: ${distEntryPath}. ${REINSTALL_HINT3}`);
|
|
58259
59590
|
}
|
|
@@ -60346,12 +61677,12 @@ var init_session_event_forwarder = __esm(() => {
|
|
|
60346
61677
|
// src/daemon/infrastructure/local/harness/services/opencode-sdk/session-metadata-store.ts
|
|
60347
61678
|
import { chmodSync as chmodSync2, existsSync as existsSync5, mkdirSync as mkdirSync4, readFileSync as readFileSync8, writeFileSync as writeFileSync2 } from "node:fs";
|
|
60348
61679
|
import { homedir as homedir4 } from "node:os";
|
|
60349
|
-
import { dirname as
|
|
61680
|
+
import { dirname as dirname13, join as join14 } from "node:path";
|
|
60350
61681
|
|
|
60351
61682
|
class FileSessionMetadataStore {
|
|
60352
61683
|
filePath;
|
|
60353
61684
|
constructor(filePath) {
|
|
60354
|
-
this.filePath = filePath ??
|
|
61685
|
+
this.filePath = filePath ?? join14(homedir4(), ".chatroom", "opencode-sdk-sessions.json");
|
|
60355
61686
|
}
|
|
60356
61687
|
load() {
|
|
60357
61688
|
try {
|
|
@@ -60363,7 +61694,7 @@ class FileSessionMetadataStore {
|
|
|
60363
61694
|
}
|
|
60364
61695
|
save(sessions) {
|
|
60365
61696
|
try {
|
|
60366
|
-
const dir =
|
|
61697
|
+
const dir = dirname13(this.filePath);
|
|
60367
61698
|
if (!existsSync5(dir)) {
|
|
60368
61699
|
mkdirSync4(dir, { recursive: true, mode: 448 });
|
|
60369
61700
|
}
|
|
@@ -60946,25 +62277,25 @@ var init_opencode_sdk = __esm(() => {
|
|
|
60946
62277
|
|
|
60947
62278
|
// src/daemon/infrastructure/local/harness/services/pi-sdk/pi-sdk-package.ts
|
|
60948
62279
|
import { existsSync as existsSync6, readFileSync as readFileSync9 } from "node:fs";
|
|
60949
|
-
import { dirname as
|
|
62280
|
+
import { dirname as dirname14, join as join15 } from "node:path";
|
|
60950
62281
|
import { fileURLToPath as fileURLToPath5, pathToFileURL as pathToFileURL4 } from "node:url";
|
|
60951
62282
|
function resolveChatroomCliRoot4(moduleRef = import.meta.url) {
|
|
60952
62283
|
const filePath = moduleRef.startsWith("file:") ? fileURLToPath5(moduleRef) : moduleRef;
|
|
60953
|
-
let dir =
|
|
60954
|
-
while (dir !==
|
|
60955
|
-
const packageJsonPath =
|
|
62284
|
+
let dir = dirname14(filePath);
|
|
62285
|
+
while (dir !== dirname14(dir)) {
|
|
62286
|
+
const packageJsonPath = join15(dir, "package.json");
|
|
60956
62287
|
if (existsSync6(packageJsonPath)) {
|
|
60957
62288
|
const pkg = JSON.parse(readFileSync9(packageJsonPath, "utf8"));
|
|
60958
62289
|
if (pkg.name === "chatroom-cli") {
|
|
60959
62290
|
return dir;
|
|
60960
62291
|
}
|
|
60961
62292
|
}
|
|
60962
|
-
dir =
|
|
62293
|
+
dir = dirname14(dir);
|
|
60963
62294
|
}
|
|
60964
62295
|
throw new PiSdkPackageError(`Could not locate chatroom-cli package root while resolving ${PI_CODING_AGENT_PKG}. ${REINSTALL_HINT4}`);
|
|
60965
62296
|
}
|
|
60966
62297
|
function readPinnedSdkVersion4(chatroomCliRoot) {
|
|
60967
|
-
const pkg = JSON.parse(readFileSync9(
|
|
62298
|
+
const pkg = JSON.parse(readFileSync9(join15(chatroomCliRoot, "package.json"), "utf8"));
|
|
60968
62299
|
const specifier = pkg.dependencies?.[PI_CODING_AGENT_PKG];
|
|
60969
62300
|
const pinned = specifier?.replace(/^[\^~>=<]+/, "").trim() ?? "";
|
|
60970
62301
|
const match5 = pinned.match(/^(\d+\.\d+\.\d+)/);
|
|
@@ -60974,18 +62305,18 @@ function readPinnedSdkVersion4(chatroomCliRoot) {
|
|
|
60974
62305
|
return match5[1];
|
|
60975
62306
|
}
|
|
60976
62307
|
function readInstalledSdkVersion4(entryPath) {
|
|
60977
|
-
const packageJsonPath =
|
|
62308
|
+
const packageJsonPath = join15(dirname14(entryPath), "..", "package.json");
|
|
60978
62309
|
const pkg = JSON.parse(readFileSync9(packageJsonPath, "utf8"));
|
|
60979
62310
|
return pkg.version;
|
|
60980
62311
|
}
|
|
60981
62312
|
function resolvePiSdkEntryPathFromNodeModules(chatroomCliRoot) {
|
|
60982
62313
|
let dir = chatroomCliRoot;
|
|
60983
|
-
while (dir !==
|
|
60984
|
-
const entryPath =
|
|
62314
|
+
while (dir !== dirname14(dir)) {
|
|
62315
|
+
const entryPath = join15(dir, "node_modules", PI_CODING_AGENT_PKG, "dist", "index.js");
|
|
60985
62316
|
if (existsSync6(entryPath)) {
|
|
60986
62317
|
return entryPath;
|
|
60987
62318
|
}
|
|
60988
|
-
dir =
|
|
62319
|
+
dir = dirname14(dir);
|
|
60989
62320
|
}
|
|
60990
62321
|
return;
|
|
60991
62322
|
}
|
|
@@ -60993,7 +62324,7 @@ function resolvePiSdkEntryPath(chatroomCliRoot) {
|
|
|
60993
62324
|
const resolveMeta = import.meta.resolve;
|
|
60994
62325
|
if (typeof resolveMeta === "function") {
|
|
60995
62326
|
try {
|
|
60996
|
-
const parentUrl = pathToFileURL4(
|
|
62327
|
+
const parentUrl = pathToFileURL4(join15(chatroomCliRoot, "package.json")).href;
|
|
60997
62328
|
return fileURLToPath5(resolveMeta(PI_CODING_AGENT_PKG, parentUrl));
|
|
60998
62329
|
} catch {}
|
|
60999
62330
|
}
|
|
@@ -61720,7 +63051,7 @@ var MACHINE_CONFIG_VERSION = "1";
|
|
|
61720
63051
|
import { randomBytes, randomUUID as randomUUID7 } from "node:crypto";
|
|
61721
63052
|
import * as fs4 from "node:fs/promises";
|
|
61722
63053
|
import { homedir as homedir5, hostname as hostname4 } from "node:os";
|
|
61723
|
-
import { join as
|
|
63054
|
+
import { join as join16 } from "node:path";
|
|
61724
63055
|
function enqueueMachineConfigSave(task) {
|
|
61725
63056
|
const run = saveChain.then(task, task);
|
|
61726
63057
|
saveChain = run.catch(() => {
|
|
@@ -61729,14 +63060,14 @@ function enqueueMachineConfigSave(task) {
|
|
|
61729
63060
|
return run;
|
|
61730
63061
|
}
|
|
61731
63062
|
function chatroomConfigDir() {
|
|
61732
|
-
return
|
|
63063
|
+
return join16(homedir5(), ".chatroom");
|
|
61733
63064
|
}
|
|
61734
63065
|
async function ensureConfigDir2() {
|
|
61735
63066
|
const dir = chatroomConfigDir();
|
|
61736
63067
|
await fs4.mkdir(dir, { recursive: true, mode: 448 });
|
|
61737
63068
|
}
|
|
61738
63069
|
function getMachineConfigPath() {
|
|
61739
|
-
return
|
|
63070
|
+
return join16(chatroomConfigDir(), MACHINE_FILE);
|
|
61740
63071
|
}
|
|
61741
63072
|
async function loadConfigFile() {
|
|
61742
63073
|
const configPath = getMachineConfigPath();
|
|
@@ -61838,7 +63169,7 @@ var init_storage2 = __esm(() => {
|
|
|
61838
63169
|
// src/infrastructure/machine/daemon-state.ts
|
|
61839
63170
|
import * as fs5 from "node:fs/promises";
|
|
61840
63171
|
import { homedir as homedir6 } from "node:os";
|
|
61841
|
-
import { join as
|
|
63172
|
+
import { join as join17 } from "node:path";
|
|
61842
63173
|
function agentKey3(chatroomId, role, workingDir) {
|
|
61843
63174
|
return workingDir ? `${chatroomId}/${role}/${encodeURIComponent(workingDir)}` : `${chatroomId}/${role}`;
|
|
61844
63175
|
}
|
|
@@ -61846,7 +63177,7 @@ async function ensureStateDir() {
|
|
|
61846
63177
|
await fs5.mkdir(STATE_DIR, { recursive: true, mode: 448 });
|
|
61847
63178
|
}
|
|
61848
63179
|
function stateFilePath(machineId) {
|
|
61849
|
-
return
|
|
63180
|
+
return join17(STATE_DIR, `${machineId}.json`);
|
|
61850
63181
|
}
|
|
61851
63182
|
async function loadDaemonState(machineId) {
|
|
61852
63183
|
const filePath = stateFilePath(machineId);
|
|
@@ -61947,8 +63278,8 @@ async function loadEventCursor(machineId) {
|
|
|
61947
63278
|
}
|
|
61948
63279
|
var CHATROOM_DIR2, STATE_DIR, STATE_VERSION = "1";
|
|
61949
63280
|
var init_daemon_state = __esm(() => {
|
|
61950
|
-
CHATROOM_DIR2 =
|
|
61951
|
-
STATE_DIR =
|
|
63281
|
+
CHATROOM_DIR2 = join17(homedir6(), ".chatroom");
|
|
63282
|
+
STATE_DIR = join17(CHATROOM_DIR2, "machines", "state");
|
|
61952
63283
|
});
|
|
61953
63284
|
|
|
61954
63285
|
// src/infrastructure/machine/index.ts
|
|
@@ -68791,8 +70122,8 @@ var init_backo2 = __esm(() => {
|
|
|
68791
70122
|
Backoff.prototype.setMin = function(min5) {
|
|
68792
70123
|
this.ms = min5;
|
|
68793
70124
|
};
|
|
68794
|
-
Backoff.prototype.setMax = function(
|
|
68795
|
-
this.max =
|
|
70125
|
+
Backoff.prototype.setMax = function(max6) {
|
|
70126
|
+
this.max = max6;
|
|
68796
70127
|
};
|
|
68797
70128
|
Backoff.prototype.setJitter = function(jitter) {
|
|
68798
70129
|
this.jitter = jitter;
|
|
@@ -69351,9 +70682,9 @@ function resolveEnvSlug(convexUrl) {
|
|
|
69351
70682
|
|
|
69352
70683
|
// src/infrastructure/log-server/resolve-logs-db-path.ts
|
|
69353
70684
|
import { homedir as homedir7 } from "node:os";
|
|
69354
|
-
import { join as
|
|
70685
|
+
import { join as join18 } from "node:path";
|
|
69355
70686
|
function resolveLogsDbPath(convexUrl) {
|
|
69356
|
-
return
|
|
70687
|
+
return join18(homedir7(), ".chatroom", resolveEnvSlug(convexUrl ?? getConvexUrl()), "logs.sqlite");
|
|
69357
70688
|
}
|
|
69358
70689
|
var init_resolve_logs_db_path = __esm(() => {
|
|
69359
70690
|
init_client2();
|
|
@@ -69387,10 +70718,10 @@ var init_log_schema = __esm(() => {
|
|
|
69387
70718
|
|
|
69388
70719
|
// src/infrastructure/log-server/open-log-database.ts
|
|
69389
70720
|
import { mkdirSync as mkdirSync5 } from "node:fs";
|
|
69390
|
-
import { dirname as
|
|
70721
|
+
import { dirname as dirname15 } from "node:path";
|
|
69391
70722
|
import { DatabaseSync as DatabaseSync2 } from "node:sqlite";
|
|
69392
70723
|
function openLogDatabase(dbPath) {
|
|
69393
|
-
mkdirSync5(
|
|
70724
|
+
mkdirSync5(dirname15(dbPath), { recursive: true });
|
|
69394
70725
|
const db = new DatabaseSync2(dbPath);
|
|
69395
70726
|
db.exec("PRAGMA journal_mode = WAL");
|
|
69396
70727
|
db.exec("PRAGMA busy_timeout = 5000");
|
|
@@ -69499,9 +70830,9 @@ function parsePsPidCommandLines(stdout) {
|
|
|
69499
70830
|
function readPpid(pid) {
|
|
69500
70831
|
if (process.platform === "linux") {
|
|
69501
70832
|
try {
|
|
69502
|
-
const
|
|
69503
|
-
const closeParen =
|
|
69504
|
-
const rest = closeParen >= 0 ?
|
|
70833
|
+
const stat7 = readFileSync10(`/proc/${pid}/stat`, "utf-8");
|
|
70834
|
+
const closeParen = stat7.lastIndexOf(")");
|
|
70835
|
+
const rest = closeParen >= 0 ? stat7.slice(closeParen + 2).split(" ") : stat7.split(" ");
|
|
69505
70836
|
const ppid = Number.parseInt(rest[1] ?? "", 10);
|
|
69506
70837
|
return Number.isFinite(ppid) && ppid >= 0 ? ppid : null;
|
|
69507
70838
|
} catch {
|
|
@@ -69582,7 +70913,7 @@ var init_daemon_process_scan = __esm(() => {
|
|
|
69582
70913
|
import { createHash as createHash5 } from "node:crypto";
|
|
69583
70914
|
import { existsSync as existsSync8, readFileSync as readFileSync11, writeFileSync as writeFileSync3, unlinkSync as unlinkSync2, mkdirSync as mkdirSync6 } from "node:fs";
|
|
69584
70915
|
import { homedir as homedir8 } from "node:os";
|
|
69585
|
-
import { join as
|
|
70916
|
+
import { join as join19 } from "node:path";
|
|
69586
70917
|
function getUrlHash2() {
|
|
69587
70918
|
const url3 = getConvexUrl();
|
|
69588
70919
|
return createHash5("sha256").update(url3).digest("hex").substring(0, 8);
|
|
@@ -69596,7 +70927,7 @@ function ensureChatroomDir2() {
|
|
|
69596
70927
|
}
|
|
69597
70928
|
}
|
|
69598
70929
|
function getPidFilePath() {
|
|
69599
|
-
return
|
|
70930
|
+
return join19(CHATROOM_DIR3, getPidFileName());
|
|
69600
70931
|
}
|
|
69601
70932
|
function isProcessRunning(pid) {
|
|
69602
70933
|
try {
|
|
@@ -69742,7 +71073,7 @@ var CHATROOM_DIR3, LOCK_RETRY_INTERVAL_MS = 500, LOCK_RETRY_MAX_WAIT_MS = 15000,
|
|
|
69742
71073
|
var init_pid = __esm(() => {
|
|
69743
71074
|
init_daemon_process_scan();
|
|
69744
71075
|
init_client2();
|
|
69745
|
-
CHATROOM_DIR3 =
|
|
71076
|
+
CHATROOM_DIR3 = join19(homedir8(), ".chatroom");
|
|
69746
71077
|
});
|
|
69747
71078
|
|
|
69748
71079
|
// src/commands/diagnostics/index.ts
|
|
@@ -69751,7 +71082,7 @@ __export(exports_diagnostics, {
|
|
|
69751
71082
|
logs: () => logs,
|
|
69752
71083
|
debugDaemon: () => debugDaemon
|
|
69753
71084
|
});
|
|
69754
|
-
import { stat as
|
|
71085
|
+
import { stat as stat7, writeFile as writeFile6 } from "node:fs/promises";
|
|
69755
71086
|
function parseDuration(value2) {
|
|
69756
71087
|
const match5 = /^(\d+(?:\.\d+)?)(ms|s|m|h|d)$/.exec(value2.trim().toLowerCase());
|
|
69757
71088
|
if (!match5)
|
|
@@ -69770,7 +71101,7 @@ function parseTimestamp(value2, flag) {
|
|
|
69770
71101
|
async function writeOrPrint(value2, output) {
|
|
69771
71102
|
const rendered = JSON.stringify(value2, null, 2);
|
|
69772
71103
|
if (output) {
|
|
69773
|
-
await
|
|
71104
|
+
await writeFile6(output, `${rendered}
|
|
69774
71105
|
`, "utf8");
|
|
69775
71106
|
console.log(`Wrote diagnostic dump to ${output}`);
|
|
69776
71107
|
return;
|
|
@@ -69813,7 +71144,7 @@ async function debugDaemon(options) {
|
|
|
69813
71144
|
async function readAllLogs(options, fromTimestamp, toTimestamp) {
|
|
69814
71145
|
const dbPath = resolveLogsDbPath();
|
|
69815
71146
|
try {
|
|
69816
|
-
await
|
|
71147
|
+
await stat7(dbPath);
|
|
69817
71148
|
} catch {
|
|
69818
71149
|
return { dbPath, entries: [] };
|
|
69819
71150
|
}
|
|
@@ -69869,7 +71200,7 @@ async function logs(options) {
|
|
|
69869
71200
|
return;
|
|
69870
71201
|
}
|
|
69871
71202
|
if (options.output) {
|
|
69872
|
-
await
|
|
71203
|
+
await writeFile6(options.output, result3.entries.map((entry) => `${new Date(entry.timestamp).toISOString()} [${entry.level}] ${entry.source} ${entry.message}`).join(`
|
|
69873
71204
|
`) + (result3.entries.length ? `
|
|
69874
71205
|
` : ""), "utf8");
|
|
69875
71206
|
console.log(`Wrote ${result3.entries.length} log entries to ${options.output}`);
|
|
@@ -70088,9 +71419,9 @@ var init_init = __esm(() => {
|
|
|
70088
71419
|
});
|
|
70089
71420
|
|
|
70090
71421
|
// src/tools/output.ts
|
|
70091
|
-
import { join as
|
|
71422
|
+
import { join as join20 } from "node:path";
|
|
70092
71423
|
function resolveChatroomDir(workingDir) {
|
|
70093
|
-
return
|
|
71424
|
+
return join20(workingDir, CHATROOM_DIR4);
|
|
70094
71425
|
}
|
|
70095
71426
|
async function ensureChatroomDir3(deps, workingDir) {
|
|
70096
71427
|
const dir = resolveChatroomDir(workingDir);
|
|
@@ -70098,7 +71429,7 @@ async function ensureChatroomDir3(deps, workingDir) {
|
|
|
70098
71429
|
return dir;
|
|
70099
71430
|
}
|
|
70100
71431
|
async function ensureGitignore(deps, workingDir) {
|
|
70101
|
-
const gitignorePath =
|
|
71432
|
+
const gitignorePath = join20(workingDir, ".gitignore");
|
|
70102
71433
|
const entry = CHATROOM_DIR4;
|
|
70103
71434
|
let content = "";
|
|
70104
71435
|
try {
|
|
@@ -70128,7 +71459,7 @@ function formatOutputTimestamp(date5 = new Date) {
|
|
|
70128
71459
|
function generateOutputPath(workingDir, toolName, extension2, date5) {
|
|
70129
71460
|
const timestamp = formatOutputTimestamp(date5);
|
|
70130
71461
|
const filename = `${toolName}-${timestamp}.${extension2}`;
|
|
70131
|
-
return
|
|
71462
|
+
return join20(resolveChatroomDir(workingDir), filename);
|
|
70132
71463
|
}
|
|
70133
71464
|
var CHATROOM_DIR4 = ".chatroom";
|
|
70134
71465
|
var init_output = () => {};
|
|
@@ -70138,7 +71469,7 @@ var exports_parse_pdf = {};
|
|
|
70138
71469
|
__export(exports_parse_pdf, {
|
|
70139
71470
|
parsePdf: () => parsePdf
|
|
70140
71471
|
});
|
|
70141
|
-
import { access, readFile as
|
|
71472
|
+
import { access, readFile as readFile10, writeFile as writeFile7, mkdir as mkdir7, appendFile } from "node:fs/promises";
|
|
70142
71473
|
import { resolve as resolve7 } from "node:path";
|
|
70143
71474
|
function isUrl(input) {
|
|
70144
71475
|
return input.startsWith("http://") || input.startsWith("https://");
|
|
@@ -70148,10 +71479,10 @@ function createDefaultDeps6() {
|
|
|
70148
71479
|
fs: {
|
|
70149
71480
|
access: (p) => access(p),
|
|
70150
71481
|
mkdir: (p, opts) => mkdir7(p, opts).then(() => {}),
|
|
70151
|
-
readFile: (p, enc) =>
|
|
71482
|
+
readFile: (p, enc) => readFile10(p, { encoding: enc }).then((b) => b.toString()),
|
|
70152
71483
|
appendFile: (p, content) => appendFile(p, content),
|
|
70153
|
-
readFileAsBuffer: (p) =>
|
|
70154
|
-
writeFile: (p, content, enc) =>
|
|
71484
|
+
readFileAsBuffer: (p) => readFile10(p),
|
|
71485
|
+
writeFile: (p, content, enc) => writeFile7(p, content, enc)
|
|
70155
71486
|
},
|
|
70156
71487
|
parser: {
|
|
70157
71488
|
parse: async (input) => {
|
|
@@ -82903,9 +84234,9 @@ var init_parse_skill_file = __esm(() => {
|
|
|
82903
84234
|
});
|
|
82904
84235
|
|
|
82905
84236
|
// src/infrastructure/external-skills/discover-external-skills.ts
|
|
82906
|
-
import { lstat as lstat2, readdir as readdir2, readFile as
|
|
84237
|
+
import { lstat as lstat2, readdir as readdir2, readFile as readFile12, realpath, stat as stat8 } from "node:fs/promises";
|
|
82907
84238
|
import os from "node:os";
|
|
82908
|
-
import { join as
|
|
84239
|
+
import { join as join22 } from "node:path";
|
|
82909
84240
|
function errorCode(err2) {
|
|
82910
84241
|
return err2?.code ?? "unknown";
|
|
82911
84242
|
}
|
|
@@ -82914,7 +84245,7 @@ function issue2(path2, reason, detail) {
|
|
|
82914
84245
|
}
|
|
82915
84246
|
function getExternalSkillRoots(homeDir) {
|
|
82916
84247
|
return EXTERNAL_SKILL_ROOT_SUFFIXES.map((suffix) => ({
|
|
82917
|
-
path:
|
|
84248
|
+
path: join22(homeDir, ...suffix.split("/"))
|
|
82918
84249
|
}));
|
|
82919
84250
|
}
|
|
82920
84251
|
async function discoverExternalSkills(options) {
|
|
@@ -82936,7 +84267,7 @@ async function scanRoot(rootPath, cap, state) {
|
|
|
82936
84267
|
state.issues.push(issue2(rootPath, "root-truncated", String(candidates.length)));
|
|
82937
84268
|
}
|
|
82938
84269
|
for (const entry of candidates.slice(0, cap)) {
|
|
82939
|
-
const sourcePath =
|
|
84270
|
+
const sourcePath = join22(rootPath, entry);
|
|
82940
84271
|
try {
|
|
82941
84272
|
await scanEntry(entry, sourcePath, state);
|
|
82942
84273
|
} catch (err2) {
|
|
@@ -82978,15 +84309,15 @@ async function scanEntry(entry, sourcePath, state) {
|
|
|
82978
84309
|
}
|
|
82979
84310
|
async function isSkillCandidate(sourcePath, issues) {
|
|
82980
84311
|
try {
|
|
82981
|
-
if (!(await
|
|
84312
|
+
if (!(await stat8(sourcePath)).isDirectory())
|
|
82982
84313
|
return false;
|
|
82983
84314
|
} catch (err2) {
|
|
82984
84315
|
issues.push(issue2(sourcePath, "unreadable", errorCode(err2)));
|
|
82985
84316
|
return false;
|
|
82986
84317
|
}
|
|
82987
|
-
const skillPath =
|
|
84318
|
+
const skillPath = join22(sourcePath, SKILL_FILE_NAME);
|
|
82988
84319
|
try {
|
|
82989
|
-
const skillStat = await
|
|
84320
|
+
const skillStat = await stat8(skillPath);
|
|
82990
84321
|
if (!skillStat.isFile())
|
|
82991
84322
|
return false;
|
|
82992
84323
|
if (skillStat.size > MAX_SKILL_FILE_BYTES) {
|
|
@@ -83011,7 +84342,7 @@ async function isSymlink2(path2) {
|
|
|
83011
84342
|
}
|
|
83012
84343
|
async function readSkillFile(sourcePath, issues) {
|
|
83013
84344
|
try {
|
|
83014
|
-
return await
|
|
84345
|
+
return await readFile12(join22(sourcePath, SKILL_FILE_NAME), "utf8");
|
|
83015
84346
|
} catch (err2) {
|
|
83016
84347
|
issues.push(issue2(sourcePath, "unreadable", errorCode(err2)));
|
|
83017
84348
|
return;
|
|
@@ -84871,10 +86202,10 @@ var init_durable_fifo_queue_schema = __esm(() => {
|
|
|
84871
86202
|
|
|
84872
86203
|
// src/daemon/infrastructure/outbox/lib/durable-fifo-queue-store.ts
|
|
84873
86204
|
import { mkdirSync as mkdirSync7 } from "node:fs";
|
|
84874
|
-
import { dirname as
|
|
86205
|
+
import { dirname as dirname16 } from "node:path";
|
|
84875
86206
|
import { DatabaseSync as DatabaseSync3 } from "node:sqlite";
|
|
84876
86207
|
function openDurableFifoQueueStore(dbPath) {
|
|
84877
|
-
mkdirSync7(
|
|
86208
|
+
mkdirSync7(dirname16(dbPath), { recursive: true });
|
|
84878
86209
|
const db = new DatabaseSync3(dbPath);
|
|
84879
86210
|
for (const sql of DURABLE_FIFO_QUEUE_MIGRATIONS)
|
|
84880
86211
|
db.exec(sql);
|
|
@@ -85169,9 +86500,9 @@ var init_keyed_fifo_batched_outbox_registry = __esm(() => {
|
|
|
85169
86500
|
|
|
85170
86501
|
// src/daemon/infrastructure/outbox/outbox-db-path.ts
|
|
85171
86502
|
import { homedir as homedir9 } from "node:os";
|
|
85172
|
-
import { join as
|
|
86503
|
+
import { join as join24 } from "node:path";
|
|
85173
86504
|
function resolveOutboxDbPath(machineId, kind) {
|
|
85174
|
-
return
|
|
86505
|
+
return join24(homedir9(), ".chatroom", "daemon", machineId, `outbox-${kind}.sqlite`);
|
|
85175
86506
|
}
|
|
85176
86507
|
var init_outbox_db_path = () => {};
|
|
85177
86508
|
|
|
@@ -85502,9 +86833,9 @@ var init_orphan_tracker = __esm(() => {
|
|
|
85502
86833
|
});
|
|
85503
86834
|
|
|
85504
86835
|
// src/daemon/entry/handlers/process/output-store.ts
|
|
85505
|
-
import { appendFile as appendFile2, mkdir as mkdir10, readFile as
|
|
86836
|
+
import { appendFile as appendFile2, mkdir as mkdir10, readFile as readFile13, rm as rm3 } from "node:fs/promises";
|
|
85506
86837
|
import { tmpdir } from "node:os";
|
|
85507
|
-
import { join as
|
|
86838
|
+
import { join as join25 } from "node:path";
|
|
85508
86839
|
|
|
85509
86840
|
class TempFileOutputStore {
|
|
85510
86841
|
state;
|
|
@@ -85535,7 +86866,7 @@ class TempFileOutputStore {
|
|
|
85535
86866
|
async getLastNLines(maxLines) {
|
|
85536
86867
|
let source;
|
|
85537
86868
|
try {
|
|
85538
|
-
source = await
|
|
86869
|
+
source = await readFile13(this.state.filePath, "utf-8");
|
|
85539
86870
|
} catch {
|
|
85540
86871
|
source = this.state.inMemory;
|
|
85541
86872
|
}
|
|
@@ -85552,7 +86883,7 @@ class TempFileOutputStore {
|
|
|
85552
86883
|
}
|
|
85553
86884
|
async getFullOutput() {
|
|
85554
86885
|
try {
|
|
85555
|
-
return await
|
|
86886
|
+
return await readFile13(this.state.filePath, "utf-8");
|
|
85556
86887
|
} catch {
|
|
85557
86888
|
return this.state.inMemory;
|
|
85558
86889
|
}
|
|
@@ -85567,7 +86898,7 @@ function createOutputStore(runId) {
|
|
|
85567
86898
|
if (!RUN_ID_RE.test(runId)) {
|
|
85568
86899
|
throw new Error(`Invalid runId: ${runId}`);
|
|
85569
86900
|
}
|
|
85570
|
-
const filePath =
|
|
86901
|
+
const filePath = join25(TEMP_DIR, `${runId}.log`);
|
|
85571
86902
|
return new TempFileOutputStore(filePath);
|
|
85572
86903
|
}
|
|
85573
86904
|
async function ensureTempDir() {
|
|
@@ -85581,15 +86912,15 @@ async function cleanOrphanTempFiles() {
|
|
|
85581
86912
|
var TAIL_WINDOW_BYTES, TEMP_DIR, RUN_ID_RE, MAX_TAIL_LINES_V2 = 50;
|
|
85582
86913
|
var init_output_store = __esm(() => {
|
|
85583
86914
|
TAIL_WINDOW_BYTES = 32 * 1024;
|
|
85584
|
-
TEMP_DIR =
|
|
86915
|
+
TEMP_DIR = join25(tmpdir(), "chatroom-cli", "runs");
|
|
85585
86916
|
RUN_ID_RE = /^[a-z0-9]+$/i;
|
|
85586
86917
|
});
|
|
85587
86918
|
|
|
85588
86919
|
// src/daemon/entry/task-handoff-repository-path.ts
|
|
85589
86920
|
import { homedir as homedir10 } from "node:os";
|
|
85590
|
-
import { join as
|
|
86921
|
+
import { join as join26 } from "node:path";
|
|
85591
86922
|
function resolveTaskHandoffRepositoryPath(machineId) {
|
|
85592
|
-
return
|
|
86923
|
+
return join26(homedir10(), ".chatroom", "daemon", machineId, "task-handoffs.sqlite");
|
|
85593
86924
|
}
|
|
85594
86925
|
var init_task_handoff_repository_path = () => {};
|
|
85595
86926
|
|
|
@@ -85705,10 +87036,10 @@ var init_durable_coalescing_state_schema = __esm(() => {
|
|
|
85705
87036
|
|
|
85706
87037
|
// src/daemon/infrastructure/outbox/lib/durable-coalescing-state-store.ts
|
|
85707
87038
|
import { mkdirSync as mkdirSync8 } from "node:fs";
|
|
85708
|
-
import { dirname as
|
|
87039
|
+
import { dirname as dirname17 } from "node:path";
|
|
85709
87040
|
import { DatabaseSync as DatabaseSync4 } from "node:sqlite";
|
|
85710
87041
|
function openDurableCoalescingStateStore(path2) {
|
|
85711
|
-
mkdirSync8(
|
|
87042
|
+
mkdirSync8(dirname17(path2), { recursive: true });
|
|
85712
87043
|
const db = new DatabaseSync4(path2);
|
|
85713
87044
|
for (const sql of DURABLE_COALESCING_STATE_MIGRATIONS)
|
|
85714
87045
|
db.exec(sql);
|
|
@@ -87182,7 +88513,7 @@ var init_workspace_visibility_policy = __esm(() => {
|
|
|
87182
88513
|
|
|
87183
88514
|
// src/infrastructure/services/workspace/workspace-ignore.ts
|
|
87184
88515
|
import { promises as fsPromises } from "node:fs";
|
|
87185
|
-
import { readFile as
|
|
88516
|
+
import { readFile as readFile14 } from "node:fs/promises";
|
|
87186
88517
|
import { homedir as homedir11 } from "node:os";
|
|
87187
88518
|
import path2 from "node:path";
|
|
87188
88519
|
function normalizeRelativePath(relativePath) {
|
|
@@ -87247,7 +88578,7 @@ async function loadGitExtraExcludeRuleSets(rootDir) {
|
|
|
87247
88578
|
}
|
|
87248
88579
|
async function readIgnoreFile(filePath) {
|
|
87249
88580
|
try {
|
|
87250
|
-
return await
|
|
88581
|
+
return await readFile14(filePath, "utf-8");
|
|
87251
88582
|
} catch {
|
|
87252
88583
|
return null;
|
|
87253
88584
|
}
|
|
@@ -88219,7 +89550,7 @@ var init_git_workspace_hierarchy = __esm(() => {
|
|
|
88219
89550
|
});
|
|
88220
89551
|
|
|
88221
89552
|
// ../../node_modules/.pnpm/readdirp@5.1.1/node_modules/readdirp/index.js
|
|
88222
|
-
import { lstat as lstat3, readdir as readdir3, realpath as realpath2, stat as
|
|
89553
|
+
import { lstat as lstat3, readdir as readdir3, realpath as realpath2, stat as stat9 } from "node:fs/promises";
|
|
88223
89554
|
import { join as pjoin, resolve as presolve, sep as psep } from "node:path";
|
|
88224
89555
|
import { Readable } from "node:stream";
|
|
88225
89556
|
function readdirp(root, options = {}) {
|
|
@@ -88316,7 +89647,7 @@ var init_readdirp = __esm(() => {
|
|
|
88316
89647
|
const type = opts.type ?? defaultOptions.type;
|
|
88317
89648
|
this._fileFilter = normalizeFilter(opts.fileFilter);
|
|
88318
89649
|
this._directoryFilter = normalizeFilter(opts.directoryFilter);
|
|
88319
|
-
const statMethod = opts.lstat ? lstat3 :
|
|
89650
|
+
const statMethod = opts.lstat ? lstat3 : stat9;
|
|
88320
89651
|
if (wantBigintFsStats) {
|
|
88321
89652
|
this._stat = (path5) => statMethod(path5, { bigint: true });
|
|
88322
89653
|
} else {
|
|
@@ -88404,9 +89735,9 @@ var init_readdirp = __esm(() => {
|
|
|
88404
89735
|
return { files, depth, path: path5 };
|
|
88405
89736
|
}
|
|
88406
89737
|
_formatEntry(dirent, path5) {
|
|
88407
|
-
const
|
|
88408
|
-
const fullPath = pjoin(path5,
|
|
88409
|
-
const entry = { path: fullPath.slice(this._relStart), fullPath, basename:
|
|
89738
|
+
const basename7 = this._isDirent ? dirent.name : dirent;
|
|
89739
|
+
const fullPath = pjoin(path5, basename7);
|
|
89740
|
+
const entry = { path: fullPath.slice(this._relStart), fullPath, basename: basename7 };
|
|
88410
89741
|
if (this._isDirent) {
|
|
88411
89742
|
entry.dirent = dirent;
|
|
88412
89743
|
return entry;
|
|
@@ -88471,7 +89802,7 @@ var init_readdirp = __esm(() => {
|
|
|
88471
89802
|
|
|
88472
89803
|
// ../../node_modules/.pnpm/chokidar@5.0.0/node_modules/chokidar/handler.js
|
|
88473
89804
|
import { watch as fs_watch, unwatchFile, watchFile } from "node:fs";
|
|
88474
|
-
import { realpath as fsrealpath, lstat as lstat4, open, stat as
|
|
89805
|
+
import { realpath as fsrealpath, lstat as lstat4, open, stat as stat10 } from "node:fs/promises";
|
|
88475
89806
|
import { type as osType } from "node:os";
|
|
88476
89807
|
import * as sp from "node:path";
|
|
88477
89808
|
function createFsWatchInstance(path5, options, listener, errHandler, emitRaw) {
|
|
@@ -88502,9 +89833,9 @@ class NodeFsHandler {
|
|
|
88502
89833
|
_watchWithNodeFs(path5, listener) {
|
|
88503
89834
|
const opts = this.fsw.options;
|
|
88504
89835
|
const directory = sp.dirname(path5);
|
|
88505
|
-
const
|
|
89836
|
+
const basename8 = sp.basename(path5);
|
|
88506
89837
|
const parent = this.fsw._getWatchedDir(directory);
|
|
88507
|
-
parent.add(
|
|
89838
|
+
parent.add(basename8);
|
|
88508
89839
|
const absolutePath = sp.resolve(path5);
|
|
88509
89840
|
const options = {
|
|
88510
89841
|
persistent: opts.persistent
|
|
@@ -88514,7 +89845,7 @@ class NodeFsHandler {
|
|
|
88514
89845
|
let closer;
|
|
88515
89846
|
if (opts.usePolling) {
|
|
88516
89847
|
const enableBin = opts.interval !== opts.binaryInterval;
|
|
88517
|
-
options.interval = enableBin && isBinaryPath(
|
|
89848
|
+
options.interval = enableBin && isBinaryPath(basename8) ? opts.binaryInterval : opts.interval;
|
|
88518
89849
|
closer = setFsWatchFileListener(path5, absolutePath, options, {
|
|
88519
89850
|
listener,
|
|
88520
89851
|
rawEmitter: this.fsw._emitRaw
|
|
@@ -88532,18 +89863,18 @@ class NodeFsHandler {
|
|
|
88532
89863
|
if (this.fsw.closed) {
|
|
88533
89864
|
return;
|
|
88534
89865
|
}
|
|
88535
|
-
const
|
|
88536
|
-
const
|
|
88537
|
-
const parent = this.fsw._getWatchedDir(
|
|
89866
|
+
const dirname19 = sp.dirname(file2);
|
|
89867
|
+
const basename8 = sp.basename(file2);
|
|
89868
|
+
const parent = this.fsw._getWatchedDir(dirname19);
|
|
88538
89869
|
let prevStats = stats;
|
|
88539
|
-
if (parent.has(
|
|
89870
|
+
if (parent.has(basename8))
|
|
88540
89871
|
return;
|
|
88541
89872
|
const listener = async (path5, newStats) => {
|
|
88542
89873
|
if (!this.fsw._throttle(THROTTLE_MODE_WATCH, file2, 5))
|
|
88543
89874
|
return;
|
|
88544
89875
|
if (!newStats || newStats.mtimeMs === 0) {
|
|
88545
89876
|
try {
|
|
88546
|
-
const newStats2 = await
|
|
89877
|
+
const newStats2 = await stat10(file2);
|
|
88547
89878
|
if (this.fsw.closed)
|
|
88548
89879
|
return;
|
|
88549
89880
|
const at = newStats2.atimeMs;
|
|
@@ -88561,9 +89892,9 @@ class NodeFsHandler {
|
|
|
88561
89892
|
prevStats = newStats2;
|
|
88562
89893
|
}
|
|
88563
89894
|
} catch (error51) {
|
|
88564
|
-
this.fsw._remove(
|
|
89895
|
+
this.fsw._remove(dirname19, basename8);
|
|
88565
89896
|
}
|
|
88566
|
-
} else if (parent.has(
|
|
89897
|
+
} else if (parent.has(basename8)) {
|
|
88567
89898
|
const at = newStats.atimeMs;
|
|
88568
89899
|
const mt = newStats.mtimeMs;
|
|
88569
89900
|
if (!at || at <= mt || mt !== prevStats.mtimeMs) {
|
|
@@ -88899,7 +90230,7 @@ var init_handler = __esm(() => {
|
|
|
88899
90230
|
ERROR: "error"
|
|
88900
90231
|
};
|
|
88901
90232
|
EV = EVENTS;
|
|
88902
|
-
statMethods = { lstat: lstat4, stat:
|
|
90233
|
+
statMethods = { lstat: lstat4, stat: stat10 };
|
|
88903
90234
|
HANDLER_KEYS = [KEY_LISTENERS, KEY_ERR, KEY_RAW];
|
|
88904
90235
|
binaryExtensions = new Set([
|
|
88905
90236
|
"3dm",
|
|
@@ -89171,7 +90502,7 @@ var init_handler = __esm(() => {
|
|
|
89171
90502
|
// ../../node_modules/.pnpm/chokidar@5.0.0/node_modules/chokidar/index.js
|
|
89172
90503
|
import { EventEmitter } from "node:events";
|
|
89173
90504
|
import { stat as statcb, Stats } from "node:fs";
|
|
89174
|
-
import { readdir as readdir4, stat as
|
|
90505
|
+
import { readdir as readdir4, stat as stat11 } from "node:fs/promises";
|
|
89175
90506
|
import * as sp2 from "node:path";
|
|
89176
90507
|
function arrify(item) {
|
|
89177
90508
|
return Array.isArray(item) ? item : [item];
|
|
@@ -89625,7 +90956,7 @@ var init_chokidar = __esm(() => {
|
|
|
89625
90956
|
const fullPath = opts.cwd ? sp2.join(opts.cwd, path5) : path5;
|
|
89626
90957
|
let stats2;
|
|
89627
90958
|
try {
|
|
89628
|
-
stats2 = await
|
|
90959
|
+
stats2 = await stat11(fullPath);
|
|
89629
90960
|
} catch (err2) {}
|
|
89630
90961
|
if (!stats2 || this.closed)
|
|
89631
90962
|
return;
|
|
@@ -89729,8 +91060,8 @@ var init_chokidar = __esm(() => {
|
|
|
89729
91060
|
}
|
|
89730
91061
|
return this._userIgnored(path5, stats);
|
|
89731
91062
|
}
|
|
89732
|
-
_isntIgnored(path5,
|
|
89733
|
-
return !this._isIgnored(path5,
|
|
91063
|
+
_isntIgnored(path5, stat12) {
|
|
91064
|
+
return !this._isIgnored(path5, stat12);
|
|
89734
91065
|
}
|
|
89735
91066
|
_getWatchHelpers(path5) {
|
|
89736
91067
|
return new WatchHelper(path5, this.options.followSymlinks, this);
|
|
@@ -89951,7 +91282,7 @@ function diffPathIndexes(previous, next2) {
|
|
|
89951
91282
|
import { createHash as createHash8, randomUUID as randomUUID8 } from "node:crypto";
|
|
89952
91283
|
import * as fs6 from "node:fs/promises";
|
|
89953
91284
|
import { homedir as homedir12 } from "node:os";
|
|
89954
|
-
import { join as
|
|
91285
|
+
import { join as join29 } from "node:path";
|
|
89955
91286
|
function workspaceKeyFor(workingDir) {
|
|
89956
91287
|
const normalized = normalizeWorkingDirForLookup(workingDir);
|
|
89957
91288
|
return createHash8("sha256").update(normalized).digest("hex").slice(0, 16);
|
|
@@ -89965,10 +91296,10 @@ function buildPathIndex(entries) {
|
|
|
89965
91296
|
}
|
|
89966
91297
|
function manifestPath(machineId, workingDir) {
|
|
89967
91298
|
const key = workspaceKeyFor(workingDir);
|
|
89968
|
-
return
|
|
91299
|
+
return join29(SYNC_STATE_DIR, machineId, key, "manifest.json");
|
|
89969
91300
|
}
|
|
89970
91301
|
async function ensureDir2(filePath) {
|
|
89971
|
-
await fs6.mkdir(
|
|
91302
|
+
await fs6.mkdir(join29(filePath, ".."), { recursive: true, mode: 448 });
|
|
89972
91303
|
}
|
|
89973
91304
|
async function loadWorkspaceSyncManifest(machineId, workingDir) {
|
|
89974
91305
|
try {
|
|
@@ -90028,7 +91359,7 @@ function entriesFromPathIndex(paths) {
|
|
|
90028
91359
|
}
|
|
90029
91360
|
var SYNC_STATE_VERSION = "2", SYNC_STATE_DIR;
|
|
90030
91361
|
var init_workspace_sync_state = __esm(() => {
|
|
90031
|
-
SYNC_STATE_DIR =
|
|
91362
|
+
SYNC_STATE_DIR = join29(homedir12(), ".chatroom", "sync-state");
|
|
90032
91363
|
});
|
|
90033
91364
|
|
|
90034
91365
|
// src/infrastructure/services/workspace/workspace-file-tree-coordinator.ts
|
|
@@ -91842,17 +93173,17 @@ function parseMakefileTargets(content) {
|
|
|
91842
93173
|
var MAX_NAME_LENGTH2 = 256;
|
|
91843
93174
|
|
|
91844
93175
|
// src/infrastructure/services/workspace/workspace-resolver.ts
|
|
91845
|
-
import { readFile as
|
|
91846
|
-
import { join as
|
|
93176
|
+
import { readFile as readFile16, readdir as readdir5, stat as stat12 } from "node:fs/promises";
|
|
93177
|
+
import { join as join30, basename as basename9, resolve as resolve11 } from "node:path";
|
|
91847
93178
|
async function resolveGlobPatternStar(rootDir, cleaned) {
|
|
91848
|
-
const parentDir2 =
|
|
93179
|
+
const parentDir2 = join30(rootDir, cleaned.slice(0, -2));
|
|
91849
93180
|
try {
|
|
91850
93181
|
const entries = await readdir5(parentDir2, { withFileTypes: true });
|
|
91851
93182
|
const dirs = [];
|
|
91852
93183
|
for (const entry of entries) {
|
|
91853
93184
|
if (!entry.isDirectory())
|
|
91854
93185
|
continue;
|
|
91855
|
-
const dirPath =
|
|
93186
|
+
const dirPath = join30(parentDir2, entry.name);
|
|
91856
93187
|
if (resolve11(dirPath).startsWith(resolve11(rootDir))) {
|
|
91857
93188
|
dirs.push(dirPath);
|
|
91858
93189
|
}
|
|
@@ -91863,11 +93194,11 @@ async function resolveGlobPatternStar(rootDir, cleaned) {
|
|
|
91863
93194
|
}
|
|
91864
93195
|
}
|
|
91865
93196
|
async function resolveLiteralPath(rootDir, cleaned) {
|
|
91866
|
-
const dir =
|
|
93197
|
+
const dir = join30(rootDir, cleaned);
|
|
91867
93198
|
try {
|
|
91868
93199
|
if (!resolve11(dir).startsWith(resolve11(rootDir)))
|
|
91869
93200
|
return [];
|
|
91870
|
-
const s = await
|
|
93201
|
+
const s = await stat12(dir);
|
|
91871
93202
|
if (s.isDirectory())
|
|
91872
93203
|
return [dir];
|
|
91873
93204
|
} catch {}
|
|
@@ -91883,10 +93214,10 @@ async function resolveGlobPattern(rootDir, pattern) {
|
|
|
91883
93214
|
}
|
|
91884
93215
|
async function readPackageJson(dir) {
|
|
91885
93216
|
try {
|
|
91886
|
-
const content = await
|
|
93217
|
+
const content = await readFile16(join30(dir, "package.json"), "utf-8");
|
|
91887
93218
|
const pkg = JSON.parse(content);
|
|
91888
93219
|
return {
|
|
91889
|
-
name: pkg.name ||
|
|
93220
|
+
name: pkg.name || basename9(dir),
|
|
91890
93221
|
scripts: pkg.scripts && typeof pkg.scripts === "object" ? pkg.scripts : {}
|
|
91891
93222
|
};
|
|
91892
93223
|
} catch {
|
|
@@ -91895,7 +93226,7 @@ async function readPackageJson(dir) {
|
|
|
91895
93226
|
}
|
|
91896
93227
|
async function readPnpmWorkspacePatterns(rootDir) {
|
|
91897
93228
|
try {
|
|
91898
|
-
const content = await
|
|
93229
|
+
const content = await readFile16(join30(rootDir, "pnpm-workspace.yaml"), "utf-8");
|
|
91899
93230
|
const patterns = [];
|
|
91900
93231
|
let inPackages = false;
|
|
91901
93232
|
for (const line of content.split(`
|
|
@@ -91922,7 +93253,7 @@ async function readPnpmWorkspacePatterns(rootDir) {
|
|
|
91922
93253
|
}
|
|
91923
93254
|
async function readPackageJsonWorkspacePatterns(rootDir) {
|
|
91924
93255
|
try {
|
|
91925
|
-
const content = await
|
|
93256
|
+
const content = await readFile16(join30(rootDir, "package.json"), "utf-8");
|
|
91926
93257
|
const pkg = JSON.parse(content);
|
|
91927
93258
|
if (!pkg.workspaces)
|
|
91928
93259
|
return [];
|
|
@@ -91970,12 +93301,12 @@ async function resolveSubWorkspaces(rootDir, pm) {
|
|
|
91970
93301
|
var init_workspace_resolver = () => {};
|
|
91971
93302
|
|
|
91972
93303
|
// src/infrastructure/services/workspace/command-discovery.ts
|
|
91973
|
-
import { access as access2, readFile as
|
|
91974
|
-
import { join as
|
|
93304
|
+
import { access as access2, readFile as readFile17 } from "node:fs/promises";
|
|
93305
|
+
import { join as join31, relative as relative3, basename as basename10 } from "node:path";
|
|
91975
93306
|
async function detectPackageManager(workingDir) {
|
|
91976
93307
|
for (const { file: file2, manager } of LOCKFILE_MAP) {
|
|
91977
93308
|
try {
|
|
91978
|
-
await access2(
|
|
93309
|
+
await access2(join31(workingDir, file2));
|
|
91979
93310
|
return manager;
|
|
91980
93311
|
} catch {}
|
|
91981
93312
|
}
|
|
@@ -92019,7 +93350,7 @@ function isValidScriptEntry(name, script) {
|
|
|
92019
93350
|
}
|
|
92020
93351
|
async function readJsonFile(filePath, label) {
|
|
92021
93352
|
try {
|
|
92022
|
-
const content = await
|
|
93353
|
+
const content = await readFile17(filePath, "utf-8");
|
|
92023
93354
|
return parseJsonc2(content);
|
|
92024
93355
|
} catch (error51) {
|
|
92025
93356
|
if (error51.code !== "ENOENT") {
|
|
@@ -92043,8 +93374,8 @@ function collectRootScriptCommands(scripts, pm, scriptPrefix, rootSw) {
|
|
|
92043
93374
|
return commands;
|
|
92044
93375
|
}
|
|
92045
93376
|
async function readRootPackageJson(workingDir, pm, scriptPrefix) {
|
|
92046
|
-
let rootPackageName =
|
|
92047
|
-
const pkg = await readJsonFile(
|
|
93377
|
+
let rootPackageName = basename10(workingDir);
|
|
93378
|
+
const pkg = await readJsonFile(join31(workingDir, "package.json"), "root package.json");
|
|
92048
93379
|
if (!pkg)
|
|
92049
93380
|
return { commands: [], rootPackageName };
|
|
92050
93381
|
if (pkg.name)
|
|
@@ -92060,7 +93391,7 @@ async function readRootPackageJson(workingDir, pm, scriptPrefix) {
|
|
|
92060
93391
|
}
|
|
92061
93392
|
async function readTurboJson(workingDir, _turboPrefix, _rootSubWorkspace) {
|
|
92062
93393
|
const turboTaskNames = [];
|
|
92063
|
-
const turbo = await readJsonFile(
|
|
93394
|
+
const turbo = await readJsonFile(join31(workingDir, "turbo.json"), "turbo.json");
|
|
92064
93395
|
if (!turbo?.tasks || typeof turbo.tasks !== "object")
|
|
92065
93396
|
return turboTaskNames;
|
|
92066
93397
|
for (const taskName of Object.keys(turbo.tasks)) {
|
|
@@ -92073,10 +93404,10 @@ async function readTurboJson(workingDir, _turboPrefix, _rootSubWorkspace) {
|
|
|
92073
93404
|
async function readDenoJson(workingDir) {
|
|
92074
93405
|
const commands = [];
|
|
92075
93406
|
for (const fileName of ["deno.json", "deno.jsonc"]) {
|
|
92076
|
-
const deno = await readJsonFile(
|
|
93407
|
+
const deno = await readJsonFile(join31(workingDir, fileName), fileName);
|
|
92077
93408
|
if (!deno?.tasks || typeof deno.tasks !== "object")
|
|
92078
93409
|
continue;
|
|
92079
|
-
const pkgName = deno.name ??
|
|
93410
|
+
const pkgName = deno.name ?? basename10(workingDir);
|
|
92080
93411
|
const subWorkspace = { type: "deno", path: ".", name: pkgName };
|
|
92081
93412
|
for (const [taskName, taskCommand] of Object.entries(deno.tasks)) {
|
|
92082
93413
|
if (!isValidScriptEntry(taskName, taskCommand))
|
|
@@ -92096,14 +93427,14 @@ async function readMakefile(workingDir) {
|
|
|
92096
93427
|
const commands = [];
|
|
92097
93428
|
for (const fileName of ["Makefile", "makefile"]) {
|
|
92098
93429
|
try {
|
|
92099
|
-
const content = await
|
|
93430
|
+
const content = await readFile17(join31(workingDir, fileName), "utf-8");
|
|
92100
93431
|
const targets = parseMakefileTargets(content);
|
|
92101
93432
|
if (targets.length === 0)
|
|
92102
93433
|
continue;
|
|
92103
93434
|
const subWorkspace = {
|
|
92104
93435
|
type: "make",
|
|
92105
93436
|
path: ".",
|
|
92106
|
-
name:
|
|
93437
|
+
name: basename10(workingDir)
|
|
92107
93438
|
};
|
|
92108
93439
|
for (const target of targets) {
|
|
92109
93440
|
commands.push({
|
|
@@ -92234,8 +93565,8 @@ function createWorkspaceGitProbe(args2) {
|
|
|
92234
93565
|
}
|
|
92235
93566
|
async function statFingerprint(absPath) {
|
|
92236
93567
|
try {
|
|
92237
|
-
const
|
|
92238
|
-
return `${
|
|
93568
|
+
const stat13 = await fs7.stat(absPath);
|
|
93569
|
+
return `${stat13.mtimeMs}:${stat13.size}`;
|
|
92239
93570
|
} catch {
|
|
92240
93571
|
return "missing";
|
|
92241
93572
|
}
|
|
@@ -93261,12 +94592,12 @@ async function readCommandsUnits(workingDir) {
|
|
|
93261
94592
|
return [{ kind: "commands", commands: commands.map(toCommandEntry) }];
|
|
93262
94593
|
}
|
|
93263
94594
|
async function readWorktreeUnits(workingDir) {
|
|
93264
|
-
const [dirty,
|
|
94595
|
+
const [dirty, stat13] = await Promise.all([isDirty(workingDir), getDiffStat(workingDir)]);
|
|
93265
94596
|
return [
|
|
93266
94597
|
{
|
|
93267
94598
|
kind: "worktree",
|
|
93268
94599
|
isDirty: dirty,
|
|
93269
|
-
diffStat:
|
|
94600
|
+
diffStat: stat13.status === "available" ? { ...stat13.diffStat } : { filesChanged: 0, insertions: 0, deletions: 0 }
|
|
93270
94601
|
}
|
|
93271
94602
|
];
|
|
93272
94603
|
}
|
|
@@ -93643,7 +94974,7 @@ var init_workspace_service2 = __esm(() => {
|
|
|
93643
94974
|
});
|
|
93644
94975
|
|
|
93645
94976
|
// src/daemon/entry/init-daemon.ts
|
|
93646
|
-
import { stat as
|
|
94977
|
+
import { stat as stat13 } from "node:fs/promises";
|
|
93647
94978
|
async function discoverModelsForHarness(harness, service4) {
|
|
93648
94979
|
const installed2 = await service4.isInstalled();
|
|
93649
94980
|
if (!installed2) {
|
|
@@ -93678,7 +95009,7 @@ function createDefaultDeps22() {
|
|
|
93678
95009
|
kill: (pid, signal) => process.kill(pid, signal)
|
|
93679
95010
|
},
|
|
93680
95011
|
fs: {
|
|
93681
|
-
stat:
|
|
95012
|
+
stat: stat13
|
|
93682
95013
|
},
|
|
93683
95014
|
machine: {
|
|
93684
95015
|
clearAgentPid,
|
|
@@ -97518,7 +98849,7 @@ var init_git_clone = __esm(() => {
|
|
|
97518
98849
|
|
|
97519
98850
|
// src/infrastructure/local-actions/git-clone.ts
|
|
97520
98851
|
import { spawn as spawn5 } from "node:child_process";
|
|
97521
|
-
import { readdir as readdir6, stat as
|
|
98852
|
+
import { readdir as readdir6, stat as stat14 } from "node:fs/promises";
|
|
97522
98853
|
function parseGitCloneProgressLine(line) {
|
|
97523
98854
|
const match5 = PROGRESS_LINE_PATTERN.exec(line.trim());
|
|
97524
98855
|
if (!match5?.[1] || !match5[2])
|
|
@@ -97532,7 +98863,7 @@ function classifyGitCloneFailure(stderrTail, spawnErrorCode) {
|
|
|
97532
98863
|
}
|
|
97533
98864
|
async function statOrNull(path8) {
|
|
97534
98865
|
try {
|
|
97535
|
-
return await
|
|
98866
|
+
return await stat14(path8);
|
|
97536
98867
|
} catch (error51) {
|
|
97537
98868
|
if (error51.code === "ENOENT")
|
|
97538
98869
|
return null;
|
|
@@ -98111,7 +99442,7 @@ var init_assert_registered_working_dir = () => {};
|
|
|
98111
99442
|
|
|
98112
99443
|
// src/infrastructure/services/workspace/workspace-path-security.ts
|
|
98113
99444
|
import { realpath as realpath3 } from "node:fs/promises";
|
|
98114
|
-
import { dirname as
|
|
99445
|
+
import { dirname as dirname20, isAbsolute as isAbsolute2, relative as relative4, resolve as resolve12, sep } from "node:path";
|
|
98115
99446
|
import { gunzipSync } from "node:zlib";
|
|
98116
99447
|
function validateRelativePathSegments(filePath) {
|
|
98117
99448
|
if (filePath.includes("\x00"))
|
|
@@ -98139,7 +99470,7 @@ function assertContained(workspaceRoot, targetPath) {
|
|
|
98139
99470
|
return { ok: true };
|
|
98140
99471
|
}
|
|
98141
99472
|
async function resolveNonExistentTarget(workspaceRoot, candidate) {
|
|
98142
|
-
let current =
|
|
99473
|
+
let current = dirname20(candidate);
|
|
98143
99474
|
for (;; ) {
|
|
98144
99475
|
try {
|
|
98145
99476
|
const ancestorReal = await realpath3(current);
|
|
@@ -98157,7 +99488,7 @@ async function resolveNonExistentTarget(workspaceRoot, candidate) {
|
|
|
98157
99488
|
if (code2 !== "ENOENT") {
|
|
98158
99489
|
return { ok: false, error: "Invalid file path" };
|
|
98159
99490
|
}
|
|
98160
|
-
const parent =
|
|
99491
|
+
const parent = dirname20(current);
|
|
98161
99492
|
if (parent === current) {
|
|
98162
99493
|
return { ok: false, error: "Path escapes workspace" };
|
|
98163
99494
|
}
|
|
@@ -98216,7 +99547,7 @@ function gunzipBase64Payload(base643, maxBytes) {
|
|
|
98216
99547
|
var init_workspace_path_security = () => {};
|
|
98217
99548
|
|
|
98218
99549
|
// src/daemon/entry/files/file-content-fulfillment.ts
|
|
98219
|
-
import { readFile as
|
|
99550
|
+
import { readFile as readFile18 } from "node:fs/promises";
|
|
98220
99551
|
import { gzipSync as gzipSync3 } from "node:zlib";
|
|
98221
99552
|
function getErrorCause(error51) {
|
|
98222
99553
|
if (typeof error51 === "object" && error51 !== null && "cause" in error51 && error51.cause !== undefined) {
|
|
@@ -98291,7 +99622,7 @@ var init_file_content_fulfillment = __esm(() => {
|
|
|
98291
99622
|
continue;
|
|
98292
99623
|
}
|
|
98293
99624
|
let fileNotFound = false;
|
|
98294
|
-
const buffer = yield* exports_Effect.catch(exports_Effect.tryPromise(() =>
|
|
99625
|
+
const buffer = yield* exports_Effect.catch(exports_Effect.tryPromise(() => readFile18(absolutePath)), (error51) => {
|
|
98295
99626
|
if (isENOENT(error51)) {
|
|
98296
99627
|
fileNotFound = true;
|
|
98297
99628
|
return exports_Effect.succeed(Buffer.alloc(0));
|
|
@@ -98536,10 +99867,10 @@ function parseAttachmentFileName(remainder) {
|
|
|
98536
99867
|
if (underscore <= 0)
|
|
98537
99868
|
return false;
|
|
98538
99869
|
const uuid3 = remainder.slice(0, underscore);
|
|
98539
|
-
const
|
|
98540
|
-
if (!UUID_V4_RE.test(uuid3) || !
|
|
99870
|
+
const basename11 = remainder.slice(underscore + 1);
|
|
99871
|
+
if (!UUID_V4_RE.test(uuid3) || !basename11)
|
|
98541
99872
|
return false;
|
|
98542
|
-
return sanitizeChatAttachmentFileName(
|
|
99873
|
+
return sanitizeChatAttachmentFileName(basename11) === basename11;
|
|
98543
99874
|
}
|
|
98544
99875
|
function getInvalidChatAttachmentUploadPathReason(relativePath) {
|
|
98545
99876
|
if (relativePath.includes("\\"))
|
|
@@ -98568,14 +99899,14 @@ function normalizeSegments(relativePath) {
|
|
|
98568
99899
|
function hasBlockedSegment(lowerSegments) {
|
|
98569
99900
|
return lowerSegments.some((segment) => BLOCKED_SEGMENT_NAMES.has(segment));
|
|
98570
99901
|
}
|
|
98571
|
-
function hasBlockedBasename(
|
|
98572
|
-
return /^\.env(?:\.|$)/.test(
|
|
99902
|
+
function hasBlockedBasename(basename11) {
|
|
99903
|
+
return /^\.env(?:\.|$)/.test(basename11) || /\.(?:pem|key)$/.test(basename11) || basename11 === "id_rsa" || basename11 === "credentials.json";
|
|
98573
99904
|
}
|
|
98574
99905
|
function isBlockedUploadTargetPath(relativePath) {
|
|
98575
99906
|
if (!relativePath)
|
|
98576
99907
|
return false;
|
|
98577
|
-
const { lowerSegments, basename:
|
|
98578
|
-
return hasBlockedSegment(lowerSegments) || hasBlockedBasename(
|
|
99908
|
+
const { lowerSegments, basename: basename11 } = normalizeSegments(relativePath);
|
|
99909
|
+
return hasBlockedSegment(lowerSegments) || hasBlockedBasename(basename11);
|
|
98579
99910
|
}
|
|
98580
99911
|
function getBlockedUploadTargetReason(relativePath) {
|
|
98581
99912
|
if (!isBlockedUploadTargetPath(relativePath))
|
|
@@ -98625,8 +99956,8 @@ var init_file_write_request_priority = __esm(() => {
|
|
|
98625
99956
|
});
|
|
98626
99957
|
|
|
98627
99958
|
// src/daemon/entry/files/file-write-fulfillment.ts
|
|
98628
|
-
import { access as access4, mkdir as mkdir12, rename as rename4, rm as rm5, writeFile as
|
|
98629
|
-
import { dirname as
|
|
99959
|
+
import { access as access4, mkdir as mkdir12, rename as rename4, rm as rm5, writeFile as writeFile11 } from "node:fs/promises";
|
|
99960
|
+
import { dirname as dirname21 } from "node:path";
|
|
98630
99961
|
function isTerminalFileWriteError(errorMessage3) {
|
|
98631
99962
|
const terminalMessages = new Set([
|
|
98632
99963
|
"Invalid file path",
|
|
@@ -98725,11 +100056,11 @@ async function validateWriteOperation(operation, absolutePath) {
|
|
|
98725
100056
|
}
|
|
98726
100057
|
async function writePayloadToDisk(absolutePath, operation, content) {
|
|
98727
100058
|
if (operation === "create") {
|
|
98728
|
-
await mkdir12(
|
|
98729
|
-
await
|
|
100059
|
+
await mkdir12(dirname21(absolutePath), { recursive: true });
|
|
100060
|
+
await writeFile11(absolutePath, content, { flag: "wx" });
|
|
98730
100061
|
return;
|
|
98731
100062
|
}
|
|
98732
|
-
await
|
|
100063
|
+
await writeFile11(absolutePath, content);
|
|
98733
100064
|
}
|
|
98734
100065
|
async function fulfillOneFileWriteRequest(session2, request3) {
|
|
98735
100066
|
const claim = await claimWriteRequest(session2, request3);
|
|
@@ -98803,7 +100134,7 @@ async function fulfillOneFileWriteRequest(session2, request3) {
|
|
|
98803
100134
|
});
|
|
98804
100135
|
return;
|
|
98805
100136
|
}
|
|
98806
|
-
await mkdir12(
|
|
100137
|
+
await mkdir12(dirname21(targetResolved.absolutePath), { recursive: true });
|
|
98807
100138
|
await rename4(resolved.absolutePath, targetResolved.absolutePath);
|
|
98808
100139
|
await completeWriteRequest(session2, claimed._id, claimed.revision, { status: "done" });
|
|
98809
100140
|
const elapsed2 = Date.now() - startTime;
|
|
@@ -100534,9 +101865,9 @@ var init_execute_chatroom_stop_command = __esm(() => {
|
|
|
100534
101865
|
|
|
100535
101866
|
// src/daemon/entry/persistence-path.ts
|
|
100536
101867
|
import { homedir as homedir13 } from "node:os";
|
|
100537
|
-
import { join as
|
|
101868
|
+
import { join as join32 } from "node:path";
|
|
100538
101869
|
function resolvePersistenceDbPath(machineId) {
|
|
100539
|
-
return
|
|
101870
|
+
return join32(homedir13(), ".chatroom", "daemon", machineId, "events.sqlite");
|
|
100540
101871
|
}
|
|
100541
101872
|
var init_persistence_path = () => {};
|
|
100542
101873
|
|
|
@@ -101095,10 +102426,10 @@ var init_schema = __esm(() => {
|
|
|
101095
102426
|
|
|
101096
102427
|
// src/daemon/infrastructure/persistence/open-database.ts
|
|
101097
102428
|
import { mkdirSync as mkdirSync9 } from "node:fs";
|
|
101098
|
-
import { dirname as
|
|
102429
|
+
import { dirname as dirname22 } from "node:path";
|
|
101099
102430
|
import { DatabaseSync as DatabaseSync5 } from "node:sqlite";
|
|
101100
102431
|
function openDatabase(dbPath) {
|
|
101101
|
-
mkdirSync9(
|
|
102432
|
+
mkdirSync9(dirname22(dbPath), { recursive: true });
|
|
101102
102433
|
const db = new DatabaseSync5(dbPath);
|
|
101103
102434
|
for (const sql of MIGRATIONS2) {
|
|
101104
102435
|
db.exec(sql);
|
|
@@ -112072,13 +113403,13 @@ var require_cookie = __commonJS((exports) => {
|
|
|
112072
113403
|
} while (index < len2);
|
|
112073
113404
|
return obj;
|
|
112074
113405
|
}
|
|
112075
|
-
function startIndex(str, index,
|
|
113406
|
+
function startIndex(str, index, max6) {
|
|
112076
113407
|
do {
|
|
112077
113408
|
var code2 = str.charCodeAt(index);
|
|
112078
113409
|
if (code2 !== 32 && code2 !== 9)
|
|
112079
113410
|
return index;
|
|
112080
|
-
} while (++index <
|
|
112081
|
-
return
|
|
113411
|
+
} while (++index < max6);
|
|
113412
|
+
return max6;
|
|
112082
113413
|
}
|
|
112083
113414
|
function endIndex(str, index, min5) {
|
|
112084
113415
|
while (index > min5) {
|
|
@@ -117211,19 +118542,19 @@ function routeRequest(req, res, deps) {
|
|
|
117211
118542
|
|
|
117212
118543
|
// src/daemon/local-web/server/serve-static.ts
|
|
117213
118544
|
import { existsSync as existsSync10, readFileSync as readFileSync12 } from "node:fs";
|
|
117214
|
-
import { dirname as
|
|
118545
|
+
import { dirname as dirname23, join as join33 } from "node:path";
|
|
117215
118546
|
import { fileURLToPath as fileURLToPath6 } from "node:url";
|
|
117216
118547
|
function clientDistCandidates(here) {
|
|
117217
118548
|
return [
|
|
117218
|
-
|
|
117219
|
-
|
|
117220
|
-
|
|
118549
|
+
join33(here, "client/build"),
|
|
118550
|
+
join33(here, "../client/build"),
|
|
118551
|
+
join33(here, "../src/daemon/local-web/client/build")
|
|
117221
118552
|
];
|
|
117222
118553
|
}
|
|
117223
|
-
function resolveClientDistDir(here =
|
|
118554
|
+
function resolveClientDistDir(here = dirname23(fileURLToPath6(import.meta.url))) {
|
|
117224
118555
|
const candidates = clientDistCandidates(here);
|
|
117225
118556
|
for (const dir of candidates) {
|
|
117226
|
-
if (existsSync10(
|
|
118557
|
+
if (existsSync10(join33(dir, "index.html")))
|
|
117227
118558
|
return dir;
|
|
117228
118559
|
}
|
|
117229
118560
|
return candidates[0];
|
|
@@ -117236,7 +118567,7 @@ function tryServeStatic(req, res, distDir) {
|
|
|
117236
118567
|
return false;
|
|
117237
118568
|
}
|
|
117238
118569
|
const safePath = pathname === "/" ? "/index.html" : pathname;
|
|
117239
|
-
const filePath =
|
|
118570
|
+
const filePath = join33(distDir, safePath);
|
|
117240
118571
|
if (!filePath.startsWith(distDir)) {
|
|
117241
118572
|
res.writeHead(403);
|
|
117242
118573
|
res.end();
|
|
@@ -117253,7 +118584,7 @@ function tryServeStatic(req, res, distDir) {
|
|
|
117253
118584
|
}
|
|
117254
118585
|
return true;
|
|
117255
118586
|
}
|
|
117256
|
-
const indexPath =
|
|
118587
|
+
const indexPath = join33(distDir, "index.html");
|
|
117257
118588
|
if (existsSync10(indexPath)) {
|
|
117258
118589
|
res.writeHead(200, { "Content-Type": "text/html" });
|
|
117259
118590
|
if (req.method === "HEAD") {
|
|
@@ -118617,7 +119948,7 @@ var {
|
|
|
118617
119948
|
} = import__.default;
|
|
118618
119949
|
|
|
118619
119950
|
// src/commands/generate-3d/index.ts
|
|
118620
|
-
import { readFile as
|
|
119951
|
+
import { readFile as readFile4, stat as stat3 } from "node:fs/promises";
|
|
118621
119952
|
init_model_registry();
|
|
118622
119953
|
var GENERATE_3D_PLATFORMS = ["fal"];
|
|
118623
119954
|
var DEFAULT_GENERATE_3D_PLATFORM = "fal";
|
|
@@ -118627,6 +119958,20 @@ function parsePlatform(value) {
|
|
|
118627
119958
|
}
|
|
118628
119959
|
return value;
|
|
118629
119960
|
}
|
|
119961
|
+
var ORIGIN_MODES = ["feet", "center", "as-is"];
|
|
119962
|
+
function parseOrigin(value) {
|
|
119963
|
+
if (!ORIGIN_MODES.includes(value)) {
|
|
119964
|
+
throw new InvalidArgumentError(`must be one of ${ORIGIN_MODES.join(", ")}`);
|
|
119965
|
+
}
|
|
119966
|
+
return value;
|
|
119967
|
+
}
|
|
119968
|
+
function parseTargetHeight(value) {
|
|
119969
|
+
const meters = Number(value);
|
|
119970
|
+
if (!Number.isFinite(meters) || meters <= 0) {
|
|
119971
|
+
throw new InvalidArgumentError("must be a positive, finite number of metres");
|
|
119972
|
+
}
|
|
119973
|
+
return meters;
|
|
119974
|
+
}
|
|
118630
119975
|
var CAPABILITY_FLAGS = [
|
|
118631
119976
|
{ capability: "prompt", flag: "--prompt" },
|
|
118632
119977
|
{ capability: "image", flag: "--input-image" },
|
|
@@ -118661,7 +120006,7 @@ function parseInputJson2(text) {
|
|
|
118661
120006
|
return parsed;
|
|
118662
120007
|
}
|
|
118663
120008
|
async function readInputFile(path) {
|
|
118664
|
-
const stats = await
|
|
120009
|
+
const stats = await stat3(path).catch(() => null);
|
|
118665
120010
|
if (stats === null)
|
|
118666
120011
|
throw new Error(`--input file not found: ${path}`);
|
|
118667
120012
|
if (!stats.isFile())
|
|
@@ -118669,7 +120014,7 @@ async function readInputFile(path) {
|
|
|
118669
120014
|
if (stats.size > MAX_INPUT_BYTES) {
|
|
118670
120015
|
throw new Error(`--input file is ${stats.size} bytes; the maximum is ${MAX_INPUT_BYTES} bytes (1 MiB).`);
|
|
118671
120016
|
}
|
|
118672
|
-
return parseInputJson2(await
|
|
120017
|
+
return parseInputJson2(await readFile4(path, "utf8"));
|
|
118673
120018
|
}
|
|
118674
120019
|
async function readExtraInput(value) {
|
|
118675
120020
|
if (value === undefined)
|
|
@@ -118702,7 +120047,16 @@ Package:
|
|
|
118702
120047
|
<base>.zip holds the master GLB, web/<stem>.web.glb, and manifest.json; the
|
|
118703
120048
|
reference image at reference/... when one was generated or supplied; and the
|
|
118704
120049
|
rigged and animation GLBs with their web versions when rigging ran.
|
|
118705
|
-
<base>.html is a standalone preview
|
|
120050
|
+
<base>.html is a standalone preview of both variants: the full-resolution
|
|
120051
|
+
master and the scaled-down web variant. <base> is <out-stem>-<timestamp>.
|
|
120052
|
+
|
|
120053
|
+
Fit:
|
|
120054
|
+
--target-height and --origin apply to the master, the web variant, and every
|
|
120055
|
+
rig output. With no flags the asset is written as the model returned it.
|
|
120056
|
+
|
|
120057
|
+
Preview:
|
|
120058
|
+
chatroom generate-3d preview <base>.zip rebuilds <base>.html from an existing
|
|
120059
|
+
package without contacting fal. Pass --force to replace an existing page.
|
|
118706
120060
|
|
|
118707
120061
|
Cost:
|
|
118708
120062
|
List prices as of ${GENERATE_3D_PRICES_AS_OF}, not billed amounts; fal returns no
|
|
@@ -118714,9 +120068,18 @@ function printResult(result) {
|
|
|
118714
120068
|
console.log(`Manifest ${result.manifestPath}`);
|
|
118715
120069
|
console.log(`Package ${result.zipPath}`);
|
|
118716
120070
|
console.log(`Preview ${result.htmlPath}`);
|
|
120071
|
+
for (const check of result.checks)
|
|
120072
|
+
console.log(`Warning: ${check.message}`);
|
|
120073
|
+
for (const warning of result.warnings)
|
|
120074
|
+
console.log(`Warning: ${warning}`);
|
|
118717
120075
|
for (const line of result.costLines)
|
|
118718
120076
|
console.log(line);
|
|
118719
120077
|
}
|
|
120078
|
+
function toFit(options) {
|
|
120079
|
+
if (options.origin === "as-is" && options.targetHeight === undefined)
|
|
120080
|
+
return;
|
|
120081
|
+
return { origin: options.origin, targetHeight: options.targetHeight };
|
|
120082
|
+
}
|
|
118720
120083
|
function toGenerate3dOptions(options, extraInput) {
|
|
118721
120084
|
const base = {
|
|
118722
120085
|
prompt: options.prompt,
|
|
@@ -118724,6 +120087,7 @@ function toGenerate3dOptions(options, extraInput) {
|
|
|
118724
120087
|
model: options.model,
|
|
118725
120088
|
out: options.out,
|
|
118726
120089
|
force: options.force,
|
|
120090
|
+
fit: toFit(options),
|
|
118727
120091
|
rig: options.rig,
|
|
118728
120092
|
packageDir: options.packageDir,
|
|
118729
120093
|
extraInput,
|
|
@@ -118747,7 +120111,12 @@ async function executeGenerate3d(options) {
|
|
|
118747
120111
|
const { generate3d: generate3d2 } = await Promise.resolve().then(() => (init_generate_3d(), exports_generate_3d));
|
|
118748
120112
|
printResult(await generate3d2(generateOptions, deps));
|
|
118749
120113
|
}
|
|
118750
|
-
async function runGenerate3d(options) {
|
|
120114
|
+
async function runGenerate3d(options, command) {
|
|
120115
|
+
if (options.out === undefined) {
|
|
120116
|
+
command.error("error: required option '--out <path>' not specified", {
|
|
120117
|
+
code: "commander.missingMandatoryOptionValue"
|
|
120118
|
+
});
|
|
120119
|
+
}
|
|
118751
120120
|
try {
|
|
118752
120121
|
await executeGenerate3d(options);
|
|
118753
120122
|
} catch (err2) {
|
|
@@ -118755,12 +120124,26 @@ async function runGenerate3d(options) {
|
|
|
118755
120124
|
process.exitCode = 1;
|
|
118756
120125
|
}
|
|
118757
120126
|
}
|
|
120127
|
+
async function runGenerate3dPreview(zip, options, command) {
|
|
120128
|
+
try {
|
|
120129
|
+
const { rebuildPreviewFromZip: rebuildPreviewFromZip2 } = await Promise.resolve().then(() => (init_rebuild_preview(), exports_rebuild_preview));
|
|
120130
|
+
const parentForce = command.parent?.opts().force === true;
|
|
120131
|
+
const htmlPath = await rebuildPreviewFromZip2(zip, {
|
|
120132
|
+
force: options.force === true || parentForce
|
|
120133
|
+
});
|
|
120134
|
+
console.log(`Preview ${htmlPath}`);
|
|
120135
|
+
} catch (err2) {
|
|
120136
|
+
console.error(`❌ ${err2 instanceof Error ? err2.message : String(err2)}`);
|
|
120137
|
+
process.exitCode = 1;
|
|
120138
|
+
}
|
|
120139
|
+
}
|
|
118758
120140
|
function registerGenerate3dCommand(program2) {
|
|
118759
|
-
program2.command("generate-3d").description("Generate one 3D mesh (GLB) with a fal model, plus its JSON manifest and a zip/preview package").option("--model <id>", "fal endpoint id (default fal-ai/trellis-2); any id is accepted").
|
|
120141
|
+
const generate3d2 = program2.command("generate-3d").description("Generate one 3D mesh (GLB) with a fal model, plus its JSON manifest and a zip/preview package").option("--model <id>", "fal endpoint id (default fal-ai/trellis-2); any id is accepted").option("--out <path>", "Output GLB path (required; manifest is written to <path>.json)").option("--platform <name>", "Generation platform: fal", parsePlatform, DEFAULT_GENERATE_3D_PLATFORM).option("--prompt <text>", "text prompt; with the default model, a reference image is generated first").option("--input-image <path-or-url>", "reference image (local file or URL); the image-to-3D input").option("--force", "replace existing output, reference, package, preview, rig, and clip files").option("--target-height <meters>", "Scale the model so its height is this many metres (positive, finite)", parseTargetHeight).option("--origin <origin>", "Where the origin goes: feet (bottom centre), center, or as-is (default)", parseOrigin, "as-is").option("--rig", "rig with Meshy 7.1 (requires --model meshy/v7.1/...); needs --confirm-cost on a real run").option("--animation-action-id <id>", "Meshy preset animation id (0-696), repeatable; requires --rig", collectRepeatable, []).option("--package-dir <dir>", "Directory for the package zip and preview (default: the directory of --out)").option("--input <json|@file>", "extra fal request fields as a JSON object, merged over the model defaults; reserved: prompt, image_url; @file reads JSON from a file").option("--confirm-cost", "confirm the priced plan for a real run that rigs or animates (Meshy 7.1 only), after the user confirms the priced dry run; not needed for --dry-run").option("--dry-run", "Validate and print the request and the static list-price estimate. No upload or fal generation call is made; FAL_API_KEY is not required").addHelpText("after", HELP_AFTER).action(runGenerate3d);
|
|
120142
|
+
generate3d2.command("preview <zip>").description("Rebuild <base>.html from an existing package zip, offline").option("--force", "replace an existing <base>.html").action(runGenerate3dPreview);
|
|
118760
120143
|
}
|
|
118761
120144
|
|
|
118762
120145
|
// src/commands/generate-image/index.ts
|
|
118763
|
-
import { readFile as
|
|
120146
|
+
import { readFile as readFile5, stat as stat4 } from "node:fs/promises";
|
|
118764
120147
|
init_image();
|
|
118765
120148
|
init_model_capabilities();
|
|
118766
120149
|
init_image_preflight();
|
|
@@ -118781,7 +120164,7 @@ async function readInputOption(value) {
|
|
|
118781
120164
|
if (!value.startsWith("@"))
|
|
118782
120165
|
return parseInputJson(value);
|
|
118783
120166
|
const path = value.slice(1);
|
|
118784
|
-
const stats = await
|
|
120167
|
+
const stats = await stat4(path).catch(() => null);
|
|
118785
120168
|
if (stats === null)
|
|
118786
120169
|
throw new Error(`--input file not found: ${path}`);
|
|
118787
120170
|
if (!stats.isFile())
|
|
@@ -118789,7 +120172,7 @@ async function readInputOption(value) {
|
|
|
118789
120172
|
if (stats.size > MAX_SIDECAR_BYTES) {
|
|
118790
120173
|
throw new Error(`--input file is ${stats.size} bytes; the maximum is ${MAX_SIDECAR_BYTES} bytes (1 MiB).`);
|
|
118791
120174
|
}
|
|
118792
|
-
return parseInputJson(await
|
|
120175
|
+
return parseInputJson(await readFile5(path, "utf8"));
|
|
118793
120176
|
}
|
|
118794
120177
|
function parseSeed(value) {
|
|
118795
120178
|
const seed = Number(value);
|
|
@@ -118852,7 +120235,7 @@ function registerChatroomRoleCommand(program2, config) {
|
|
|
118852
120235
|
}
|
|
118853
120236
|
|
|
118854
120237
|
// src/commands/remove-image-background/remove-image-background.ts
|
|
118855
|
-
import { basename as
|
|
120238
|
+
import { basename as basename3, dirname as dirname6, extname as extname3, join as join4, resolve as resolve3 } from "node:path";
|
|
118856
120239
|
|
|
118857
120240
|
// src/commands/remove-image-background/background-key.ts
|
|
118858
120241
|
init_image_preflight();
|
|
@@ -119217,7 +120600,7 @@ function resolveMode(opts) {
|
|
|
119217
120600
|
throw new RemoveBackgroundError("--out must end in .png.");
|
|
119218
120601
|
}
|
|
119219
120602
|
const outPath = resolve3(opts.out);
|
|
119220
|
-
return { kind: "single", inPath: resolve3(opts.in), outPath, outDir:
|
|
120603
|
+
return { kind: "single", inPath: resolve3(opts.in), outPath, outDir: dirname6(outPath) };
|
|
119221
120604
|
}
|
|
119222
120605
|
if (opts.inDir === undefined || opts.outDir === undefined) {
|
|
119223
120606
|
throw new RemoveBackgroundError("--in-dir and --out-dir must be used together.");
|
|
@@ -119245,7 +120628,7 @@ function requireRanges(opts) {
|
|
|
119245
120628
|
async function enumerateInputs(mode, deps) {
|
|
119246
120629
|
if (mode.kind === "single") {
|
|
119247
120630
|
return {
|
|
119248
|
-
inputs: [{ path: mode.inPath, stem:
|
|
120631
|
+
inputs: [{ path: mode.inPath, stem: basename3(mode.inPath, extname3(mode.inPath)) }],
|
|
119249
120632
|
ignoredNonPng: 0
|
|
119250
120633
|
};
|
|
119251
120634
|
}
|
|
@@ -119258,7 +120641,7 @@ async function enumerateInputs(mode, deps) {
|
|
|
119258
120641
|
throw new RemoveBackgroundError(`${mode.inDir} contains ${pngs.length} PNG files; the maximum is ${MAX_BATCH_FILES}.`);
|
|
119259
120642
|
}
|
|
119260
120643
|
return {
|
|
119261
|
-
inputs: pngs.map((name) => ({ path:
|
|
120644
|
+
inputs: pngs.map((name) => ({ path: join4(mode.inDir, name), stem: basename3(name, ".png") })),
|
|
119262
120645
|
ignoredNonPng: entries.length - pngs.length
|
|
119263
120646
|
};
|
|
119264
120647
|
}
|
|
@@ -119313,7 +120696,7 @@ function requireSafeName(name, context) {
|
|
|
119313
120696
|
}
|
|
119314
120697
|
function assignNames(mode, opts, tiles) {
|
|
119315
120698
|
if (mode.kind === "single") {
|
|
119316
|
-
const name = requireSafeName(
|
|
120699
|
+
const name = requireSafeName(basename3(mode.outPath, ".png"), "--out");
|
|
119317
120700
|
return [{ tile: tiles[0], assignedName: name, assignedBy: "out" }];
|
|
119318
120701
|
}
|
|
119319
120702
|
const stems = new Set(tiles.map((tile) => tile.stem));
|
|
@@ -119538,7 +120921,7 @@ async function prepareAssets(named, mode, options, deps) {
|
|
|
119538
120921
|
throw new RemoveBackgroundError(`Cannot remove the background from ${entry.tile.path}: ${keyed.message}`);
|
|
119539
120922
|
}
|
|
119540
120923
|
const { encoded, outputWidth, outputHeight, trim } = encodeAsset(entry.tile.image, keyed, options, deps);
|
|
119541
|
-
const path = mode.kind === "single" ? mode.outPath :
|
|
120924
|
+
const path = mode.kind === "single" ? mode.outPath : join4(mode.outDir, `${entry.assignedName}.png`);
|
|
119542
120925
|
prepared.push({
|
|
119543
120926
|
tile: namedTile,
|
|
119544
120927
|
keyed,
|
|
@@ -119817,7 +121200,7 @@ function registerRemoveImageBackgroundFalCommand(program2) {
|
|
|
119817
121200
|
|
|
119818
121201
|
// src/commands/slice-image/slice.ts
|
|
119819
121202
|
init_image_preflight();
|
|
119820
|
-
import { basename as
|
|
121203
|
+
import { basename as basename5, extname as extname4, join as join5, resolve as resolve5 } from "node:path";
|
|
119821
121204
|
var SLICE_TOOL = "chatroom slice-image";
|
|
119822
121205
|
var MAX_TILES = 256;
|
|
119823
121206
|
var MAX_GRID_DIMENSION = 64;
|
|
@@ -119832,12 +121215,12 @@ class SliceImageError extends Error {
|
|
|
119832
121215
|
function padWidth(tileCount) {
|
|
119833
121216
|
return Math.max(2, String(tileCount).length);
|
|
119834
121217
|
}
|
|
119835
|
-
function requireInteger(value, label, min,
|
|
121218
|
+
function requireInteger(value, label, min, max2) {
|
|
119836
121219
|
if (!Number.isInteger(value)) {
|
|
119837
121220
|
throw new SliceImageError(`${label} must be an integer.`);
|
|
119838
121221
|
}
|
|
119839
|
-
if (value < min ||
|
|
119840
|
-
const range =
|
|
121222
|
+
if (value < min || max2 !== undefined && value > max2) {
|
|
121223
|
+
const range = max2 === undefined ? `at least ${min}` : `between ${min} and ${max2}`;
|
|
119841
121224
|
throw new SliceImageError(`${label} must be ${range}.`);
|
|
119842
121225
|
}
|
|
119843
121226
|
return value;
|
|
@@ -120128,20 +121511,20 @@ async function sliceImage(opts, deps) {
|
|
|
120128
121511
|
gutter,
|
|
120129
121512
|
allowRemainder: opts.allowRemainder === true
|
|
120130
121513
|
});
|
|
120131
|
-
const sheetStem =
|
|
121514
|
+
const sheetStem = basename5(inPath, extname4(inPath));
|
|
120132
121515
|
const names = resolveTileNames({
|
|
120133
121516
|
cols,
|
|
120134
121517
|
rows,
|
|
120135
121518
|
names: opts.names,
|
|
120136
121519
|
prefix: opts.prefix ?? sheetStem
|
|
120137
121520
|
});
|
|
120138
|
-
const indexPath =
|
|
121521
|
+
const indexPath = join5(outDir, `${sheetStem}.slices.json`);
|
|
120139
121522
|
const sourceManifestPath = `${inPath}.json`;
|
|
120140
121523
|
const outputs = grid.cells.map((cell) => {
|
|
120141
121524
|
const name = names[cell.index] ?? "";
|
|
120142
121525
|
if (name.length === 0)
|
|
120143
121526
|
return null;
|
|
120144
|
-
const path =
|
|
121527
|
+
const path = join5(outDir, `${name}.png`);
|
|
120145
121528
|
return { cell, name, path, manifestPath: `${path}.json` };
|
|
120146
121529
|
}).filter((entry) => entry !== null);
|
|
120147
121530
|
const skipped = grid.cells.filter((cell) => (names[cell.index] ?? "").length === 0).map((cell) => cell.index);
|
|
@@ -121048,4 +122431,4 @@ program2.hook("preAction", async (_thisCommand, actionCommand) => {
|
|
|
121048
122431
|
});
|
|
121049
122432
|
program2.parse();
|
|
121050
122433
|
|
|
121051
|
-
//# debugId=
|
|
122434
|
+
//# debugId=0BF4A795FB05C49664756E2164756E21
|