@promptbook/node 0.114.0-4 → 0.114.0-6

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 (82) hide show
  1. package/README.md +3 -3
  2. package/esm/index.es.js +199 -39
  3. package/esm/index.es.js.map +1 -1
  4. package/esm/scripts/run-agent-messages/messages/buildAgentMessagePrompt.d.ts +7 -1
  5. package/esm/scripts/run-agent-messages/messages/buildAgentTeamPromptSection.d.ts +12 -0
  6. package/esm/src/avatars/renderAvatarVisualTerminalText.d.ts +80 -0
  7. package/esm/src/avatars/types/AvatarVisualDefinition.d.ts +54 -0
  8. package/esm/src/book-3.0/AgentTeamConversationWorkspace.d.ts +85 -0
  9. package/esm/src/book-components/Chat/Chat/ChatProps.d.ts +3 -2
  10. package/esm/src/book-components/Chat/utils/renderMarkdown.d.ts +5 -3
  11. package/esm/src/cli/cli-commands/coder/boilerplateCount.d.ts +1 -1
  12. package/esm/src/cli/cli-commands/coder/generate-boilerplates.d.ts +1 -1
  13. package/esm/src/cli/cli-commands/coder/verify.d.ts +1 -1
  14. package/esm/src/cli/cli-commands/common/{harness/$askForHarnessInstallationApproval.d.ts → npm/$askForNpmPackageInstallationApproval.d.ts} +2 -2
  15. package/esm/src/cli/cli-commands/common/{harness/$resolveLatestHarnessVersion.d.ts → npm/$resolveLatestNpmPackageVersion.d.ts} +2 -3
  16. package/esm/src/cli/cli-commands/common/npm/extractNpmPackageVersionFromOutput.d.ts +12 -0
  17. package/esm/src/cli/cli-commands/common/npm/isNpmPackageVersionOutdated.d.ts +9 -0
  18. package/esm/src/cli/cli-commands/common/promptbook-cli/$checkPromptbookCliInstallations.d.ts +9 -0
  19. package/esm/src/cli/cli-commands/common/promptbook-cli/$ensurePromptbookCliInstallations.d.ts +14 -0
  20. package/esm/src/cli/cli-commands/common/promptbook-cli/$ensurePromptbookCliInstallations.test.d.ts +1 -0
  21. package/esm/src/cli/cli-commands/common/promptbook-cli/$resolvePromptbookCliInstallations.d.ts +12 -0
  22. package/esm/src/cli/cli-commands/common/promptbook-cli/$resolvePromptbookCliInstallations.test.d.ts +1 -0
  23. package/esm/src/cli/cli-commands/common/promptbook-cli/$updatePromptbookCliInstallation.d.ts +10 -0
  24. package/esm/src/cli/cli-commands/common/promptbook-cli/PromptbookCliInstallation.d.ts +39 -0
  25. package/esm/src/cli/cli-commands/common/promptbook-cli/PromptbookCliInstallationStatus.d.ts +26 -0
  26. package/esm/src/cli/cli-commands/common/promptbook-cli/buildPromptbookCliInstallCommand.d.ts +7 -0
  27. package/esm/src/cli/cli-commands/common/promptbook-cli/buildPromptbookCliInstallCommand.test.d.ts +1 -0
  28. package/esm/src/cli/cli-commands/common/promptbook-cli/formatPromptbookCliInstallationWarning.d.ts +7 -0
  29. package/esm/src/utils/agent-message-runtime/resolveAgentMessageRuntimeActivity.d.ts +3 -3
  30. package/esm/src/utils/agents/terminalAgentAvatarVisual.d.ts +5 -2
  31. package/esm/src/utils/ascii-art/convertImageDataToAsciiArt.d.ts +6 -0
  32. package/esm/src/utils/ascii-art/createAnsiColorCode.d.ts +46 -0
  33. package/esm/src/utils/misc/debounce.d.ts +4 -2
  34. package/esm/src/utils/misc/debounce.test.d.ts +1 -0
  35. package/esm/src/version.d.ts +1 -1
  36. package/package.json +2 -2
  37. package/umd/index.umd.js +199 -39
  38. package/umd/index.umd.js.map +1 -1
  39. package/umd/scripts/run-agent-messages/messages/buildAgentMessagePrompt.d.ts +7 -1
  40. package/umd/scripts/run-agent-messages/messages/buildAgentTeamPromptSection.d.ts +12 -0
  41. package/umd/src/avatars/renderAvatarVisualTerminalText.d.ts +80 -0
  42. package/umd/src/avatars/renderAvatarVisualTerminalText.test.d.ts +1 -0
  43. package/umd/src/avatars/types/AvatarVisualDefinition.d.ts +54 -0
  44. package/umd/src/book-3.0/AgentTeamConversationWorkspace.d.ts +85 -0
  45. package/umd/src/book-components/Chat/Chat/ChatProps.d.ts +3 -2
  46. package/umd/src/book-components/Chat/utils/renderMarkdown.d.ts +5 -3
  47. package/umd/src/cli/cli-commands/coder/boilerplateCount.d.ts +1 -1
  48. package/umd/src/cli/cli-commands/coder/generate-boilerplates.d.ts +1 -1
  49. package/umd/src/cli/cli-commands/coder/verify.d.ts +1 -1
  50. package/umd/src/cli/cli-commands/common/{harness/$askForHarnessInstallationApproval.d.ts → npm/$askForNpmPackageInstallationApproval.d.ts} +2 -2
  51. package/umd/src/cli/cli-commands/common/{harness/$resolveLatestHarnessVersion.d.ts → npm/$resolveLatestNpmPackageVersion.d.ts} +2 -3
  52. package/umd/src/cli/cli-commands/common/npm/$resolveLatestNpmPackageVersion.test.d.ts +1 -0
  53. package/umd/src/cli/cli-commands/common/npm/extractNpmPackageVersionFromOutput.d.ts +12 -0
  54. package/umd/src/cli/cli-commands/common/npm/extractNpmPackageVersionFromOutput.test.d.ts +1 -0
  55. package/umd/src/cli/cli-commands/common/npm/isNpmPackageVersionOutdated.d.ts +9 -0
  56. package/umd/src/cli/cli-commands/common/npm/isNpmPackageVersionOutdated.test.d.ts +1 -0
  57. package/umd/src/cli/cli-commands/common/promptbook-cli/$checkPromptbookCliInstallations.d.ts +9 -0
  58. package/umd/src/cli/cli-commands/common/promptbook-cli/$ensurePromptbookCliInstallations.d.ts +14 -0
  59. package/umd/src/cli/cli-commands/common/promptbook-cli/$ensurePromptbookCliInstallations.test.d.ts +1 -0
  60. package/umd/src/cli/cli-commands/common/promptbook-cli/$resolvePromptbookCliInstallations.d.ts +12 -0
  61. package/umd/src/cli/cli-commands/common/promptbook-cli/$resolvePromptbookCliInstallations.test.d.ts +1 -0
  62. package/umd/src/cli/cli-commands/common/promptbook-cli/$updatePromptbookCliInstallation.d.ts +10 -0
  63. package/umd/src/cli/cli-commands/common/promptbook-cli/PromptbookCliInstallation.d.ts +39 -0
  64. package/umd/src/cli/cli-commands/common/promptbook-cli/PromptbookCliInstallationStatus.d.ts +26 -0
  65. package/umd/src/cli/cli-commands/common/promptbook-cli/buildPromptbookCliInstallCommand.d.ts +7 -0
  66. package/umd/src/cli/cli-commands/common/promptbook-cli/buildPromptbookCliInstallCommand.test.d.ts +1 -0
  67. package/umd/src/cli/cli-commands/common/promptbook-cli/formatPromptbookCliInstallationWarning.d.ts +7 -0
  68. package/umd/src/utils/agent-message-runtime/resolveAgentMessageRuntimeActivity.d.ts +3 -3
  69. package/umd/src/utils/agents/terminalAgentAvatarVisual.d.ts +5 -2
  70. package/umd/src/utils/ascii-art/convertImageDataToAsciiArt.d.ts +6 -0
  71. package/umd/src/utils/ascii-art/createAnsiColorCode.d.ts +46 -0
  72. package/umd/src/utils/misc/debounce.d.ts +4 -2
  73. package/umd/src/utils/misc/debounce.test.d.ts +1 -0
  74. package/umd/src/version.d.ts +1 -1
  75. package/esm/src/cli/cli-commands/common/harness/extractHarnessVersionFromOutput.d.ts +0 -11
  76. package/esm/src/cli/cli-commands/common/harness/isHarnessVersionOutdated.d.ts +0 -9
  77. package/umd/src/cli/cli-commands/common/harness/extractHarnessVersionFromOutput.d.ts +0 -11
  78. package/umd/src/cli/cli-commands/common/harness/isHarnessVersionOutdated.d.ts +0 -9
  79. /package/esm/src/{cli/cli-commands/common/harness/extractHarnessVersionFromOutput.test.d.ts → avatars/renderAvatarVisualTerminalText.test.d.ts} +0 -0
  80. /package/esm/src/cli/cli-commands/common/{harness/isHarnessVersionOutdated.test.d.ts → npm/$resolveLatestNpmPackageVersion.test.d.ts} +0 -0
  81. /package/{umd/src/cli/cli-commands/common/harness/extractHarnessVersionFromOutput.test.d.ts → esm/src/cli/cli-commands/common/npm/extractNpmPackageVersionFromOutput.test.d.ts} +0 -0
  82. /package/{umd/src/cli/cli-commands/common/harness/isHarnessVersionOutdated.test.d.ts → esm/src/cli/cli-commands/common/npm/isNpmPackageVersionOutdated.test.d.ts} +0 -0
package/README.md CHANGED
@@ -463,7 +463,7 @@ Or you can install them separately:
463
463
 
464
464
  Promptbook Coder is **not another standalone coding model**. It is an orchestration layer over coding agents such as **GitHub Copilot**, **OpenAI Codex**, **Claude Code**, **Opencode**, **Cline**, and **Gemini CLI**. The difference is that Promptbook Coder adds a repeatable repository workflow on top of them:
465
465
 
466
- - prompt files with explicit statuses like `[ ]`, `[x]`, and `[-]`
466
+ - prompt files with explicit statuses like `[ ]`, `[^]`, `[x]`, and `[-]`
467
467
  - automatic selection of the next runnable task, including priority support
468
468
  - optional shared repo context loaded from a file such as `AGENTS.md`
469
469
  - automatic `git add`, commit, and push after each successful prompt
@@ -478,11 +478,11 @@ In short: tools like Claude Code, Codex, or GitHub Copilot are the **engines**;
478
478
  1. `ptbk coder init` prepares the project for the coder workflow, seeds project-owned generic templates in `prompts/templates/`, creates a starter `AGENTS.md` context file, adds helper `npm run coder:*` scripts, ensures `.gitignore` ignores `/.promptbook`, and configures VS Code prompt screenshots in `prompts/screenshots/`.
479
479
  2. `ptbk coder generate-boilerplates` creates prompt files in `prompts/`.
480
480
  3. You replace placeholder `@@@` sections with real coding tasks.
481
- 4. `ptbk coder run` sends the next ready `[ ]` prompt to the selected coding agent.
481
+ 4. `ptbk coder run` sends the next ready `[ ]` prompt to the selected coding agent and immediately marks it as in progress `[^]`, naming the harness, the model and the step which is running.
482
482
  5. Promptbook Coder marks the prompt as done `[x]`, records runner metadata, then stages, commits, and pushes the resulting changes.
483
483
  6. `ptbk coder verify` reviews completed prompts, archives finished files to `prompts/done/`, and appends a repair prompt when more work is needed.
484
484
 
485
- Prompts marked with `[-]` are not ready yet, prompts containing `@@@` are treated as not fully written, and prompts with more `!` markers have higher priority.
485
+ Prompts marked with `[-]` are not ready yet, prompts containing `@@@` are treated as not fully written, and prompts with more `!` markers have higher priority. A prompt left as `[^]` was interrupted in the middle of its implementation — the in-progress status is never reverted, so a killed or crashed coder always leaves that signal behind.
486
486
 
487
487
  #### Features
488
488
 
package/esm/index.es.js CHANGED
@@ -29,7 +29,7 @@ const BOOK_LANGUAGE_VERSION = '2.0.0';
29
29
  * @generated
30
30
  * @see https://github.com/webgptorg/promptbook
31
31
  */
32
- const PROMPTBOOK_ENGINE_VERSION = '0.114.0-4';
32
+ const PROMPTBOOK_ENGINE_VERSION = '0.114.0-6';
33
33
  /**
34
34
  * TODO: string_promptbook_version should be constrained to the all versions of Promptbook engine
35
35
  * Note: [💞] Ignore a discrepancy between file name and entity name
@@ -5130,6 +5130,65 @@ function buildProjectRuntimeInstructions(projectRuntimeApi) {
5130
5130
  `);
5131
5131
  }
5132
5132
 
5133
+ // Note: [💞] This file defines the shared TEAM workspace convention rather than one standalone entity.
5134
+ /**
5135
+ * Relative directory for an active TEAM conversation workspace.
5136
+ *
5137
+ * @private internal convention shared by the Agents Server and agent-folder runner
5138
+ */
5139
+ join(AGENT_MESSAGES_DIRECTORY_PATH, 'team');
5140
+ /**
5141
+ * Relative directory where completed TEAM conversation transcripts are retained.
5142
+ *
5143
+ * @private internal convention shared by the Agents Server and agent-folder runner
5144
+ */
5145
+ join(AGENT_FINISHED_MESSAGES_DIRECTORY_PATH, 'team');
5146
+ /**
5147
+ * Name of the read-only teammate-source directory inside one TEAM workspace.
5148
+ *
5149
+ * @private internal convention shared by the Agents Server and agent-folder runner
5150
+ */
5151
+ const AGENT_TEAMMATE_SOURCES_DIRECTORY_NAME = 'teammates';
5152
+
5153
+ /**
5154
+ * Builds the optional single-run TEAM consultation instructions for a coding harness.
5155
+ */
5156
+ function buildAgentTeamPromptSection(workspace) {
5157
+ if (!workspace || workspace.manifest.teammates.length === 0) {
5158
+ return '';
5159
+ }
5160
+ const teammateSections = workspace.manifest.teammates.map((teammate) => {
5161
+ const sourcePath = toPromptPath(join(workspace.relativeWorkspacePath, AGENT_TEAMMATE_SOURCES_DIRECTORY_NAME, teammate.sourceFileName));
5162
+ const transcriptPath = toPromptPath(join(workspace.relativeWorkspacePath, `${teammate.permanentId}--01.book`));
5163
+ const instructions = teammate.instructions.trim() || 'No additional TEAM instructions were provided.';
5164
+ return spaceTrim$1(`
5165
+ - ${teammate.agentName}
5166
+ - TEAM instructions: ${instructions}
5167
+ - Read-only source: \`${sourcePath}\`
5168
+ - First transcript file: \`${transcriptPath}\`
5169
+ `);
5170
+ });
5171
+ return spaceTrim$1((block) => `
5172
+ ## Team consultations
5173
+
5174
+ The following teammates are available for this user turn:
5175
+
5176
+ ${block(teammateSections.join('\n'))}
5177
+
5178
+ - The underlying coding harness is already executing this turn **exactly once**. Never start, queue, or invoke another coding harness, agent runner, or \`ptbk\` command to consult a teammate.
5179
+ - The primary agent remains responsible for the final user-facing \`MESSAGE @Agent\` answer.
5180
+ - Teammate source files are read-only context. When a teammate consultation occurs, record the actual exchange in a new top-level \`.book\` file in \`${toPromptPath(workspace.relativeWorkspacePath)}\`.
5181
+ - Name each transcript \`<teammate permanent id>--<sequence>.book\`, for example \`${workspace.manifest.teammates[0].permanentId}--01.book\`.
5182
+ - Every transcript must contain alternating \`MESSAGE @${workspace.manifest.primaryAgent.agentName}\` and \`MESSAGE @<teammate name>\` blocks. Do not create a transcript for a teammate that was not consulted.
5183
+ `);
5184
+ }
5185
+ /**
5186
+ * Converts a filesystem-relative path into the portable path notation used in prompts.
5187
+ */
5188
+ function toPromptPath(path) {
5189
+ return path.replace(/\\/gu, '/');
5190
+ }
5191
+
5133
5192
  /**
5134
5193
  * Builds the prompt sent to the selected coding runner for one queued user-thread book.
5135
5194
  */
@@ -5139,7 +5198,7 @@ function buildAgentMessagePrompt(messageRelativePath, agentSystemMessage, option
5139
5198
 
5140
5199
  - Read \`${messageRelativePath}\` and answer the most recent \`MESSAGE @User\`
5141
5200
  - Only change the queued message file by appending one new \`MESSAGE @Agent\` block
5142
- - Do not modify any other file in the repository, except files inside your own \`${AGENT_PROJECTS_DIRECTORY_PATH}/\` directory
5201
+ ${block(buildAllowedFileChangesPromptLine(options.teamWorkspace))}
5143
5202
 
5144
5203
  ## Rules for the answering
5145
5204
 
@@ -5177,11 +5236,22 @@ function buildAgentMessagePrompt(messageRelativePath, agentSystemMessage, option
5177
5236
 
5178
5237
  ${block(buildAgentProjectsPromptSection(options))}
5179
5238
 
5239
+ ${block(buildAgentTeamPromptSection(options.teamWorkspace))}
5240
+
5180
5241
  ## This is how you should behave
5181
5242
 
5182
5243
  ${block(agentSystemMessage)}
5183
5244
  `);
5184
5245
  }
5246
+ /**
5247
+ * Explains the exact files that one coding harness may change for a user turn.
5248
+ */
5249
+ function buildAllowedFileChangesPromptLine(teamWorkspace) {
5250
+ if (!teamWorkspace) {
5251
+ return `- Do not modify any other file in the repository, except files inside your own \`${AGENT_PROJECTS_DIRECTORY_PATH}/\` directory`;
5252
+ }
5253
+ return `- Do not modify any other file in the repository, except files inside your own \`${AGENT_PROJECTS_DIRECTORY_PATH}/\` directory and new consultation transcripts inside \`${teamWorkspace.relativeWorkspacePath.replace(/\\/gu, '/')}\``;
5254
+ }
5185
5255
 
5186
5256
  /**
5187
5257
  * Temporary subdirectory used for agent-message runner shell scripts.
@@ -13897,6 +13967,13 @@ function darken(amount) {
13897
13967
  }
13898
13968
 
13899
13969
  /* eslint-disable no-magic-numbers */
13970
+ // Note: [💞] Ignore a discrepancy between file name and entity name
13971
+ /**
13972
+ * Default square size used by avatar renderers.
13973
+ *
13974
+ * @private utility of the avatar rendering system
13975
+ */
13976
+ const DEFAULT_AVATAR_SIZE = 192;
13900
13977
  /**
13901
13978
  * Corner radius ratio used for the common rounded card frame.
13902
13979
  *
@@ -14267,6 +14344,15 @@ const OUTLINE_GLYPHS = ['#', '%', '@'];
14267
14344
  * @private helper of `asciiOctopusAvatarVisual`
14268
14345
  */
14269
14346
  const ATMOSPHERE_GLYPHS = ['.', ':', "'", '`'];
14347
+ /**
14348
+ * Coordinate space the octopus layout is generated in when it is painted into a terminal.
14349
+ *
14350
+ * The terminal renderer has its own character grid, so the geometry only needs one stable
14351
+ * square coordinate space which the grid is then sampled from.
14352
+ *
14353
+ * @private helper of `asciiOctopusAvatarVisual`
14354
+ */
14355
+ const TERMINAL_ASCII_OCTOPUS_LAYOUT_SIZE = DEFAULT_AVATAR_SIZE;
14270
14356
  /**
14271
14357
  * AsciiOctopus avatar visual.
14272
14358
  *
@@ -14283,41 +14369,115 @@ const asciiOctopusAvatarVisual = {
14283
14369
  const staticRandom = createRandom('ascii-octopus-static');
14284
14370
  const gridMetrics = createAsciiGridMetrics(size, gridRandom);
14285
14371
  const layout = createAsciiOctopusLayout(size, timeMs, createRandom, staticRandom, interaction);
14372
+ const glyphGrid = createAsciiOctopusGlyphGrid({
14373
+ sampleGrid: gridMetrics,
14374
+ layout,
14375
+ palette,
14376
+ cellRandom: createRandom('ascii-octopus-cells'),
14377
+ timeMs,
14378
+ });
14286
14379
  drawAvatarFrame(context, size, palette);
14287
14380
  drawAsciiBackdrop(context, size, palette, layout, timeMs);
14288
14381
  context.save();
14289
14382
  context.font = `600 ${gridMetrics.fontSize}px monospace`;
14290
14383
  context.textAlign = 'center';
14291
14384
  context.textBaseline = 'middle';
14292
- // The ASCII renderer samples the morphing octopus field on a low-resolution grid so the shape stays organic
14293
- // while the glyph layout remains deterministic for the same avatar input.
14294
- const cellRandom = createRandom('ascii-octopus-cells');
14295
14385
  for (let rowIndex = 0; rowIndex < gridMetrics.rowCount; rowIndex++) {
14296
14386
  for (let columnIndex = 0; columnIndex < gridMetrics.columnCount; columnIndex++) {
14297
- const point = {
14298
- x: gridMetrics.offsetX + columnIndex * gridMetrics.cellWidth,
14299
- y: gridMetrics.offsetY + rowIndex * gridMetrics.cellHeight,
14300
- };
14301
- const noise = cellRandom();
14302
- const glyphDescriptor = resolveAsciiGlyph({
14303
- point,
14304
- layout,
14305
- palette,
14306
- cellWidth: gridMetrics.cellWidth,
14307
- cellHeight: gridMetrics.cellHeight,
14308
- noise,
14309
- timeMs,
14310
- });
14387
+ const glyphDescriptor = glyphGrid[rowIndex][columnIndex];
14311
14388
  if (!glyphDescriptor) {
14312
14389
  continue;
14313
14390
  }
14391
+ const point = resolveAsciiSampleGridPoint(gridMetrics, columnIndex, rowIndex);
14314
14392
  context.fillStyle = glyphDescriptor.color;
14315
14393
  context.fillText(glyphDescriptor.character, point.x, point.y);
14316
14394
  }
14317
14395
  }
14318
14396
  context.restore();
14319
14397
  },
14398
+ renderTerminalText({ columns, rows, palette, createRandom, timeMs, interaction }) {
14399
+ const staticRandom = createRandom('ascii-octopus-static');
14400
+ const layout = createAsciiOctopusLayout(TERMINAL_ASCII_OCTOPUS_LAYOUT_SIZE, timeMs, createRandom, staticRandom, interaction);
14401
+ return createAsciiOctopusGlyphGrid({
14402
+ sampleGrid: createAsciiTerminalSampleGrid(columns, rows),
14403
+ layout,
14404
+ palette,
14405
+ cellRandom: createRandom('ascii-octopus-cells'),
14406
+ timeMs,
14407
+ });
14408
+ },
14320
14409
  };
14410
+ /**
14411
+ * Resolves the geometry point sampled for one cell of the grid.
14412
+ *
14413
+ * @param sampleGrid Character-cell sampling grid.
14414
+ * @param columnIndex Zero-based cell column.
14415
+ * @param rowIndex Zero-based cell row.
14416
+ * @returns Sampled point in the octopus coordinate space.
14417
+ *
14418
+ * @private helper of `asciiOctopusAvatarVisual`
14419
+ */
14420
+ function resolveAsciiSampleGridPoint(sampleGrid, columnIndex, rowIndex) {
14421
+ return {
14422
+ x: sampleGrid.offsetX + columnIndex * sampleGrid.cellWidth,
14423
+ y: sampleGrid.offsetY + rowIndex * sampleGrid.cellHeight,
14424
+ };
14425
+ }
14426
+ /**
14427
+ * Builds the sampling grid used when the octopus is painted straight into terminal character cells.
14428
+ *
14429
+ * @param columns Available terminal columns.
14430
+ * @param rows Available terminal rows.
14431
+ * @returns Character-cell sampling grid covering the whole octopus coordinate space.
14432
+ *
14433
+ * @private helper of `asciiOctopusAvatarVisual`
14434
+ */
14435
+ function createAsciiTerminalSampleGrid(columns, rows) {
14436
+ const cellWidth = TERMINAL_ASCII_OCTOPUS_LAYOUT_SIZE / columns;
14437
+ const cellHeight = TERMINAL_ASCII_OCTOPUS_LAYOUT_SIZE / rows;
14438
+ return {
14439
+ cellWidth,
14440
+ cellHeight,
14441
+ columnCount: columns,
14442
+ rowCount: rows,
14443
+ offsetX: cellWidth / 2,
14444
+ offsetY: cellHeight / 2,
14445
+ };
14446
+ }
14447
+ /**
14448
+ * Samples the morphing octopus field into one deterministic grid of ASCII glyphs.
14449
+ *
14450
+ * The field is sampled on a low-resolution grid so the shape stays organic while the glyph
14451
+ * layout remains deterministic for the same avatar input. Both the canvas visual and the
14452
+ * terminal visual share this single sampling pass so they always describe the same octopus.
14453
+ *
14454
+ * @param options Sampling grid, prepared octopus layout, palette, per-cell noise, and animation time.
14455
+ * @returns Resolved glyph of every sampled cell, where `null` means an empty cell.
14456
+ *
14457
+ * @private helper of `asciiOctopusAvatarVisual`
14458
+ */
14459
+ function createAsciiOctopusGlyphGrid(options) {
14460
+ const { sampleGrid, layout, palette, cellRandom, timeMs } = options;
14461
+ const glyphGrid = [];
14462
+ for (let rowIndex = 0; rowIndex < sampleGrid.rowCount; rowIndex++) {
14463
+ const glyphRow = [];
14464
+ for (let columnIndex = 0; columnIndex < sampleGrid.columnCount; columnIndex++) {
14465
+ const point = resolveAsciiSampleGridPoint(sampleGrid, columnIndex, rowIndex);
14466
+ const noise = cellRandom();
14467
+ glyphRow.push(resolveAsciiGlyph({
14468
+ point,
14469
+ layout,
14470
+ palette,
14471
+ cellWidth: sampleGrid.cellWidth,
14472
+ cellHeight: sampleGrid.cellHeight,
14473
+ noise,
14474
+ timeMs,
14475
+ }));
14476
+ }
14477
+ glyphGrid.push(glyphRow);
14478
+ }
14479
+ return glyphGrid;
14480
+ }
14321
14481
  /**
14322
14482
  * Draws the dark terminal-like glow behind the ASCII octopus.
14323
14483
  *
@@ -29380,28 +29540,28 @@ function $getCurrentDate() {
29380
29540
  */
29381
29541
  function buildToolInvocationScript(options) {
29382
29542
  const { functionName, functionArgsExpression } = options;
29383
- return `
29384
- const args = ${functionArgsExpression};
29385
- const runtimeContextRaw =
29386
- typeof ${TOOL_RUNTIME_CONTEXT_PARAMETER} === 'undefined'
29387
- ? undefined
29388
- : ${TOOL_RUNTIME_CONTEXT_PARAMETER};
29543
+ return spaceTrim$1((block) => `
29544
+ const args = ${block(functionArgsExpression)};
29545
+ const runtimeContextRaw =
29546
+ typeof ${TOOL_RUNTIME_CONTEXT_PARAMETER} === 'undefined'
29547
+ ? undefined
29548
+ : ${TOOL_RUNTIME_CONTEXT_PARAMETER};
29389
29549
 
29390
- if (runtimeContextRaw !== undefined && args && typeof args === 'object' && !Array.isArray(args)) {
29391
- args.${TOOL_RUNTIME_CONTEXT_ARGUMENT} = runtimeContextRaw;
29392
- }
29550
+ if (runtimeContextRaw !== undefined && args && typeof args === 'object' && !Array.isArray(args)) {
29551
+ args.${TOOL_RUNTIME_CONTEXT_ARGUMENT} = runtimeContextRaw;
29552
+ }
29393
29553
 
29394
- const toolProgressTokenRaw =
29395
- typeof ${TOOL_PROGRESS_TOKEN_PARAMETER} === 'undefined'
29396
- ? undefined
29397
- : ${TOOL_PROGRESS_TOKEN_PARAMETER};
29554
+ const toolProgressTokenRaw =
29555
+ typeof ${TOOL_PROGRESS_TOKEN_PARAMETER} === 'undefined'
29556
+ ? undefined
29557
+ : ${TOOL_PROGRESS_TOKEN_PARAMETER};
29398
29558
 
29399
- if (toolProgressTokenRaw !== undefined && args && typeof args === 'object' && !Array.isArray(args)) {
29400
- args.${TOOL_PROGRESS_TOKEN_ARGUMENT} = toolProgressTokenRaw;
29401
- }
29559
+ if (toolProgressTokenRaw !== undefined && args && typeof args === 'object' && !Array.isArray(args)) {
29560
+ args.${TOOL_PROGRESS_TOKEN_ARGUMENT} = toolProgressTokenRaw;
29561
+ }
29402
29562
 
29403
- return await ${functionName}(args);
29404
- `;
29563
+ return await ${functionName}(args);
29564
+ `);
29405
29565
  }
29406
29566
 
29407
29567
  /**
@@ -36242,8 +36402,8 @@ const formatCommandParser = {
36242
36402
  */
36243
36403
  $applyToTaskJson(command, $taskJson) {
36244
36404
  if ($taskJson.format !== undefined && command.format !== $taskJson.format) {
36245
- throw new ParseError(`Format format is already defined to "${$taskJson.format}".
36246
- Now you try to redefine it by "${command.format}"`);
36405
+ throw new ParseError(spaceTrim$1(`Format format is already defined to "${$taskJson.format}".
36406
+ Now you try to redefine it by "${command.format}"`));
36247
36407
  }
36248
36408
  $taskJson.format = command.format;
36249
36409
  },