@mindstudio-ai/remy 0.1.75 → 0.1.76
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/headless.js +107 -67
- package/dist/index.js +125 -75
- package/dist/subagents/designExpert/data/sources/ui_inspiration.json +49 -1
- package/dist/subagents/designExpert/data/sources/ui_inspiration_compiled.json +192 -0
- package/dist/subagents/designExpert/prompts/images.md +4 -2
- package/dist/subagents/designExpert/tools/images/enhance-image-prompt.md +4 -3
- package/package.json +1 -1
package/dist/headless.js
CHANGED
|
@@ -1706,9 +1706,9 @@ var setProjectMetadataTool = {
|
|
|
1706
1706
|
import fs9 from "fs/promises";
|
|
1707
1707
|
var DEFAULT_MAX_LINES2 = 500;
|
|
1708
1708
|
function isBinary(buffer) {
|
|
1709
|
-
const
|
|
1710
|
-
for (let i = 0; i <
|
|
1711
|
-
if (
|
|
1709
|
+
const sample = buffer.subarray(0, 8192);
|
|
1710
|
+
for (let i = 0; i < sample.length; i++) {
|
|
1711
|
+
if (sample[i] === 0) {
|
|
1712
1712
|
return true;
|
|
1713
1713
|
}
|
|
1714
1714
|
}
|
|
@@ -3765,7 +3765,7 @@ async function executeDesignExpertTool(name, input, context, toolCallId, onLog)
|
|
|
3765
3765
|
}
|
|
3766
3766
|
|
|
3767
3767
|
// src/subagents/designExpert/prompt.ts
|
|
3768
|
-
import
|
|
3768
|
+
import fs16 from "fs";
|
|
3769
3769
|
|
|
3770
3770
|
// src/subagents/common/context.ts
|
|
3771
3771
|
import fs14 from "fs";
|
|
@@ -3867,25 +3867,74 @@ The first-party SDK (@mindstudio-ai/agent) provides access to 200+ AI models (Op
|
|
|
3867
3867
|
</platform_brief>`;
|
|
3868
3868
|
}
|
|
3869
3869
|
|
|
3870
|
+
// src/subagents/designExpert/data/sampleCache.ts
|
|
3871
|
+
import fs15 from "fs";
|
|
3872
|
+
var SAMPLE_FILE = ".remy-design-sample.json";
|
|
3873
|
+
var cached = null;
|
|
3874
|
+
function generateIndices(poolSize, sampleSize) {
|
|
3875
|
+
const n = Math.min(sampleSize, poolSize);
|
|
3876
|
+
const indices = Array.from({ length: poolSize }, (_, i) => i);
|
|
3877
|
+
for (let i = indices.length - 1; i > 0; i--) {
|
|
3878
|
+
const j = Math.floor(Math.random() * (i + 1));
|
|
3879
|
+
[indices[i], indices[j]] = [indices[j], indices[i]];
|
|
3880
|
+
}
|
|
3881
|
+
return indices.slice(0, n);
|
|
3882
|
+
}
|
|
3883
|
+
function load() {
|
|
3884
|
+
try {
|
|
3885
|
+
return JSON.parse(fs15.readFileSync(SAMPLE_FILE, "utf-8"));
|
|
3886
|
+
} catch {
|
|
3887
|
+
return null;
|
|
3888
|
+
}
|
|
3889
|
+
}
|
|
3890
|
+
function save(indices) {
|
|
3891
|
+
try {
|
|
3892
|
+
fs15.writeFileSync(SAMPLE_FILE, JSON.stringify(indices));
|
|
3893
|
+
} catch {
|
|
3894
|
+
}
|
|
3895
|
+
}
|
|
3896
|
+
function getSampleIndices(pools, sizes) {
|
|
3897
|
+
if (cached) {
|
|
3898
|
+
return cached;
|
|
3899
|
+
}
|
|
3900
|
+
const loaded = load();
|
|
3901
|
+
if (loaded) {
|
|
3902
|
+
let dirty = false;
|
|
3903
|
+
for (const key of ["uiInspiration", "designReferences", "fonts"]) {
|
|
3904
|
+
const before = loaded[key].length;
|
|
3905
|
+
loaded[key] = loaded[key].filter((i) => i < pools[key]);
|
|
3906
|
+
if (loaded[key].length < before) {
|
|
3907
|
+
dirty = true;
|
|
3908
|
+
}
|
|
3909
|
+
}
|
|
3910
|
+
if (dirty) {
|
|
3911
|
+
save(loaded);
|
|
3912
|
+
}
|
|
3913
|
+
cached = loaded;
|
|
3914
|
+
return cached;
|
|
3915
|
+
}
|
|
3916
|
+
cached = {
|
|
3917
|
+
uiInspiration: generateIndices(pools.uiInspiration, sizes.uiInspiration),
|
|
3918
|
+
designReferences: generateIndices(
|
|
3919
|
+
pools.designReferences,
|
|
3920
|
+
sizes.designReferences
|
|
3921
|
+
),
|
|
3922
|
+
fonts: generateIndices(pools.fonts, sizes.fonts)
|
|
3923
|
+
};
|
|
3924
|
+
save(cached);
|
|
3925
|
+
return cached;
|
|
3926
|
+
}
|
|
3927
|
+
function pickByIndices(arr, indices) {
|
|
3928
|
+
return indices.filter((i) => i < arr.length).map((i) => arr[i]);
|
|
3929
|
+
}
|
|
3930
|
+
|
|
3870
3931
|
// src/subagents/designExpert/data/getFontLibrarySample.ts
|
|
3871
3932
|
var fontData = readJsonAsset(
|
|
3872
|
-
{ cssUrlPattern: "", fonts: []
|
|
3933
|
+
{ cssUrlPattern: "", fonts: [] },
|
|
3873
3934
|
"subagents/designExpert/data/sources/fonts.json"
|
|
3874
3935
|
);
|
|
3875
|
-
function
|
|
3876
|
-
|
|
3877
|
-
return [...arr];
|
|
3878
|
-
}
|
|
3879
|
-
const copy = [...arr];
|
|
3880
|
-
for (let i = copy.length - 1; i > 0; i--) {
|
|
3881
|
-
const j = Math.floor(Math.random() * (i + 1));
|
|
3882
|
-
[copy[i], copy[j]] = [copy[j], copy[i]];
|
|
3883
|
-
}
|
|
3884
|
-
return copy.slice(0, n);
|
|
3885
|
-
}
|
|
3886
|
-
function getFontLibrarySample() {
|
|
3887
|
-
const fonts = sample(fontData.fonts, 60);
|
|
3888
|
-
const pairings = sample(fontData.pairings, 30);
|
|
3936
|
+
function getFontLibrarySample(fontIndices) {
|
|
3937
|
+
const fonts = pickByIndices(fontData.fonts, fontIndices);
|
|
3889
3938
|
if (!fonts.length) {
|
|
3890
3939
|
return "";
|
|
3891
3940
|
}
|
|
@@ -3901,16 +3950,11 @@ function getFontLibrarySample() {
|
|
|
3901
3950
|
const desc = f.description ? ` ${f.description}` : "";
|
|
3902
3951
|
return `- **${f.name}** \u2014 ${f.category}. Weights: ${f.weights.join(", ")}.${f.variable ? " Variable." : ""}${f.italics ? " Has italics." : ""}${cssInfo}${desc}`;
|
|
3903
3952
|
}).join("\n");
|
|
3904
|
-
const pairingList = pairings.map(
|
|
3905
|
-
(p) => `- **${p.heading.font}** (${p.heading.weight}) heading + **${p.body.font}** (${p.body.weight}) body`
|
|
3906
|
-
).join("\n");
|
|
3907
3953
|
return `
|
|
3908
3954
|
## Font Library
|
|
3909
3955
|
|
|
3910
3956
|
This is your personal library of fonts you love. Use it as a starting point when thinking about anything related to typography.
|
|
3911
3957
|
|
|
3912
|
-
### Fonts
|
|
3913
|
-
|
|
3914
3958
|
${fontList}`.trim();
|
|
3915
3959
|
}
|
|
3916
3960
|
|
|
@@ -3919,19 +3963,8 @@ var inspirationImages = readJsonAsset(
|
|
|
3919
3963
|
{ images: [] },
|
|
3920
3964
|
"subagents/designExpert/data/sources/inspiration.json"
|
|
3921
3965
|
).images;
|
|
3922
|
-
function
|
|
3923
|
-
|
|
3924
|
-
return [...arr];
|
|
3925
|
-
}
|
|
3926
|
-
const copy = [...arr];
|
|
3927
|
-
for (let i = copy.length - 1; i > 0; i--) {
|
|
3928
|
-
const j = Math.floor(Math.random() * (i + 1));
|
|
3929
|
-
[copy[i], copy[j]] = [copy[j], copy[i]];
|
|
3930
|
-
}
|
|
3931
|
-
return copy.slice(0, n);
|
|
3932
|
-
}
|
|
3933
|
-
function getDesignReferencesSample() {
|
|
3934
|
-
const images = sample2(inspirationImages, 25);
|
|
3966
|
+
function getDesignReferencesSample(indices) {
|
|
3967
|
+
const images = pickByIndices(inspirationImages, indices);
|
|
3935
3968
|
if (!images.length) {
|
|
3936
3969
|
return "";
|
|
3937
3970
|
}
|
|
@@ -3950,19 +3983,8 @@ var uiScreens = readJsonAsset(
|
|
|
3950
3983
|
{ screens: [] },
|
|
3951
3984
|
"subagents/designExpert/data/sources/ui_inspiration_compiled.json"
|
|
3952
3985
|
).screens;
|
|
3953
|
-
function
|
|
3954
|
-
|
|
3955
|
-
return [...arr];
|
|
3956
|
-
}
|
|
3957
|
-
const copy = [...arr];
|
|
3958
|
-
for (let i = copy.length - 1; i > 0; i--) {
|
|
3959
|
-
const j = Math.floor(Math.random() * (i + 1));
|
|
3960
|
-
[copy[i], copy[j]] = [copy[j], copy[i]];
|
|
3961
|
-
}
|
|
3962
|
-
return copy.slice(0, n);
|
|
3963
|
-
}
|
|
3964
|
-
function getUiInspirationSample() {
|
|
3965
|
-
const screens = sample3(uiScreens, 25);
|
|
3986
|
+
function getUiInspirationSample(indices) {
|
|
3987
|
+
const screens = pickByIndices(uiScreens, indices);
|
|
3966
3988
|
if (!screens.length) {
|
|
3967
3989
|
return "";
|
|
3968
3990
|
}
|
|
@@ -3989,10 +4011,28 @@ var PROMPT_TEMPLATE = readAsset(SUBAGENT, "prompt.md").replace(/\{\{([^}]+)\}\}/
|
|
|
3989
4011
|
}).replace(/\n{3,}/g, "\n\n");
|
|
3990
4012
|
function getDesignExpertPrompt() {
|
|
3991
4013
|
const specContext = loadSpecContext();
|
|
4014
|
+
const indices = getSampleIndices(
|
|
4015
|
+
{
|
|
4016
|
+
uiInspiration: uiScreens.length,
|
|
4017
|
+
designReferences: inspirationImages.length,
|
|
4018
|
+
fonts: fontData.fonts.length
|
|
4019
|
+
},
|
|
4020
|
+
{
|
|
4021
|
+
uiInspiration: 50,
|
|
4022
|
+
designReferences: 50,
|
|
4023
|
+
fonts: 50
|
|
4024
|
+
}
|
|
4025
|
+
);
|
|
3992
4026
|
let prompt = PROMPT_TEMPLATE.replace(
|
|
3993
4027
|
"{{font_library}}",
|
|
3994
|
-
getFontLibrarySample()
|
|
3995
|
-
).replace(
|
|
4028
|
+
getFontLibrarySample(indices.fonts)
|
|
4029
|
+
).replace(
|
|
4030
|
+
"{{visual_design_references}}",
|
|
4031
|
+
getDesignReferencesSample(indices.designReferences)
|
|
4032
|
+
).replace(
|
|
4033
|
+
"{{ui_case_studies}}",
|
|
4034
|
+
getUiInspirationSample(indices.uiInspiration)
|
|
4035
|
+
);
|
|
3996
4036
|
prompt += "\n\n<!-- cache_breakpoint -->";
|
|
3997
4037
|
if (specContext) {
|
|
3998
4038
|
prompt += `
|
|
@@ -4000,7 +4040,7 @@ function getDesignExpertPrompt() {
|
|
|
4000
4040
|
${specContext}`;
|
|
4001
4041
|
}
|
|
4002
4042
|
try {
|
|
4003
|
-
|
|
4043
|
+
fs16.writeFileSync(`.design-prompt.md`, prompt);
|
|
4004
4044
|
} catch {
|
|
4005
4045
|
}
|
|
4006
4046
|
return prompt;
|
|
@@ -4209,7 +4249,7 @@ var VISION_TOOLS = [
|
|
|
4209
4249
|
];
|
|
4210
4250
|
|
|
4211
4251
|
// src/subagents/productVision/executor.ts
|
|
4212
|
-
import
|
|
4252
|
+
import fs17 from "fs";
|
|
4213
4253
|
import path8 from "path";
|
|
4214
4254
|
var ROADMAP_DIR = "src/roadmap";
|
|
4215
4255
|
function formatRequires(requires) {
|
|
@@ -4228,8 +4268,8 @@ async function executeVisionTool(name, input) {
|
|
|
4228
4268
|
} = input;
|
|
4229
4269
|
const filePath = path8.join(ROADMAP_DIR, `${slug}.md`);
|
|
4230
4270
|
try {
|
|
4231
|
-
|
|
4232
|
-
const oldContent =
|
|
4271
|
+
fs17.mkdirSync(ROADMAP_DIR, { recursive: true });
|
|
4272
|
+
const oldContent = fs17.existsSync(filePath) ? fs17.readFileSync(filePath, "utf-8") : "";
|
|
4233
4273
|
const content = `---
|
|
4234
4274
|
name: ${itemName}
|
|
4235
4275
|
type: roadmap
|
|
@@ -4241,7 +4281,7 @@ requires: ${formatRequires(requires)}
|
|
|
4241
4281
|
|
|
4242
4282
|
${body}
|
|
4243
4283
|
`;
|
|
4244
|
-
|
|
4284
|
+
fs17.writeFileSync(filePath, content, "utf-8");
|
|
4245
4285
|
const lineCount = content.split("\n").length;
|
|
4246
4286
|
const label = oldContent ? "Updated" : "Wrote";
|
|
4247
4287
|
return `${label} ${filePath} (${lineCount} lines)
|
|
@@ -4254,10 +4294,10 @@ ${unifiedDiff(filePath, oldContent, content)}`;
|
|
|
4254
4294
|
const { slug } = input;
|
|
4255
4295
|
const filePath = path8.join(ROADMAP_DIR, `${slug}.md`);
|
|
4256
4296
|
try {
|
|
4257
|
-
if (!
|
|
4297
|
+
if (!fs17.existsSync(filePath)) {
|
|
4258
4298
|
return `Error: ${filePath} does not exist`;
|
|
4259
4299
|
}
|
|
4260
|
-
const oldContent =
|
|
4300
|
+
const oldContent = fs17.readFileSync(filePath, "utf-8");
|
|
4261
4301
|
let content = oldContent;
|
|
4262
4302
|
if (input.status) {
|
|
4263
4303
|
content = content.replace(
|
|
@@ -4310,7 +4350,7 @@ ${input.appendHistory}
|
|
|
4310
4350
|
`;
|
|
4311
4351
|
}
|
|
4312
4352
|
}
|
|
4313
|
-
|
|
4353
|
+
fs17.writeFileSync(filePath, content, "utf-8");
|
|
4314
4354
|
const lineCount = content.split("\n").length;
|
|
4315
4355
|
return `Updated ${filePath} (${lineCount} lines)
|
|
4316
4356
|
${unifiedDiff(filePath, oldContent, content)}`;
|
|
@@ -4322,11 +4362,11 @@ ${unifiedDiff(filePath, oldContent, content)}`;
|
|
|
4322
4362
|
const { slug } = input;
|
|
4323
4363
|
const filePath = path8.join(ROADMAP_DIR, `${slug}.md`);
|
|
4324
4364
|
try {
|
|
4325
|
-
if (!
|
|
4365
|
+
if (!fs17.existsSync(filePath)) {
|
|
4326
4366
|
return `Error: ${filePath} does not exist`;
|
|
4327
4367
|
}
|
|
4328
|
-
const oldContent =
|
|
4329
|
-
|
|
4368
|
+
const oldContent = fs17.readFileSync(filePath, "utf-8");
|
|
4369
|
+
fs17.unlinkSync(filePath);
|
|
4330
4370
|
return `Deleted ${filePath}
|
|
4331
4371
|
${unifiedDiff(filePath, oldContent, "")}`;
|
|
4332
4372
|
} catch (err) {
|
|
@@ -4646,12 +4686,12 @@ function executeTool(name, input, context) {
|
|
|
4646
4686
|
}
|
|
4647
4687
|
|
|
4648
4688
|
// src/session.ts
|
|
4649
|
-
import
|
|
4689
|
+
import fs18 from "fs";
|
|
4650
4690
|
var log7 = createLogger("session");
|
|
4651
4691
|
var SESSION_FILE = ".remy-session.json";
|
|
4652
4692
|
function loadSession(state) {
|
|
4653
4693
|
try {
|
|
4654
|
-
const raw =
|
|
4694
|
+
const raw = fs18.readFileSync(SESSION_FILE, "utf-8");
|
|
4655
4695
|
const data = JSON.parse(raw);
|
|
4656
4696
|
if (Array.isArray(data.messages) && data.messages.length > 0) {
|
|
4657
4697
|
state.messages = sanitizeMessages(data.messages);
|
|
@@ -4700,7 +4740,7 @@ function sanitizeMessages(messages) {
|
|
|
4700
4740
|
}
|
|
4701
4741
|
function saveSession(state) {
|
|
4702
4742
|
try {
|
|
4703
|
-
|
|
4743
|
+
fs18.writeFileSync(
|
|
4704
4744
|
SESSION_FILE,
|
|
4705
4745
|
JSON.stringify({ messages: state.messages }, null, 2),
|
|
4706
4746
|
"utf-8"
|
|
@@ -4713,7 +4753,7 @@ function saveSession(state) {
|
|
|
4713
4753
|
function clearSession(state) {
|
|
4714
4754
|
state.messages = [];
|
|
4715
4755
|
try {
|
|
4716
|
-
|
|
4756
|
+
fs18.unlinkSync(SESSION_FILE);
|
|
4717
4757
|
} catch {
|
|
4718
4758
|
}
|
|
4719
4759
|
}
|