@wix/ditto-codegen-public 1.0.481 → 1.0.483

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.
@@ -2,27 +2,75 @@ import { tool } from "@opencode-ai/plugin";
2
2
  import { readFile } from "fs/promises";
3
3
  import { join, isAbsolute } from "path";
4
4
 
5
+ // opencode cuts any tool output over 2,000 lines or 50 KB and saves the rest to
6
+ // a file the agent rarely reads, so every file after the cut is silently lost.
7
+ // Stay well under both limits and name the files that didn't fit instead.
8
+ export const OUTPUT_LIMIT = { bytes: 40 * 1024, lines: 1500 };
9
+
10
+ const SECTION_SEPARATOR = "\n\n";
11
+
12
+ async function readSection(
13
+ filePath: string,
14
+ directory: string,
15
+ ): Promise<string> {
16
+ const fullPath = isAbsolute(filePath) ? filePath : join(directory, filePath);
17
+ try {
18
+ const content = await readFile(fullPath, "utf-8");
19
+ return `--- ${filePath} ---\n${content}`;
20
+ } catch (e) {
21
+ const msg = e instanceof Error ? e.message : String(e);
22
+ return `--- ${filePath} ---\nERROR: ${msg}`;
23
+ }
24
+ }
25
+
26
+ function notReadSection(paths: string[]): string {
27
+ return (
28
+ `--- NOT READ (output limit) ---\n` +
29
+ `These files were not read, to keep this output under the tool output limit. ` +
30
+ `Read them with another batch-read call:\n` +
31
+ paths.map((path) => `- ${path}`).join("\n")
32
+ );
33
+ }
34
+
5
35
  export default tool({
6
36
  description:
7
37
  "Read multiple files at once and return their contents. " +
8
- "Use this instead of calling read multiple times sequentially.",
38
+ "Use this instead of calling read multiple times sequentially. " +
39
+ `Returns whole files, in order, up to about ${OUTPUT_LIMIT.bytes / 1024} KB and ${OUTPUT_LIMIT.lines} lines per call; ` +
40
+ "any files past that are listed as not read, so read them in another call.",
9
41
  args: {
10
42
  paths: tool.schema
11
43
  .array(tool.schema.string())
12
44
  .describe("Array of file paths (relative to project root) to read"),
13
45
  },
14
46
  async execute(args, context) {
15
- const results: string[] = [];
47
+ const sections: string[] = [];
48
+ const notRead: string[] = [];
49
+ let bytes = 0;
50
+ let lines = 0;
16
51
  for (const filePath of args.paths) {
17
- const fullPath = isAbsolute(filePath) ? filePath : join(context.directory, filePath);
18
- try {
19
- const content = await readFile(fullPath, "utf-8");
20
- results.push(`--- ${filePath} ---\n${content}`);
21
- } catch (e) {
22
- const msg = e instanceof Error ? e.message : String(e);
23
- results.push(`--- ${filePath} ---\nERROR: ${msg}`);
52
+ if (notRead.length > 0) {
53
+ notRead.push(filePath);
54
+ continue;
55
+ }
56
+ const section = await readSection(filePath, context.directory);
57
+ const sectionBytes =
58
+ Buffer.byteLength(section) + SECTION_SEPARATOR.length;
59
+ const sectionLines = section.split("\n").length + 1;
60
+ // The first file always goes in: alone, it is no worse than a plain read.
61
+ const fits =
62
+ sections.length === 0 ||
63
+ (bytes + sectionBytes <= OUTPUT_LIMIT.bytes &&
64
+ lines + sectionLines <= OUTPUT_LIMIT.lines);
65
+ if (!fits) {
66
+ notRead.push(filePath);
67
+ continue;
24
68
  }
69
+ sections.push(section);
70
+ bytes += sectionBytes;
71
+ lines += sectionLines;
25
72
  }
26
- return results.join("\n\n");
73
+ if (notRead.length > 0) sections.push(notReadSection(notRead));
74
+ return sections.join(SECTION_SEPARATOR);
27
75
  },
28
76
  });
package/dist/out.js CHANGED
@@ -14957,7 +14957,7 @@ var require_shared_rules = __commonJS({
14957
14957
  "dist/opencode-integration/rules/shared-rules.js"(exports2) {
14958
14958
  "use strict";
14959
14959
  Object.defineProperty(exports2, "__esModule", { value: true });
14960
- exports2.OUTPUT_MESSAGE_RULES = exports2.BOUNDARY_RULES = void 0;
14960
+ exports2.OUTCOME_MESSAGE_RULES = exports2.OUTPUT_MESSAGE_RULES = exports2.BOUNDARY_RULES = void 0;
14961
14961
  exports2.buildEnvironmentRules = buildEnvironmentRules;
14962
14962
  exports2.buildFileOperationsRules = buildFileOperationsRules;
14963
14963
  function buildEnvironmentRules(environmentIdentity) {
@@ -14972,6 +14972,7 @@ ${environmentIdentity}`;
14972
14972
  - Match their technical level: include code/technical detail only if their request was technical; otherwise describe the outcome in plain language (no code, file/type names, or internals).
14973
14973
  - List any manual setup the user must still do for the feature to work, as short "next steps" (e.g. installing a dependent app or enabling a dashboard setting).
14974
14974
  - Be honest: if you didn't fully build what was asked (e.g. stored data but didn't send it), say so. Keep it short.`;
14975
+ exports2.OUTCOME_MESSAGE_RULES = `- Lead with whether the request succeeded or failed and what changed (e.g. "Added\u2026", "Removed\u2026"). Never report validation, build, or type-check status as the outcome, and re-state the outcome in your last message even if you already said it earlier.`;
14975
14976
  function buildFileOperationsRules(multiEditContextClause) {
14976
14977
  return `- Package dependencies \u2014 \`npm install <pkg>\` any package not already in \`package.json\` BEFORE the first \`validate\` (do NOT wait for \`TS2307\`); install all needed packages in ONE command, except heavy ones: the sandbox has a memory limit and an install that exceeds it kills the machine and loses the whole run, so install those in several smaller commands. Do NOT hand-edit \`package.json\` for deps unless npm cannot be used. Never pass \`--package-lock=false\`.
14977
14978
  - File operations \u2014 pick the BATCH tool whenever you have 2+ files; the single-file variants are 5\u201310\xD7 slower:
@@ -15068,7 +15069,8 @@ The \`required-permissions\` tool records and surfaces permissions to the user a
15068
15069
  (0, shared_rules_1.buildEnvironmentRules)(environmentIdentity),
15069
15070
  shared_rules_1.BOUNDARY_RULES,
15070
15071
  buildCoreRules(validation),
15071
- shared_rules_1.OUTPUT_MESSAGE_RULES
15072
+ `${shared_rules_1.OUTPUT_MESSAGE_RULES}
15073
+ ${shared_rules_1.OUTCOME_MESSAGE_RULES}`
15072
15074
  ].join("\n\n");
15073
15075
  }
15074
15076
  }
@@ -15993,7 +15995,7 @@ var require_validation_state = __commonJS({
15993
15995
  exports2.VALIDATION_STATE_EVENT_TYPE = "validation_state";
15994
15996
  exports2.VALIDATION_LOADED_EVENT_TYPE = "validation_loaded";
15995
15997
  exports2.VALIDATION_STATE_PLUGIN_FILENAME = "validation-state.ts";
15996
- exports2.VALIDATION_NUDGE = "Project files need validation. Follow your validation workflow (delegate to codegen-validator if your instructions require it), run validate({ runBuild: true }), and fix any errors before finishing.";
15998
+ exports2.VALIDATION_NUDGE = "Project files need validation. Follow your validation workflow (delegate to codegen-validator if your instructions require it), run validate({ runBuild: true }), and fix any errors before finishing. Your last message is shown to the user: once validation passes, end with a short plain-language summary of what changed for them, not the validation status.";
15997
15999
  function buildValidationStateSource() {
15998
16000
  return String.raw`// Generated by @wix/ditto-codegen (validation-state). Do not edit.
15999
16001
  const EVENT_TYPE = ${JSON.stringify(exports2.VALIDATION_STATE_EVENT_TYPE)};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wix/ditto-codegen-public",
3
- "version": "1.0.481",
3
+ "version": "1.0.483",
4
4
  "description": "AI-powered Wix CLI app generator - standalone executable",
5
5
  "scripts": {
6
6
  "build": "node build.mjs",
@@ -29,5 +29,5 @@
29
29
  "esbuild": "^0.27.2",
30
30
  "vitest": "^4.0.16"
31
31
  },
32
- "falconPackageHash": "fb8725cd483f4c797567c369d6b0481e296080219712238314bf34dd"
32
+ "falconPackageHash": "08e5c0c0beef6a0acb833061c90a5e77d57ad5d9f552a1b4ee922c0b"
33
33
  }