@promptbook/node 0.112.0-126 → 0.112.0-127

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.
Files changed (46) hide show
  1. package/README.md +5 -5
  2. package/esm/index.es.js +257 -59
  3. package/esm/index.es.js.map +1 -1
  4. package/esm/src/_packages/components.index.d.ts +2 -0
  5. package/esm/src/_packages/types.index.d.ts +2 -0
  6. package/esm/src/avatars/avatarAnimationScheduler.d.ts +4 -0
  7. package/esm/src/book-components/Chat/Chat/ChatCitationModal.d.ts +2 -0
  8. package/esm/src/book-components/Chat/Chat/ChatMessageItem.d.ts +4 -0
  9. package/esm/src/book-components/Chat/Chat/ChatMessageList.d.ts +4 -0
  10. package/esm/src/book-components/Chat/Chat/ChatProps.d.ts +5 -0
  11. package/esm/src/book-components/Chat/Chat/ChatToolCallModal.d.ts +2 -0
  12. package/esm/src/book-components/Chat/Chat/ChatToolCallModalContent.d.ts +3 -1
  13. package/esm/src/book-components/Chat/Chat/TeamToolCallModalContent.d.ts +2 -0
  14. package/esm/src/book-components/Chat/SourceChip/SourceChip.d.ts +6 -1
  15. package/esm/src/book-components/Chat/hooks/useResolvedCitationLabel.d.ts +12 -0
  16. package/esm/src/book-components/Chat/types/ChatMessage.d.ts +4 -0
  17. package/esm/src/book-components/Chat/types/ChatParticipant.d.ts +1 -1
  18. package/esm/src/book-components/Chat/types/CitationLabelResolver.d.ts +8 -0
  19. package/esm/src/book-components/Chat/utils/citationHelpers.d.ts +9 -0
  20. package/esm/src/book-components/Chat/utils/decodeJsonUnicodeEscapesInMarkdownText.d.ts +14 -0
  21. package/esm/src/book-components/Chat/utils/decodeJsonUnicodeEscapesInMarkdownText.test.d.ts +1 -0
  22. package/esm/src/book-components/Chat/utils/parseCitationsFromContent.d.ts +4 -0
  23. package/esm/src/version.d.ts +1 -1
  24. package/package.json +2 -2
  25. package/umd/index.umd.js +257 -59
  26. package/umd/index.umd.js.map +1 -1
  27. package/umd/src/_packages/components.index.d.ts +2 -0
  28. package/umd/src/_packages/types.index.d.ts +2 -0
  29. package/umd/src/avatars/avatarAnimationScheduler.d.ts +4 -0
  30. package/umd/src/book-components/Chat/Chat/ChatCitationModal.d.ts +2 -0
  31. package/umd/src/book-components/Chat/Chat/ChatMessageItem.d.ts +4 -0
  32. package/umd/src/book-components/Chat/Chat/ChatMessageList.d.ts +4 -0
  33. package/umd/src/book-components/Chat/Chat/ChatProps.d.ts +5 -0
  34. package/umd/src/book-components/Chat/Chat/ChatToolCallModal.d.ts +2 -0
  35. package/umd/src/book-components/Chat/Chat/ChatToolCallModalContent.d.ts +3 -1
  36. package/umd/src/book-components/Chat/Chat/TeamToolCallModalContent.d.ts +2 -0
  37. package/umd/src/book-components/Chat/SourceChip/SourceChip.d.ts +6 -1
  38. package/umd/src/book-components/Chat/hooks/useResolvedCitationLabel.d.ts +12 -0
  39. package/umd/src/book-components/Chat/types/ChatMessage.d.ts +4 -0
  40. package/umd/src/book-components/Chat/types/ChatParticipant.d.ts +1 -1
  41. package/umd/src/book-components/Chat/types/CitationLabelResolver.d.ts +8 -0
  42. package/umd/src/book-components/Chat/utils/citationHelpers.d.ts +9 -0
  43. package/umd/src/book-components/Chat/utils/decodeJsonUnicodeEscapesInMarkdownText.d.ts +14 -0
  44. package/umd/src/book-components/Chat/utils/decodeJsonUnicodeEscapesInMarkdownText.test.d.ts +1 -0
  45. package/umd/src/book-components/Chat/utils/parseCitationsFromContent.d.ts +4 -0
  46. package/umd/src/version.d.ts +1 -1
package/README.md CHANGED
@@ -480,7 +480,7 @@ Prompts marked with `[-]` are not ready yet, prompts containing `@@@` are treate
480
480
  - **Multi-runner execution:** `openai-codex`, `github-copilot`, `cline`, `claude-code`, `opencode`, `gemini`
481
481
  - **Context injection:** `--agent agents/coding/developer.book --context AGENTS.md` or inline extra instructions
482
482
  - **Reasoning control:** `--thinking-level low|medium|high|xhigh` for supported runners
483
- - **Interactive or unattended runs:** default wait mode, or `--no-wait` for batch execution
483
+ - **Unattended or interactive runs:** default auto mode, or `--no-auto` to wait for user confirmation before each prompt
484
484
  - **Git safety:** clean working tree check by default, optional `--ignore-git-changes`
485
485
  - **Opt-in remote pushes:** commits stay local unless you explicitly pass `--auto-push`
486
486
  - **Prompt triage:** `--priority` to process only more important tasks first
@@ -502,7 +502,7 @@ npx ts-node ./src/cli/test/ptbk.ts coder run --harness github-copilot --model gp
502
502
 
503
503
  npx ts-node ./src/cli/test/ptbk.ts coder run --harness github-copilot --model gpt-5.4 --thinking-level xhigh --agent agents/coding/developer.book --context AGENTS.md --auto-push
504
504
 
505
- npx ts-node ./src/cli/test/ptbk.ts coder run --harness github-copilot --model gpt-5.4 --thinking-level xhigh --agent agents/coding/developer.book --context AGENTS.md --ignore-git-changes --no-wait
505
+ npx ts-node ./src/cli/test/ptbk.ts coder run --harness github-copilot --model gpt-5.4 --thinking-level xhigh --agent agents/coding/developer.book --context AGENTS.md --ignore-git-changes
506
506
 
507
507
  npx ts-node ./src/cli/test/ptbk.ts coder find-refactor-candidates
508
508
 
@@ -528,7 +528,7 @@ ptbk coder run --harness github-copilot --model gpt-5.4 --thinking-level xhigh -
528
528
 
529
529
  ptbk coder run --harness github-copilot --model gpt-5.4 --thinking-level xhigh --agent agents/coding/developer.book --context AGENTS.md --auto-push
530
530
 
531
- ptbk coder run --harness github-copilot --model gpt-5.4 --thinking-level xhigh --agent agents/coding/developer.book --context AGENTS.md --test npm run test --ignore-git-changes --no-wait
531
+ ptbk coder run --harness github-copilot --model gpt-5.4 --thinking-level xhigh --agent agents/coding/developer.book --context AGENTS.md --test npm run test --ignore-git-changes
532
532
 
533
533
  ptbk coder find-refactor-candidates
534
534
 
@@ -558,7 +558,7 @@ ptbk coder verify
558
558
  | `--context <text-or-file>` | Appends extra instructions inline or from a file like `AGENTS.md`. |
559
559
  | `--test <command>` | Runs a verification command after each prompt attempt and feeds failing output back for retries. |
560
560
  | `--thinking-level <level>` | Sets reasoning effort for supported runners. |
561
- | `--no-wait` | Skips interactive pauses between prompts for unattended execution. |
561
+ | `--no-auto` | Waits for user confirmation before each prompt instead of running automatically through the queue. |
562
562
  | `--ignore-git-changes` | Disables the clean-working-tree guard. |
563
563
  | `--priority <n>` | Runs only prompts at or above the given priority. |
564
564
  | `--dry-run` | Prints which prompts are ready instead of executing them. |
@@ -571,7 +571,7 @@ ptbk coder verify
571
571
  1. Initialize once with `ptbk coder init`.
572
572
  2. Customize `prompts/templates/*.md` if needed, then create or write prompt files in `prompts/`.
573
573
  3. Customize the starter `AGENTS.md` with repository-specific instructions, then pass `--agent agents/coding/developer.book --context AGENTS.md`.
574
- 4. Run one prompt at a time interactively, or use `--no-wait` for unattended batches.
574
+ 4. Run unattended batches by default, or pass `--no-auto` to confirm each prompt interactively.
575
575
  5. Finish with `ptbk coder verify` so resolved prompts are archived and broken ones get explicit repair follow-ups.
576
576
 
577
577
 
package/esm/index.es.js CHANGED
@@ -35,7 +35,7 @@ const BOOK_LANGUAGE_VERSION = '2.0.0';
35
35
  * @generated
36
36
  * @see https://github.com/webgptorg/promptbook
37
37
  */
38
- const PROMPTBOOK_ENGINE_VERSION = '0.112.0-126';
38
+ const PROMPTBOOK_ENGINE_VERSION = '0.112.0-127';
39
39
  /**
40
40
  * TODO: string_promptbook_version should be constrained to the all versions of Promptbook engine
41
41
  * Note: [💞] Ignore a discrepancy between file name and entity name
@@ -3508,7 +3508,11 @@ function createOutputSnippet(output) {
3508
3508
  if (normalized.length <= OUTPUT_SNIPPET_MAX_CHARS) {
3509
3509
  return normalized;
3510
3510
  }
3511
- return `${normalized.slice(0, OUTPUT_SNIPPET_MAX_CHARS)}\n\n...[truncated]`;
3511
+ return spaceTrim$1((block) => `
3512
+ ${block(normalized.slice(0, OUTPUT_SNIPPET_MAX_CHARS))}
3513
+
3514
+ ...[truncated]
3515
+ `);
3512
3516
  }
3513
3517
  /**
3514
3518
  * Builds one command failure message that keeps a useful snippet of CLI output.
@@ -3518,7 +3522,11 @@ function buildCommandFailureMessage(scriptPathPosix, code, fullOutput) {
3518
3522
  if (!outputSnippet) {
3519
3523
  return `Command "bash ${scriptPathPosix}" exited with code ${code !== null && code !== void 0 ? code : 'unknown'}`;
3520
3524
  }
3521
- return `Command "bash ${scriptPathPosix}" exited with code ${code !== null && code !== void 0 ? code : 'unknown'}\n\n${outputSnippet}`;
3525
+ return spaceTrim$1((block) => `
3526
+ Command "bash ${scriptPathPosix}" exited with code ${code !== null && code !== void 0 ? code : 'unknown'}
3527
+
3528
+ ${block(outputSnippet)}
3529
+ `);
3522
3530
  }
3523
3531
  /**
3524
3532
  * Runs a script until a completion marker is observed and output is idle for a set timeout.
@@ -3635,7 +3643,9 @@ async function runScriptUntilMarkerIdle(options) {
3635
3643
  * Handles process exit and resolves or rejects accordingly.
3636
3644
  */
3637
3645
  const handleExit = (code) => {
3638
- const failure = code === 0 || markerSeen ? undefined : new Error(buildCommandFailureMessage(scriptPathPosix, code, fullOutput));
3646
+ const failure = code === 0 || markerSeen
3647
+ ? undefined
3648
+ : new Error(buildCommandFailureMessage(scriptPathPosix, code, fullOutput));
3639
3649
  const status = failure ? `failed with exit code ${code !== null && code !== void 0 ? code : 'unknown'}` : 'succeeded';
3640
3650
  settleWithLog(status, () => {
3641
3651
  if (!failure) {
@@ -3653,8 +3663,14 @@ async function runScriptUntilMarkerIdle(options) {
3653
3663
  });
3654
3664
  commandProcess.on('error', (error) => {
3655
3665
  const outputSnippet = createOutputSnippet(fullOutput);
3656
- const details = outputSnippet ? `\n\n${outputSnippet}` : '';
3657
- const failure = new Error(`Command "bash ${scriptPathPosix}" failed: ${error.message}${details}`);
3666
+ const failureMessage = outputSnippet
3667
+ ? spaceTrim$1((block) => `
3668
+ Command "bash ${scriptPathPosix}" failed: ${error.message}
3669
+
3670
+ ${block(outputSnippet)}
3671
+ `)
3672
+ : `Command "bash ${scriptPathPosix}" failed: ${error.message}`;
3673
+ const failure = new Error(failureMessage);
3658
3674
  settleWithLog('failed before completion', () => reject(failure), failure);
3659
3675
  });
3660
3676
  });
@@ -4057,7 +4073,11 @@ function limitErrorDetails(details, maxChars = 4000) {
4057
4073
  if (normalized.length <= maxChars) {
4058
4074
  return normalized;
4059
4075
  }
4060
- return `${normalized.slice(0, maxChars)}\n\n...[truncated]`;
4076
+ return spaceTrim((block) => `
4077
+ ${block(normalized.slice(0, maxChars))}
4078
+
4079
+ ...[truncated]
4080
+ `);
4061
4081
  }
4062
4082
  /**
4063
4083
  * Returns true if at least one regex matches the provided text.
@@ -12479,8 +12499,11 @@ class GoalCommitmentDefinition extends BaseCommitmentDefinition {
12479
12499
  if (!trimmedContent) {
12480
12500
  return requirements;
12481
12501
  }
12482
- // Add goal as a proper h2 section to the system message
12483
- const goalSection = `## Goal\n\n${trimmedContent}`;
12502
+ const goalSection = spaceTrim$1((block) => `
12503
+ ## Goal
12504
+
12505
+ ${block(trimmedContent)}
12506
+ `);
12484
12507
  const requirementsWithGoal = this.appendToSystemMessage(requirements, goalSection, '\n\n');
12485
12508
  return this.appendToPromptSuffix(requirementsWithGoal, trimmedContent);
12486
12509
  }
@@ -13002,8 +13025,11 @@ class LanguageCommitmentDefinition extends BaseCommitmentDefinition {
13002
13025
  if (!trimmedContent) {
13003
13026
  return requirements;
13004
13027
  }
13005
- // Add language as a bullet under a ## Language section
13006
- const languageSection = `## Language\n\n- Your language is ${trimmedContent}`;
13028
+ const languageSection = spaceTrim$1((block) => `
13029
+ ## Language
13030
+
13031
+ - Your language is ${block(trimmedContent)}
13032
+ `);
13007
13033
  return this.appendToSystemMessage(requirements, languageSection, '\n\n');
13008
13034
  }
13009
13035
  }
@@ -17949,41 +17975,91 @@ function drawBlobbyOctopusShadow(context, size, palette, interaction, timeMs, mo
17949
17975
  context.fill();
17950
17976
  context.restore();
17951
17977
  }
17978
+ /**
17979
+ * Number of latitude segments used by the single blobby octopus mesh.
17980
+ *
17981
+ * @private helper of `octopus3d2AvatarVisual`
17982
+ */
17983
+ const LATITUDE_PATCH_COUNT$1 = 12;
17984
+ /**
17985
+ * Number of longitude segments used by the single blobby octopus mesh.
17986
+ *
17987
+ * @private helper of `octopus3d2AvatarVisual`
17988
+ */
17989
+ const LONGITUDE_PATCH_COUNT$1 = 24;
17952
17990
  /**
17953
17991
  * Resolves all visible projected patches for the single blobby octopus mesh.
17954
17992
  *
17993
+ * Within a single frame, mesh corner samples and longitude-only lobe-wave values are
17994
+ * quantized to the patch grid and computed once each rather than re-evaluated for every
17995
+ * patch corner — the patch loop alone would call `sampleBlobbyOctopusSurfacePoint`
17996
+ * `latitudePatchCount * longitudePatchCount * 4` times without caching, even though most
17997
+ * corners are shared between neighboring patches.
17998
+ *
17955
17999
  * @private helper of `octopus3d2AvatarVisual`
17956
18000
  */
17957
18001
  function resolveVisibleBlobbyOctopusPatches(options) {
17958
18002
  const { center, rotationX, rotationY, sceneCenterX, sceneCenterY, size, palette, morphologyProfile, animationPhase, timeMs, } = options;
17959
- const latitudePatchCount = 12;
17960
- const longitudePatchCount = 24;
18003
+ const latitudePatchCount = LATITUDE_PATCH_COUNT$1;
18004
+ const longitudePatchCount = LONGITUDE_PATCH_COUNT$1;
17961
18005
  const surfacePatches = [];
18006
+ const latitudeBoundaries = new Float64Array(latitudePatchCount + 1);
18007
+ const longitudeBoundaries = new Float64Array(longitudePatchCount + 1);
18008
+ for (let boundaryIndex = 0; boundaryIndex <= latitudePatchCount; boundaryIndex++) {
18009
+ latitudeBoundaries[boundaryIndex] = -Math.PI / 2 + (boundaryIndex / latitudePatchCount) * Math.PI;
18010
+ }
18011
+ for (let boundaryIndex = 0; boundaryIndex <= longitudePatchCount; boundaryIndex++) {
18012
+ longitudeBoundaries[boundaryIndex] = -Math.PI + (boundaryIndex / longitudePatchCount) * Math.PI * 2;
18013
+ }
18014
+ const cachedLobeWavesByCornerLongitude = new Float64Array(longitudePatchCount + 1);
18015
+ for (let boundaryIndex = 0; boundaryIndex <= longitudePatchCount; boundaryIndex++) {
18016
+ cachedLobeWavesByCornerLongitude[boundaryIndex] = resolveLowerLobeWave(longitudeBoundaries[boundaryIndex], morphologyProfile, animationPhase, timeMs);
18017
+ }
18018
+ const cornerCount = (latitudePatchCount + 1) * (longitudePatchCount + 1);
18019
+ const transformedCornerSamples = new Array(cornerCount);
18020
+ for (let latitudeBoundaryIndex = 0; latitudeBoundaryIndex <= latitudePatchCount; latitudeBoundaryIndex++) {
18021
+ const cornerLatitude = latitudeBoundaries[latitudeBoundaryIndex];
18022
+ for (let longitudeBoundaryIndex = 0; longitudeBoundaryIndex <= longitudePatchCount; longitudeBoundaryIndex++) {
18023
+ const cornerLongitude = longitudeBoundaries[longitudeBoundaryIndex];
18024
+ const cornerIndex = latitudeBoundaryIndex * (longitudePatchCount + 1) + longitudeBoundaryIndex;
18025
+ const cornerSample = sampleBlobbyOctopusSurfacePointWithLongitudeCache(options, cornerLatitude, cornerLongitude, cachedLobeWavesByCornerLongitude[longitudeBoundaryIndex]);
18026
+ transformedCornerSamples[cornerIndex] = transformScenePoint(cornerSample, center, rotationX, rotationY);
18027
+ }
18028
+ }
17962
18029
  for (let latitudeIndex = 0; latitudeIndex < latitudePatchCount; latitudeIndex++) {
17963
- const startLatitude = -Math.PI / 2 + (latitudeIndex / latitudePatchCount) * Math.PI;
17964
- const endLatitude = -Math.PI / 2 + ((latitudeIndex + 1) / latitudePatchCount) * Math.PI;
18030
+ const startLatitude = latitudeBoundaries[latitudeIndex];
18031
+ const endLatitude = latitudeBoundaries[latitudeIndex + 1];
17965
18032
  const centerLatitude = (startLatitude + endLatitude) / 2;
17966
18033
  const verticalProgress = (Math.sin(centerLatitude) + 1) / 2;
18034
+ const startCornerRowOffset = latitudeIndex * (longitudePatchCount + 1);
18035
+ const endCornerRowOffset = (latitudeIndex + 1) * (longitudePatchCount + 1);
17967
18036
  for (let longitudeIndex = 0; longitudeIndex < longitudePatchCount; longitudeIndex++) {
17968
- const startLongitude = -Math.PI + (longitudeIndex / longitudePatchCount) * Math.PI * 2;
17969
- const endLongitude = -Math.PI + ((longitudeIndex + 1) / longitudePatchCount) * Math.PI * 2;
18037
+ const startLongitude = longitudeBoundaries[longitudeIndex];
18038
+ const endLongitude = longitudeBoundaries[longitudeIndex + 1];
17970
18039
  const centerLongitude = (startLongitude + endLongitude) / 2;
17971
- const localCorners = [
17972
- sampleBlobbyOctopusSurfacePoint(options, startLatitude, startLongitude),
17973
- sampleBlobbyOctopusSurfacePoint(options, startLatitude, endLongitude),
17974
- sampleBlobbyOctopusSurfacePoint(options, endLatitude, endLongitude),
17975
- sampleBlobbyOctopusSurfacePoint(options, endLatitude, startLongitude),
18040
+ const transformedCorners = [
18041
+ transformedCornerSamples[startCornerRowOffset + longitudeIndex],
18042
+ transformedCornerSamples[startCornerRowOffset + longitudeIndex + 1],
18043
+ transformedCornerSamples[endCornerRowOffset + longitudeIndex + 1],
18044
+ transformedCornerSamples[endCornerRowOffset + longitudeIndex],
17976
18045
  ];
17977
- const transformedCorners = localCorners.map((localCorner) => transformScenePoint(localCorner, center, rotationX, rotationY));
17978
18046
  const surfaceNormal = normalizeVector3(crossProduct3D(subtractPoint3D(transformedCorners[1], transformedCorners[0]), subtractPoint3D(transformedCorners[2], transformedCorners[0])));
17979
18047
  if (surfaceNormal.z <= 0.01) {
17980
18048
  continue;
17981
18049
  }
17982
- const projectedCorners = transformedCorners.map((transformedCorner) => projectScenePoint(transformedCorner, size, sceneCenterX, sceneCenterY));
18050
+ const projectedCorners = [
18051
+ projectScenePoint(transformedCorners[0], size, sceneCenterX, sceneCenterY),
18052
+ projectScenePoint(transformedCorners[1], size, sceneCenterX, sceneCenterY),
18053
+ projectScenePoint(transformedCorners[2], size, sceneCenterX, sceneCenterY),
18054
+ projectScenePoint(transformedCorners[3], size, sceneCenterX, sceneCenterY),
18055
+ ];
17983
18056
  surfacePatches.push({
17984
18057
  corners: projectedCorners,
17985
- averageDepth: transformedCorners.reduce((depthSum, transformedCorner) => depthSum + transformedCorner.z, 0) /
17986
- transformedCorners.length,
18058
+ averageDepth: (transformedCorners[0].z +
18059
+ transformedCorners[1].z +
18060
+ transformedCorners[2].z +
18061
+ transformedCorners[3].z) /
18062
+ 4,
17987
18063
  lightIntensity: clampNumber$1(dotProduct3D(surfaceNormal, LIGHT_DIRECTION$1), -1, 1),
17988
18064
  fillStyle: resolveBlobbySurfacePatchFillStyle(palette, verticalProgress, Math.max(0, Math.cos(centerLongitude)), resolveLowerLobeWave(centerLongitude, morphologyProfile, animationPhase, timeMs)),
17989
18065
  outlineColor: verticalProgress < 0.58 ? `${palette.highlight}73` : `${palette.shadow}8a`,
@@ -18001,12 +18077,21 @@ function resolveVisibleBlobbyOctopusPatches(options) {
18001
18077
  * @private helper of `octopus3d2AvatarVisual`
18002
18078
  */
18003
18079
  function sampleBlobbyOctopusSurfacePoint(options, latitude, longitude) {
18080
+ const { morphologyProfile, animationPhase, timeMs } = options;
18081
+ return sampleBlobbyOctopusSurfacePointWithLongitudeCache(options, latitude, longitude, resolveLowerLobeWave(longitude, morphologyProfile, animationPhase, timeMs));
18082
+ }
18083
+ /**
18084
+ * Samples one point on the continuous Octopus 3D 2 surface using a precomputed lower-lobe wave
18085
+ * to skip the per-call trig evaluation for `latitudePatchCount + 1` longitude-shared corners.
18086
+ *
18087
+ * @private helper of `octopus3d2AvatarVisual`
18088
+ */
18089
+ function sampleBlobbyOctopusSurfacePointWithLongitudeCache(options, latitude, longitude, lowerLobeWave) {
18004
18090
  const { radiusX, radiusY, radiusZ, morphologyProfile, timeMs, animationPhase } = options;
18005
18091
  const cosineLatitude = Math.max(0, Math.cos(latitude));
18006
18092
  const verticalProgress = (Math.sin(latitude) + 1) / 2;
18007
18093
  const upperBlend = Math.pow(1 - verticalProgress, 1.2);
18008
18094
  const lowerBlend = Math.pow(verticalProgress, 1.42);
18009
- const lowerLobeWave = resolveLowerLobeWave(longitude, morphologyProfile, animationPhase, timeMs);
18010
18095
  const skirtEnvelope = Math.pow(cosineLatitude, 0.5) * lowerBlend;
18011
18096
  const horizontalScale = 1.02 +
18012
18097
  skirtEnvelope * (0.34 + (morphologyProfile.tentacles.rootSpreadScale - 1) * 0.22 + lowerLobeWave * 0.22) -
@@ -18303,45 +18388,102 @@ function drawContinuousOctopusShadow(context, size, palette, interaction, timeMs
18303
18388
  context.fill();
18304
18389
  context.restore();
18305
18390
  }
18391
+ /**
18392
+ * Number of latitude segments used by the continuous Octopus 3D 3 mesh.
18393
+ *
18394
+ * @private helper of `octopus3d3AvatarVisual`
18395
+ */
18396
+ const LATITUDE_PATCH_COUNT = 16;
18397
+ /**
18398
+ * Number of longitude segments used by the continuous Octopus 3D 3 mesh.
18399
+ *
18400
+ * @private helper of `octopus3d3AvatarVisual`
18401
+ */
18402
+ const LONGITUDE_PATCH_COUNT = 40;
18306
18403
  /**
18307
18404
  * Resolves visible projected patches for the continuous octopus mesh.
18308
18405
  *
18406
+ * Within a single frame, mesh corner samples and longitude-only computations (tentacle
18407
+ * influence and lobe wave) are quantized to the patch grid and computed once each rather
18408
+ * than re-evaluated for every patch corner — the patch loop alone calls `sampleContinuousOctopusSurfacePoint`
18409
+ * for `latitudePatchCount * longitudePatchCount * 4` corners without caching, and each call
18410
+ * triggers an inner 8-iteration `Math.exp` loop, which dominates the per-frame cost.
18411
+ *
18309
18412
  * @private helper of `octopus3d3AvatarVisual`
18310
18413
  */
18311
18414
  function resolveVisibleContinuousOctopusPatches(options) {
18312
18415
  const { center, rotationX, rotationY, sceneCenterX, sceneCenterY, size, palette } = options;
18313
- const latitudePatchCount = 16;
18314
- const longitudePatchCount = 40;
18416
+ const latitudePatchCount = LATITUDE_PATCH_COUNT;
18417
+ const longitudePatchCount = LONGITUDE_PATCH_COUNT;
18315
18418
  const surfacePatches = [];
18419
+ const latitudeBoundaries = new Float64Array(latitudePatchCount + 1);
18420
+ const longitudeBoundaries = new Float64Array(longitudePatchCount + 1);
18421
+ for (let boundaryIndex = 0; boundaryIndex <= latitudePatchCount; boundaryIndex++) {
18422
+ latitudeBoundaries[boundaryIndex] = -Math.PI / 2 + (boundaryIndex / latitudePatchCount) * Math.PI;
18423
+ }
18424
+ for (let boundaryIndex = 0; boundaryIndex <= longitudePatchCount; boundaryIndex++) {
18425
+ longitudeBoundaries[boundaryIndex] = -Math.PI + (boundaryIndex / longitudePatchCount) * Math.PI * 2;
18426
+ }
18427
+ const cachedTentacleInfluencesByCornerLongitude = new Array(longitudePatchCount + 1);
18428
+ const cachedLobeWavesByCornerLongitude = new Float64Array(longitudePatchCount + 1);
18429
+ const cachedTentacleInfluencesByPatchCenterLongitude = new Array(longitudePatchCount);
18430
+ const cachedLobeWavesByPatchCenterLongitude = new Float64Array(longitudePatchCount);
18431
+ const cachedCosByPatchCenterLongitude = new Float64Array(longitudePatchCount);
18432
+ for (let boundaryIndex = 0; boundaryIndex <= longitudePatchCount; boundaryIndex++) {
18433
+ const cornerLongitude = longitudeBoundaries[boundaryIndex];
18434
+ cachedTentacleInfluencesByCornerLongitude[boundaryIndex] = resolveContinuousTentacleInfluence(options, cornerLongitude);
18435
+ cachedLobeWavesByCornerLongitude[boundaryIndex] = resolveContinuousLobeWave(options, cornerLongitude);
18436
+ }
18437
+ for (let longitudeIndex = 0; longitudeIndex < longitudePatchCount; longitudeIndex++) {
18438
+ const patchCenterLongitude = (longitudeBoundaries[longitudeIndex] + longitudeBoundaries[longitudeIndex + 1]) / 2;
18439
+ cachedTentacleInfluencesByPatchCenterLongitude[longitudeIndex] = resolveContinuousTentacleInfluence(options, patchCenterLongitude);
18440
+ cachedLobeWavesByPatchCenterLongitude[longitudeIndex] = resolveContinuousLobeWave(options, patchCenterLongitude);
18441
+ cachedCosByPatchCenterLongitude[longitudeIndex] = Math.max(0, Math.cos(patchCenterLongitude));
18442
+ }
18443
+ const cornerCount = (latitudePatchCount + 1) * (longitudePatchCount + 1);
18444
+ const transformedCornerSamples = new Array(cornerCount);
18445
+ for (let latitudeBoundaryIndex = 0; latitudeBoundaryIndex <= latitudePatchCount; latitudeBoundaryIndex++) {
18446
+ const cornerLatitude = latitudeBoundaries[latitudeBoundaryIndex];
18447
+ for (let longitudeBoundaryIndex = 0; longitudeBoundaryIndex <= longitudePatchCount; longitudeBoundaryIndex++) {
18448
+ const cornerLongitude = longitudeBoundaries[longitudeBoundaryIndex];
18449
+ const cornerIndex = latitudeBoundaryIndex * (longitudePatchCount + 1) + longitudeBoundaryIndex;
18450
+ const cornerSample = sampleContinuousOctopusSurfacePointWithLongitudeCache(options, cornerLatitude, cornerLongitude, cachedTentacleInfluencesByCornerLongitude[longitudeBoundaryIndex], cachedLobeWavesByCornerLongitude[longitudeBoundaryIndex]);
18451
+ transformedCornerSamples[cornerIndex] = transformScenePoint(cornerSample, center, rotationX, rotationY);
18452
+ }
18453
+ }
18316
18454
  for (let latitudeIndex = 0; latitudeIndex < latitudePatchCount; latitudeIndex++) {
18317
- const startLatitude = -Math.PI / 2 + (latitudeIndex / latitudePatchCount) * Math.PI;
18318
- const endLatitude = -Math.PI / 2 + ((latitudeIndex + 1) / latitudePatchCount) * Math.PI;
18455
+ const startLatitude = latitudeBoundaries[latitudeIndex];
18456
+ const endLatitude = latitudeBoundaries[latitudeIndex + 1];
18319
18457
  const centerLatitude = (startLatitude + endLatitude) / 2;
18320
18458
  const verticalProgress = (Math.sin(centerLatitude) + 1) / 2;
18459
+ const startCornerRowOffset = latitudeIndex * (longitudePatchCount + 1);
18460
+ const endCornerRowOffset = (latitudeIndex + 1) * (longitudePatchCount + 1);
18321
18461
  for (let longitudeIndex = 0; longitudeIndex < longitudePatchCount; longitudeIndex++) {
18322
- const startLongitude = -Math.PI + (longitudeIndex / longitudePatchCount) * Math.PI * 2;
18323
- const endLongitude = -Math.PI + ((longitudeIndex + 1) / longitudePatchCount) * Math.PI * 2;
18324
- const centerLongitude = (startLongitude + endLongitude) / 2;
18325
- const localCorners = [
18326
- sampleContinuousOctopusSurfacePoint(options, startLatitude, startLongitude),
18327
- sampleContinuousOctopusSurfacePoint(options, startLatitude, endLongitude),
18328
- sampleContinuousOctopusSurfacePoint(options, endLatitude, endLongitude),
18329
- sampleContinuousOctopusSurfacePoint(options, endLatitude, startLongitude),
18462
+ const transformedCorners = [
18463
+ transformedCornerSamples[startCornerRowOffset + longitudeIndex],
18464
+ transformedCornerSamples[startCornerRowOffset + longitudeIndex + 1],
18465
+ transformedCornerSamples[endCornerRowOffset + longitudeIndex + 1],
18466
+ transformedCornerSamples[endCornerRowOffset + longitudeIndex],
18330
18467
  ];
18331
- const transformedCorners = localCorners.map((localCorner) => transformScenePoint(localCorner, center, rotationX, rotationY));
18332
18468
  const surfaceNormal = normalizeVector3(crossProduct3D(subtractPoint3D(transformedCorners[1], transformedCorners[0]), subtractPoint3D(transformedCorners[2], transformedCorners[0])));
18333
18469
  if (surfaceNormal.z <= 0.008) {
18334
18470
  continue;
18335
18471
  }
18336
- const projectedCorners = transformedCorners.map((transformedCorner) => projectScenePoint(transformedCorner, size, sceneCenterX, sceneCenterY));
18337
- const tentacleInfluence = resolveContinuousTentacleInfluence(options, centerLongitude);
18338
- const lowerLobeWave = resolveContinuousLobeWave(options, centerLongitude);
18472
+ const projectedCorners = [
18473
+ projectScenePoint(transformedCorners[0], size, sceneCenterX, sceneCenterY),
18474
+ projectScenePoint(transformedCorners[1], size, sceneCenterX, sceneCenterY),
18475
+ projectScenePoint(transformedCorners[2], size, sceneCenterX, sceneCenterY),
18476
+ projectScenePoint(transformedCorners[3], size, sceneCenterX, sceneCenterY),
18477
+ ];
18339
18478
  surfacePatches.push({
18340
18479
  corners: projectedCorners,
18341
- averageDepth: transformedCorners.reduce((depthSum, transformedCorner) => depthSum + transformedCorner.z, 0) /
18342
- transformedCorners.length,
18480
+ averageDepth: (transformedCorners[0].z +
18481
+ transformedCorners[1].z +
18482
+ transformedCorners[2].z +
18483
+ transformedCorners[3].z) /
18484
+ 4,
18343
18485
  lightIntensity: clampNumber$1(dotProduct3D(surfaceNormal, LIGHT_DIRECTION), -1, 1),
18344
- fillStyle: resolveContinuousSurfacePatchFillStyle(palette, verticalProgress, Math.max(0, Math.cos(centerLongitude)), tentacleInfluence.core, lowerLobeWave),
18486
+ fillStyle: resolveContinuousSurfacePatchFillStyle(palette, verticalProgress, cachedCosByPatchCenterLongitude[longitudeIndex], cachedTentacleInfluencesByPatchCenterLongitude[longitudeIndex].core, cachedLobeWavesByPatchCenterLongitude[longitudeIndex]),
18345
18487
  outlineColor: verticalProgress < 0.54 ? `${palette.highlight}69` : `${palette.shadow}78`,
18346
18488
  });
18347
18489
  }
@@ -18357,16 +18499,27 @@ function resolveVisibleContinuousOctopusPatches(options) {
18357
18499
  * @private helper of `octopus3d3AvatarVisual`
18358
18500
  */
18359
18501
  function sampleContinuousOctopusSurfacePoint(options, latitude, longitude) {
18502
+ return sampleContinuousOctopusSurfacePointWithLongitudeCache(options, latitude, longitude, resolveContinuousTentacleInfluence(options, longitude), resolveContinuousLobeWave(options, longitude));
18503
+ }
18504
+ /**
18505
+ * Samples one point on the continuous Octopus 3D 3 surface using precomputed longitude-only
18506
+ * values to skip the per-call `Math.exp` tentacle-influence loop and the lobe-wave trig call.
18507
+ *
18508
+ * The patch loop quantizes the mesh into a fixed `(latitudePatchCount + 1) * (longitudePatchCount + 1)`
18509
+ * corner grid, so the same longitude is reused across every latitude row and each
18510
+ * tentacle/lobe value can be computed once per frame instead of `latitudePatchCount * 4` times.
18511
+ *
18512
+ * @private helper of `octopus3d3AvatarVisual`
18513
+ */
18514
+ function sampleContinuousOctopusSurfacePointWithLongitudeCache(options, latitude, longitude, tentacleInfluence, lowerLobeWave) {
18360
18515
  const { radiusX, radiusY, radiusZ, morphologyProfile, timeMs, animationPhase } = options;
18361
18516
  const cosineLatitude = Math.max(0, Math.cos(latitude));
18362
18517
  const verticalProgress = (Math.sin(latitude) + 1) / 2;
18363
18518
  const upperBlend = Math.pow(1 - verticalProgress, 1.28);
18364
18519
  const lowerBlend = smoothStep(0.38, 1, verticalProgress);
18365
18520
  const tipBlend = smoothStep(0.68, 1, verticalProgress);
18366
- const tentacleInfluence = resolveContinuousTentacleInfluence(options, longitude);
18367
18521
  const centerPull = resolveSignedAngularDistance(longitude, tentacleInfluence.centerLongitude);
18368
18522
  const effectiveLongitude = longitude + centerPull * lowerBlend * tentacleInfluence.core * (0.24 + tipBlend * 0.2);
18369
- const lowerLobeWave = resolveContinuousLobeWave(options, longitude);
18370
18523
  const mantleRipple = Math.sin(longitude * morphologyProfile.body.lobeCount +
18371
18524
  animationPhase * 0.6 +
18372
18525
  timeMs / (1750 + morphologyProfile.body.lobeCount * 30)) *
@@ -21697,7 +21850,15 @@ function buildTeammateMetadata(entry) {
21697
21850
  * Builds the teammate request text, optionally including context.
21698
21851
  */
21699
21852
  function buildTeammateRequest(message, context) {
21700
- return context ? `${message}\n\nContext:\n${context}` : message;
21853
+ if (!context) {
21854
+ return message;
21855
+ }
21856
+ return spaceTrim$1((block) => `
21857
+ ${block(message)}
21858
+
21859
+ Context:
21860
+ ${block(context)}
21861
+ `);
21701
21862
  }
21702
21863
  /**
21703
21864
  * Builds a minimal chat prompt for teammate calls.
@@ -25523,7 +25684,11 @@ function createUseProjectToolFunctions() {
25523
25684
  const lineRangedContent = applyOptionalLineRange(decodedContent, args.startLine, args.endLine);
25524
25685
  const wasCharacterTruncated = lineRangedContent.length > MAX_PROJECT_FILE_CONTENT_CHARACTERS;
25525
25686
  const contentToReturn = wasCharacterTruncated
25526
- ? `${lineRangedContent.slice(0, MAX_PROJECT_FILE_CONTENT_CHARACTERS)}\n\n[...truncated...]`
25687
+ ? spaceTrim$1((block) => `
25688
+ ${block(lineRangedContent.slice(0, MAX_PROJECT_FILE_CONTENT_CHARACTERS))}
25689
+
25690
+ [...truncated...]
25691
+ `)
25527
25692
  : lineRangedContent;
25528
25693
  const wasTruncated = decoded.isTruncated || wasCharacterTruncated;
25529
25694
  if (wasCharacterTruncated) {
@@ -29059,11 +29224,19 @@ const JsonFileImportPlugin = {
29059
29224
  try {
29060
29225
  const json = JSON.parse(content);
29061
29226
  const formattedJson = JSON.stringify(json, null, 4);
29062
- return `\`\`\`json\n${formattedJson}\n\`\`\``;
29227
+ return spaceTrim$1((block) => `
29228
+ \`\`\`json
29229
+ ${block(formattedJson)}
29230
+ \`\`\`
29231
+ `);
29063
29232
  }
29064
29233
  catch (error) {
29065
29234
  // If JSON is invalid, still import it but maybe not as pretty JSON
29066
- return `\`\`\`json\n${content}\n\`\`\``;
29235
+ return spaceTrim$1((block) => `
29236
+ \`\`\`json
29237
+ ${block(content)}
29238
+ \`\`\`
29239
+ `);
29067
29240
  }
29068
29241
  },
29069
29242
  };
@@ -29087,7 +29260,11 @@ const TextFileImportPlugin = {
29087
29260
  import(content, mimeType) {
29088
29261
  const extension = mimeTypeToExtension(mimeType);
29089
29262
  const codeBlockType = extension || 'txt';
29090
- return `\`\`\`${codeBlockType}\n${content}\n\`\`\``;
29263
+ return spaceTrim$1((block) => `
29264
+ \`\`\`${codeBlockType}
29265
+ ${block(content)}
29266
+ \`\`\`
29267
+ `);
29091
29268
  },
29092
29269
  };
29093
29270
 
@@ -29334,11 +29511,19 @@ function collectExampleInteractionLines(parseResult, samples) {
29334
29511
  const examples = [];
29335
29512
  const initialMessage = (_a = parseResult.commitments.find((commitment) => commitment.type === 'INITIAL MESSAGE')) === null || _a === void 0 ? void 0 : _a.content;
29336
29513
  if (initialMessage) {
29337
- examples.push(`**Agent:**\n${initialMessage}`);
29514
+ examples.push(spaceTrim$1((block) => `
29515
+ **Agent:**
29516
+ ${block(initialMessage)}
29517
+ `));
29338
29518
  }
29339
29519
  if (samples && samples.length > 0) {
29340
29520
  for (const sample of samples) {
29341
- examples.push(`**User:** ${sample.question}\n\n**Agent:**\n${sample.answer}`);
29521
+ examples.push(spaceTrim$1((block) => `
29522
+ **User:** ${block(String(sample.question))}
29523
+
29524
+ **Agent:**
29525
+ ${block(sample.answer)}
29526
+ `));
29342
29527
  }
29343
29528
  }
29344
29529
  return examples;
@@ -30525,10 +30710,14 @@ async function createAgentRunnerSystemMessage(agentSource) {
30525
30710
  * Formats prepared model requirements for a text-only CLI harness prompt.
30526
30711
  */
30527
30712
  function formatAgentModelRequirementsForRunner(modelRequirements) {
30713
+ const promptSuffix = modelRequirements.promptSuffix.trim();
30528
30714
  return [
30529
30715
  modelRequirements.systemMessage.trim(),
30530
- modelRequirements.promptSuffix.trim()
30531
- ? `## Prompt suffix\n${modelRequirements.promptSuffix.trim()}`
30716
+ promptSuffix
30717
+ ? spaceTrim$1((block) => `
30718
+ ## Prompt suffix
30719
+ ${block(promptSuffix)}
30720
+ `)
30532
30721
  : '',
30533
30722
  ]
30534
30723
  .filter(Boolean)
@@ -42336,7 +42525,12 @@ function colorizeAvailableProviderMessage(providerMessage, { isInstalled, isFull
42336
42525
  * @private internal function of `$registeredLlmToolsMessage`
42337
42526
  */
42338
42527
  function createUsedEnvMessage() {
42339
- return $usedEnvFilename === null ? `Unknown \`.env\` file` : `Used \`.env\` file:\n${$usedEnvFilename}`;
42528
+ return $usedEnvFilename === null
42529
+ ? `Unknown \`.env\` file`
42530
+ : spaceTrim$1(`
42531
+ Used \`.env\` file:
42532
+ ${$usedEnvFilename}
42533
+ `);
42340
42534
  }
42341
42535
  // TODO: [®] DRY Register logic
42342
42536
  // TODO: [🧠][⚛] Maybe pass env as argument
@@ -46146,7 +46340,11 @@ function truncateAttachmentInlineText(content, maxCharacters) {
46146
46340
  };
46147
46341
  }
46148
46342
  return {
46149
- content: `${content.slice(0, Math.max(0, maxCharacters))}\n\n[...truncated...]`,
46343
+ content: spaceTrim$1((block) => `
46344
+ ${block(content.slice(0, Math.max(0, maxCharacters)))}
46345
+
46346
+ [...truncated...]
46347
+ `),
46150
46348
  isTruncated: true,
46151
46349
  };
46152
46350
  }