@mcpher/gas-fakes 2.3.17 → 2.3.18

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/gf_agent/SKILL.md CHANGED
@@ -164,8 +164,9 @@ Agent:
164
164
 
165
165
 
166
166
  ### Google Sheets (SpreadsheetApp)
167
- - **Chart Creation & Ranges**: When using `EmbeddedChartBuilder.addRange()`, the Sheets API requires `ChartSourceRange` domains and series to have a length of 1 for either rows or columns.
168
- - **Crucial**: Do **not** pass a multi-column range to `addRange()`. Add domains and series as separate single-column ranges.
167
+ - **Efficiency & Batching (CRITICAL)**: Always prefer `range.setValues(array)` over making multiple individual `range.setValue(val)` calls. If you need to write multiple rows or columns of data to a sheet, batch them up into a 2D array and write them all at once. This significantly improves performance and avoids unnecessary API rate limits.
168
+ - **Chart Creation & Ranges**: While `gas-fakes` now emulates Live Apps Script behavior by automatically splitting multi-column ranges in `addRange()` (first column as domain, rest as series), for **maximum reliability** and clear control over your chart structure, it is still recommended to add domains and series as separate single-column ranges.
169
+ - *Example*: `chart.addRange(sheet.getRange("A2:A10")).addRange(sheet.getRange("B2:B10"))` is preferred over `chart.addRange(sheet.getRange("A2:B10"))`.
169
170
  - **Values vs. Display Values**:
170
171
  - `getValues()` returns unformatted data.
171
172
  - `getDisplayValues()` returns formatted strings.
@@ -409,7 +410,9 @@ Unlike the standard Apps Script Services (`SpreadsheetApp`, `DriveApp`), the sig
409
410
  If you are orchestrating a complex task that requires an Advanced Service (such as resizing an image via `Docs.Documents.batchUpdate` or applying granular formatting via `Sheets.Spreadsheets.batchUpdate`) and you do not know the exact JSON payload structure, you MUST research it using the Google API Discovery documents.
410
411
 
411
412
  **How to Research Advanced Services:**
412
- Do not guess the payload structure. Instead, use the `run_shell_command` tool to `curl` and `grep` the official Discovery Document for the specific API version.
413
+ You SHOULD FIRST use the `run_shell_command` tool to `curl` and `grep` the official Google API Discovery Document for the specific API version. This is the most reliable way to guarantee accurate, 100% current REST JSON schemas.
414
+
415
+ **Web Search Fallback**: Only if `curl`ing the Discovery API fails, or if it does not provide enough clarity to construct the request, you MAY use the `google_web_search` tool as a fallback default. Be cautious: web search often returns outdated or non-REST API examples (like Java or Python SDKs) which cause script failures.
413
416
 
414
417
  **Discovery Document URLs:**
415
418
  - **Docs API v1**: `https://docs.googleapis.com/$discovery/rest?version=v1`
@@ -423,6 +426,10 @@ If you need to know how to structure an `insertInlineImage` request for the Docs
423
426
  ```bash
424
427
  curl -s "https://docs.googleapis.com/$discovery/rest?version=v1" | grep -A 30 '"InsertInlineImageRequest":'
425
428
  ```
429
+ For `deleteObject` (e.g., deleting an image):
430
+ ```bash
431
+ curl -s "https://docs.googleapis.com/$discovery/rest?version=v1" | grep -A 20 '"DeleteObjectRequest":'
432
+ ```
426
433
 
427
434
  By fetching the exact schema from the discovery document, you ensure your `batchUpdate` arrays and payload objects are 100% accurate before generating the execution script.
428
435
 
@@ -441,6 +448,23 @@ When generating code that uses the `Utilities` service, you must adhere to the f
441
448
  - If you are writing tests or robust `try/catch` blocks intended to run cross-platform, DO NOT assert against the exact string value of the error message (like `e.message.includes("failed")`). Simply check that an exception was thrown.
442
449
 
443
450
 
451
+ ### Context Efficiency & Logging (CRITICAL)
452
+
453
+ To maintain a clean and professional user experience, `gf_agent` MUST prioritize context efficiency and minimize redundant tool logging.
454
+
455
+ 1. **Avoid Redundant Research**:
456
+ - Before calling `lookup_docs` or searching remote documentation, ALWAYS check the local `skills/` directory for the required service.
457
+ - If the method signatures are already known or simple, proceed to script generation without extra tool calls.
458
+ - DO NOT call `lookup_docs` for every service in every turn. Only call it when a specific method signature is unknown or when a script fails with a "not a function" error.
459
+
460
+ 2. **Minimize Output Verbosity**:
461
+ - When reporting the results of research to the user, DO NOT print long lists of method names found in documentation. Summarize only the relevant findings.
462
+ - The user does not need to see the "raw" output of discovery tools.
463
+
464
+ 3. **Quiet Execution**:
465
+ - Aim for a "one-shot" success pattern. Use the gathered knowledge to write a robust script that works on the first try, avoiding the "Retry/Correction" cycle which generates excessive terminal logs.
466
+
467
+
444
468
  # gf_agent Knowledge Base
445
469
 
446
470
  This directory contains modular markdown files representing the "Lessons Learned & Best Practices" for the `gf_agent` skill.
@@ -1,6 +1,7 @@
1
1
  ### Google Sheets (SpreadsheetApp)
2
- - **Chart Creation & Ranges**: When using `EmbeddedChartBuilder.addRange()`, the Sheets API requires `ChartSourceRange` domains and series to have a length of 1 for either rows or columns.
3
- - **Crucial**: Do **not** pass a multi-column range to `addRange()`. Add domains and series as separate single-column ranges.
2
+ - **Efficiency & Batching (CRITICAL)**: Always prefer `range.setValues(array)` over making multiple individual `range.setValue(val)` calls. If you need to write multiple rows or columns of data to a sheet, batch them up into a 2D array and write them all at once. This significantly improves performance and avoids unnecessary API rate limits.
3
+ - **Chart Creation & Ranges**: While `gas-fakes` now emulates Live Apps Script behavior by automatically splitting multi-column ranges in `addRange()` (first column as domain, rest as series), for **maximum reliability** and clear control over your chart structure, it is still recommended to add domains and series as separate single-column ranges.
4
+ - *Example*: `chart.addRange(sheet.getRange("A2:A10")).addRange(sheet.getRange("B2:B10"))` is preferred over `chart.addRange(sheet.getRange("A2:B10"))`.
4
5
  - **Values vs. Display Values**:
5
6
  - `getValues()` returns unformatted data.
6
7
  - `getDisplayValues()` returns formatted strings.
@@ -5,7 +5,9 @@ Unlike the standard Apps Script Services (`SpreadsheetApp`, `DriveApp`), the sig
5
5
  If you are orchestrating a complex task that requires an Advanced Service (such as resizing an image via `Docs.Documents.batchUpdate` or applying granular formatting via `Sheets.Spreadsheets.batchUpdate`) and you do not know the exact JSON payload structure, you MUST research it using the Google API Discovery documents.
6
6
 
7
7
  **How to Research Advanced Services:**
8
- Do not guess the payload structure. Instead, use the `run_shell_command` tool to `curl` and `grep` the official Discovery Document for the specific API version.
8
+ You SHOULD FIRST use the `run_shell_command` tool to `curl` and `grep` the official Google API Discovery Document for the specific API version. This is the most reliable way to guarantee accurate, 100% current REST JSON schemas.
9
+
10
+ **Web Search Fallback**: Only if `curl`ing the Discovery API fails, or if it does not provide enough clarity to construct the request, you MAY use the `google_web_search` tool as a fallback default. Be cautious: web search often returns outdated or non-REST API examples (like Java or Python SDKs) which cause script failures.
9
11
 
10
12
  **Discovery Document URLs:**
11
13
  - **Docs API v1**: `https://docs.googleapis.com/$discovery/rest?version=v1`
@@ -19,5 +21,9 @@ If you need to know how to structure an `insertInlineImage` request for the Docs
19
21
  ```bash
20
22
  curl -s "https://docs.googleapis.com/$discovery/rest?version=v1" | grep -A 30 '"InsertInlineImageRequest":'
21
23
  ```
24
+ For `deleteObject` (e.g., deleting an image):
25
+ ```bash
26
+ curl -s "https://docs.googleapis.com/$discovery/rest?version=v1" | grep -A 20 '"DeleteObjectRequest":'
27
+ ```
22
28
 
23
29
  By fetching the exact schema from the discovery document, you ensure your `batchUpdate` arrays and payload objects are 100% accurate before generating the execution script.
@@ -0,0 +1,15 @@
1
+ ### Context Efficiency & Logging (CRITICAL)
2
+
3
+ To maintain a clean and professional user experience, `gf_agent` MUST prioritize context efficiency and minimize redundant tool logging.
4
+
5
+ 1. **Avoid Redundant Research**:
6
+ - Before calling `lookup_docs` or searching remote documentation, ALWAYS check the local `skills/` directory for the required service.
7
+ - If the method signatures are already known or simple, proceed to script generation without extra tool calls.
8
+ - DO NOT call `lookup_docs` for every service in every turn. Only call it when a specific method signature is unknown or when a script fails with a "not a function" error.
9
+
10
+ 2. **Minimize Output Verbosity**:
11
+ - When reporting the results of research to the user, DO NOT print long lists of method names found in documentation. Summarize only the relevant findings.
12
+ - The user does not need to see the "raw" output of discovery tools.
13
+
14
+ 3. **Quiet Execution**:
15
+ - Aim for a "one-shot" success pattern. Use the gathered knowledge to write a robust script that works on the first try, avoiding the "Retry/Correction" cycle which generates excessive terminal logs.
package/package.json CHANGED
@@ -40,7 +40,7 @@
40
40
  },
41
41
  "name": "@mcpher/gas-fakes",
42
42
  "author": "bruce mcpherson",
43
- "version": "2.3.17",
43
+ "version": "2.3.18",
44
44
  "license": "MIT",
45
45
  "main": "main.js",
46
46
  "description": "An implementation of the Google Workspace Apps Script runtime: Run native App Script Code on Node and Cloud Run",
@@ -59,15 +59,40 @@ export class FakeEmbeddedChartBuilder {
59
59
  if (nargs !== 1) matchThrow();
60
60
 
61
61
  const gridRange = makeSheetsGridRange(range);
62
+ const startCol = gridRange.startColumnIndex || 0;
63
+ const endCol = gridRange.endColumnIndex || startCol + 1;
64
+ const numCols = endCol - startCol;
62
65
 
63
- if (this.__apiChart.spec.basicChart.domains.length === 0) {
66
+ // If it's a multi-column range, live GAS splits the first column as domain
67
+ // and the rest as series (unless it's already got a domain)
68
+ if (numCols > 1 && this.__apiChart.spec.basicChart.domains.length === 0) {
69
+ // First column is domain
70
+ const domainRange = JSON.parse(JSON.stringify(gridRange));
71
+ domainRange.endColumnIndex = startCol + 1;
64
72
  this.__apiChart.spec.basicChart.domains.push({
65
- domain: { sourceRange: { sources: [gridRange] } },
73
+ domain: { sourceRange: { sources: [domainRange] } },
66
74
  });
75
+
76
+ // Rest are series
77
+ for (let i = 1; i < numCols; i++) {
78
+ const seriesRange = JSON.parse(JSON.stringify(gridRange));
79
+ seriesRange.startColumnIndex = startCol + i;
80
+ seriesRange.endColumnIndex = startCol + i + 1;
81
+ this.__apiChart.spec.basicChart.series.push({
82
+ series: { sourceRange: { sources: [seriesRange] } },
83
+ });
84
+ }
67
85
  } else {
68
- this.__apiChart.spec.basicChart.series.push({
69
- series: { sourceRange: { sources: [gridRange] } },
70
- });
86
+ // Standard behavior
87
+ if (this.__apiChart.spec.basicChart.domains.length === 0) {
88
+ this.__apiChart.spec.basicChart.domains.push({
89
+ domain: { sourceRange: { sources: [gridRange] } },
90
+ });
91
+ } else {
92
+ this.__apiChart.spec.basicChart.series.push({
93
+ series: { sourceRange: { sources: [gridRange] } },
94
+ });
95
+ }
71
96
  }
72
97
  return this;
73
98
  }