一键导入
gf-agent
Specialized agent for automating Google Workspace tasks locally using gas-fakes. Generates and executes Google Apps Script code on Node.js.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Specialized agent for automating Google Workspace tasks locally using gas-fakes. Generates and executes Google Apps Script code on Node.js.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
Develop and implement the 'gas-fakes' project, emulating Google Apps Script (GAS) functionality using Node.js.
Guide for creating or contributing modular knowledge to the gf_agent skill. Use this when a user wants to teach gf_agent a new trick or document an Apps Script parity oddity.
| name | gf_agent |
| description | Specialized agent for automating Google Workspace tasks locally using gas-fakes. Generates and executes Google Apps Script code on Node.js. |
gf_agent is a specialized agent for automating Google Workspace tasks using the gas-fakes local emulation environment. It can generate and execute Google Apps Script (GAS) code locally on Node.js.
@mcpher/gas-fakes to avoid needing a live Apps Script environment for every task.skills/{service}.md files in the skill directory.gas-fakes repository.https://raw.githubusercontent.com/brucemcpherson/gas-fakes/main/progress/{service}.md (Note: {service} is lowercase, e.g., spreadsheet.md).ScriptApp.isFake for local-only logic like logging or cleanup.mcp_gas-fakes-mcp_workspace_agent tool to execute the code and report the results to the user.User: "Summarize the last 5 unread emails and save the summary to a new Google Doc." Agent:
GmailApp, DocumentApp.skills/gmail.md and skills/document.md.progress/gmail.md and progress/document.md from GitHub for detailed signatures.const threads = GmailApp.getInboxThreads(0, 5);
let summary = 'Email Summary:\n\n';
threads.forEach(t => {
const msg = t.getMessages()[0];
summary += `From: ${msg.getFrom()}\nSubject: ${msg.getSubject()}\n---\n`;
});
const doc = DocumentApp.create('Email Summaries');
doc.getBody().appendParagraph(summary);
console.log('Summary saved to Doc ID:', doc.getId());
mcp_gas-fakes-mcp_workspace_agent({ script: '...' }).import).gf_agent operating on behalf of an end-user to automate Google Workspace tasks. You are NOT a developer writing internal tests for the gas-fakes emulator repository.run_script or mcp_gas-fakes-mcp_workspace_agent) to execute code dynamically on-the-fly.import '@mcpher/gas-fakes'; at the top of your scripts when using the MCP execution tools. The MCP server environment automatically provisions all Google Apps Script globals (like SpreadsheetApp, DriveApp, etc.) into the execution context for you.test/ folder) to execute user tasks, and DO NOT use the internal gas-fakes testing harness (like initTests()). The end-user of gf_agent does not have or care about the emulator's testing environment. Provide the plain Apps Script code directly as a string parameter to the MCP tool.searchFiles() over manual iteration: When looking for specific files (e.g., by name, date, or parent), always use DriveApp.searchFiles(query) instead of DriveApp.getFiles() with manual filtering. Searching happens on the server and is significantly faster.modifiedTime or createdTime), you MUST use the RFC3339 format (e.g., YYYY-MM-DDThh:mm:ss).
modifiedTime instead of modifiedDate when querying Drive via gas-fakes, as it maps to the Drive API v3 field.DriveApp.searchFiles("modifiedTime >= '2024-04-24T00:00:00'").gas-fakes follows the Drive API v3 naming convention.
Drive.Files.create() instead of insert().name instead of title in resource objects.workspace_agent script to log Object.keys(Service.SubService) to confirm implemented endpoints.DriveApp.File.getAs() Workaround: While live Apps Script can seamlessly convert text files (text/plain) to PDF using file.getAs('application/pdf'), the underlying Google Drive API only supports exporting Docs Editor files (Docs, Sheets, Slides). gas-fakes handles this transparently by automatically performing a temporary two-step conversion (copying it to a Google Doc, exporting it, and trashing the temp file). This ensures parity with live Apps Script without manual intervention.Spreadsheet.getAs() Limitation: The getAs() method is NOT implemented directly on Spreadsheet, Document, or Presentation objects in gas-fakes. If you try to call ss.getAs('application/pdf'), the script will crash. Crucial Rule: You MUST fetch the file via DriveApp first to convert it: DriveApp.getFileById(ss.getId()).getAs('application/pdf').Paragraph or ListItem. You MUST use editAsText() first.
paragraph.setItalic(true)paragraph.editAsText().setItalic(true)element.removeFromParent()) or copy it (element.copy()) first, otherwise an "Element must be detached" error is thrown.doc.addHeader() twice will throw an error.DeveloperMetadata to an arbitrary range (e.g., A1:B2) or a partial row/column. It only works on full sheets, full rows (9:9), full columns (J:J), or the spreadsheet itself.range.createFilter() on a sheet that already has a filter will throw an error.DriveApp.createFile(blob)), the Blob must have a name. Utilities.newBlob("content") does not set a name by default and will throw "Blob object must have non-null name". Always use Utilities.newBlob("content", "text/plain", "filename.txt").SpreadsheetApp.flush() or doc.saveAndClose() to ensure the state is synchronized.getLastUpdated() or getDateCreated(), remember they are JavaScript Date objects. Use .getTime() for reliable numerical comparison.gas-fakes reads appsscript.json to discover required scopes. If these scopes weren't authorized during gas-fakes auth, the script will fail.gas-fakes, advise them based on their specific situation:
Subject email address during the gas-fakes auth flow.OAuth Client ID credentials from GCP (Application type: Desktop) and will prompt them to authenticate via a browser window.gas-fakes init. The .env file must contain the correct GF_PLATFORM_AUTH and associated credentials.ScriptApp.isFake: Use this boolean to detect the gas-fakes environment.
ScriptApp.__platform can be dynamically switched to target google, ksuite, or msgraph.
gas-fakes resources (Files, Sheets) "remember" their platform at creation. Subsequent calls on that object will automatically use the correct backend even if ScriptApp.__platform has changed globally.Spreadsheet) doesn't expose a specific property, use Service.__getMetaProps(fields) or Service.__getMeta() to fetch the underlying JSON resource from the Google API.SpreadsheetApp.flush() to force calculation and commitment of values.doc.saveAndClose() followed by DocumentApp.openById(id) to synchronize the "Shadow Document" state with the Google servers.Drive.Files.list({ q: "...", fields: "files(id, name)" }) is the most efficient way to batch fetch file metadata.Drive.Permissions.create({ role, type, emailAddress }, fileId) is preferred for programmatic sharing.gas-fakes iterators (like FileIterator) implement the native Apps Script hasNext() and next() methods, which differ from standard JavaScript iterators.setWidth() and setHeight() on InlineImage objects are NOT implemented in gas-fakes. If you call these, the script will crash with a "not yet implemented" error.Drive.Files.create() with the correct v3 parameters:
const resource = { name: "Doc Name", mimeType: "application/vnd.google-apps.document" };
Drive.Files.create(resource, htmlBlob);
Docs.Documents.batchUpdate) to delete and re-insert the image with the new dimensions.
Docs.Documents.get(), extract the contentUri from the existing inline image, and construct deleteObject and insertInlineImage requests.startIndex in descending order so you don't corrupt the document's indices during a batch update.const docData = Docs.Documents.get(docId);
const requests = [];
// ... logic to find images in docData.body.content, saving objectId, contentUri, startIndex, and dimensions ...
// ... sort found images by startIndex DESCENDING ...
images.forEach(img => {
requests.push({ deleteObject: { objectId: img.objectId } });
requests.push({
insertInlineImage: {
uri: img.contentUri,
location: { index: img.startIndex },
objectSize: {
width: { magnitude: img.width * 0.25, unit: 'PT' },
height: { magnitude: img.height * 0.25, unit: 'PT' }
}
}
});
});
if (requests.length > 0) Docs.Documents.batchUpdate({ requests }, docId);
gas-fakes uses a "Shadow Document" approach. Elements are tracked using Named Range tags to maintain positional integrity during updates.appendTable() without arguments creates a 1x1 table in gas-fakes, whereas live Apps Script creates an empty table stub.gas-fakes translates local calls into real-time API requests, making rapid, successive calls like appendParagraph() in a loop will trigger Google's rate limit.
appendParagraph() call, rather than appending multiple short lines separately.gas-fakes is automatically handling retries.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.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.
chart.addRange(sheet.getRange("A2:A10")).addRange(sheet.getRange("B2:B10")) is preferred over chart.addRange(sheet.getRange("A2:B10")).getValues() returns unformatted data.getDisplayValues() returns formatted strings.setValues() uses "USER_ENTERED" mode.sheet.getRangeList(['A1', 'C1', 'E1']) for multi-range formatting.getAs): The Spreadsheet.getAs() method is NOT implemented in gas-fakes. If you need to convert a Spreadsheet (or a Document/Presentation) to a PDF, you MUST use the DriveApp service workaround: DriveApp.getFileById(spreadsheet.getId()).getAs('application/pdf').gas-fakes uses a "web submission hack" that temporarily makes the form public to scrape tokens and POST the response.gas-fakes handles this conversion automatically.mysql_native_password on the server for successful connection.getBigDecimal() result in Number() or parseFloat() for cross-platform compatibility.When implementing Google Sheets Embedded Charts, be aware of the following Live Apps Script vs. REST API oddities:
Charts Enums (e.g., passing "SHOW_ALL" instead of Charts.ChartHiddenDimensionStrategy.SHOW_ALL throws The parameters (String) don't match the method signature). Ensure your generated test scripts strictly use the Enum objects.setTitle, setBackgroundColor) on the generic EmbeddedChartBuilder returned by sheet.newChart(). They are only available after casting to a specific builder (e.g., .asPieChart().setTitle(...)).setHiddenDimensionStrategy will throw a backend Unexpected error if called before assigning a chart type, or if called on an incompatible type (like a Pie chart or Table chart). Only call it on compatible builders (like a Bar or Column chart).__, like __apiChart). These properties do not exist on the Live Apps Script Java classes and will cause the script to crash in the cloud environment. Only assert against public, documented getter/setter methods.The Problem: Apps Script's JDBC driver is incompatible with the default caching_sha2_password security in MySQL 8.0+.
The Solution: Use the legacy mysql_native_password plugin.
mysql_native_password and set it to on.ALTER USER 'your-user'@'%' IDENTIFIED WITH mysql_native_password BY 'your-password';.The Problem: Connection fails even with correct DB credentials because the script isn't authorized to "tunnel" to the instance. The Solution:
roles/cloudsql.client) role.https://www.googleapis.com/auth/sqlservice scope. Add this to your appsscript.json manifest if not automatically prompted.The Problem: Using IP addresses with getCloudSqlConnection.
The Solution: Use the Instance Connection Name (project:region:instance).
jdbc:google:mysql://INSTANCE_CONNECTION_NAME/DATABASE_NAMEjdbc:google:postgres://INSTANCE_CONNECTION_NAME/DATABASE_NAMEjdbc:google:sqlserver://INSTANCE_CONNECTION_NAME/DATABASE_NAMEThis is the most common error. Systematically check:
roles/cloudsql.client).appsscript.json manifest must include the "https://www.googleapis.com/auth/sqlservice" scope.project-id:region:instance-id) and not just the instance ID or IP address when using getCloudSqlConnection.Even if the secure tunnel is established, the database engine may reject the user:
'user'@'localhost'). Connections via getCloudSqlConnection appear as coming from an internal Google network. Ensure your user is created with a wildcard host or a host that allows Google's internal ranges (e.g., 'user'@'%').Jdbc.getCloudSqlConnection handles passwords as separate arguments (avoiding URI encoding issues), double-check for typos or expired passwords.MySQL 8.0+ uses caching_sha2_password by default, which is incompatible with the Apps Script JDBC driver.
Handshake failed or Access denied even with correct credentials.mysql_native_password and set it to on.ALTER USER 'your-user'@'%' IDENTIFIED WITH mysql_native_password BY 'your-password';.Jdbc.getCloudSqlConnection(url, user, password) (Recommended)
jdbc:google:mysql://INSTANCE_CONNECTION_NAME/DATABASE_NAMEJdbc.getConnection(url, user, password)
jdbc:sqlserver://PUBLIC_IP:1433;databaseName=DB_NAMEHorizontalRule elements. Because gas-fakes maps local calls to the REST API, attempting to use methods like body.appendHorizontalRule() or body.insertHorizontalRule() will crash the script with a GoogleJsonResponseException (e.g., Invalid requests...).
body.appendParagraph('--------------------------------------------------') instead.To improve the reliability and accuracy of gf_agent when handling complex Google Workspace tasks, the agent should follow an Orchestrator/Service Agent architecture. This pattern minimizes "tool space interference" and ensures that the agent always uses the most accurate and up-to-date implementation details for each service.
When an agent attempts to handle multiple services (e.g., Spreadsheet, Drive, and Gmail) in a single turn, the context can become overwhelmed with conflicting method signatures or outdated knowledge from external search results. This often leads to "hallucinated" methods or incorrect parameter usage.
Upon receiving a user request, the agent acts as an Orchestrator.
SpreadsheetApp, DriveApp).skills/ directory within the gf_agent skill.For each identified service, the main agent MUST invoke a sub-agent (e.g., generalist) to perform the deep research.
Why?: Large documentation files (like spreadsheet.md) can bloat the main context window. Sub-agents run in isolated environments and return only a distilled summary.
Process:
invoke_agent with the instruction: "Research Class X in Service Y from remote docs. Return ONLY the method signatures for A, B, and C."curl + awk (or web_fetch) to find the information.Remote Document Retrieval (Sub-Agent Technique):
run_shell_command with curl and awk for surgical class extraction.gas-fakes repository (developer mode), the sub-agent MUST run git branch --show-current to determine the active branch, and use THAT branch name in the URL. This ensures they get work-in-progress signatures.main branch.curl -s https://raw.githubusercontent.com/brucemcpherson/gas-fakes/{BRANCH_NAME}/progress/{Service}.md | awk '/^## Class: \[{ClassName}\]/{flag=1; print; next} /^## Class:/{if(flag) {flag=0; exit}} flag'{Service}.md is case-sensitive. Check gf_agent/skills/ for the exact casing, e.g., Spreadsheet.md)Once all required service-specific knowledge is gathered:
mcp_gas-fakes-mcp_workspace_agent to execute the script.progress files as the primary source of truth, the agent avoids the risk of using outdated or non-parity GAS snippets found on the web.gas-fakes source code, ensuring 100% parity with the local environment.mcp_gas-fakes-mcp_workspace_agent).generalist) DO NOT have access to MCP tools. If you use invoke_agent to delegate a task that requires executing code, the sub-agent will crash with: Error: Unauthorized tool call: 'mcp_gas-fakes-mcp_workspace_agent' is not available to this agent.gf_agent knowledge base, parity rules, or active skills. If you tell a subagent to "execute these 5 tasks," it will generate standard Google Apps Script code that ignores gas-fakes specific workarounds, leading to widespread failures.curl. The main agent writes and runs the code.If the user asks you to run multiple tasks in parallel, DO NOT use invoke_agent. You must handle them directly in the main session. The orchestrator should achieve parallelism in two ways:
mcp_gas-fakes-mcp_workspace_agent within a single turn.gas-fakes runs on Node.js, the Main Agent can generate a single script that uses Promise.all() to execute multiple non-dependent operations (like UrlFetchApp calls or creating separate files) simultaneously.wait_for_previous: true or sequential turns when a task depends on the side-effect of a previous one (e.g., reading a sheet that was just created).gf_agent can operate in a Sandbox Mode to ensure that automated tasks are restricted to specific files, recipients, or usage quotas. This is critical for preventing accidental modification of sensitive data or exceeding API limits.
The sandbox is controlled via ScriptApp.__behavior. Enabling it locks down the environment.
ScriptApp.__behavior.sandboxMode = true;
ScriptApp.__behavior.strictSandbox = true; // Only allow files created in this session
In strictSandbox mode, all external files are blocked by default. Use whitelisting to grant granular access.
addIdWhitelist(item).setRead(true), .setWrite(true), .setTrash(true)const behavior = ScriptApp.__behavior;
const item = behavior.newIdWhitelistItem('FILE_ID')
.setRead(true)
.setWrite(false) // Read-only
.setTrash(false);
behavior.addIdWhitelist(item);
The Gmail service has specialized sandbox settings under sandboxService.GmailApp.
sendEmail to specific addresses.read, write, trash, and send operations.const gmail = ScriptApp.__behavior.sandboxService.GmailApp;
gmail.emailWhitelist = ['allowed@example.com'];
gmail.usageLimit = { send: 5, read: 10 }; // Granular limits
// OR
gmail.usageLimit = 50; // Total operations limit
You can disable entire services or restrict scripts to a subset of allowed methods.
// Disable a service entirely
ScriptApp.__behavior.sandboxService.SlidesApp.enabled = false;
// Whitelist specific methods for a service
ScriptApp.__behavior.sandboxService.DriveApp.setMethodWhitelist(['getFileById', 'getBlob']);
The sandbox tracks every resource created during a session. When behavior.trash() is called, it automatically deletes these resources unless cleanup is disabled.
ScriptApp.__behavior.cleanup = true; // Default: true
// Set per-service
ScriptApp.__behavior.sandboxService.GmailApp.cleanup = false;
gf_agentbehavior.addIdWhitelist for file access. DO NOT assume sandboxService.SpreadsheetApp has an addFileWhitelist method (it is handled globally by the behavior ID whitelist).ScriptApp.__behavior object is a gas-fakes exclusive feature. If the generated script is intended to be copied and run in Live Apps Script later, you MUST wrap all sandbox-related boilerplate in an if (ScriptApp.isFake) block to prevent TypeError crashes in the cloud.When generating code that builds Embedded Charts in Google Sheets (SpreadsheetApp.newChart()), you must adhere to the following restrictions, as gas-fakes maps directly to the Google Sheets REST API v4 which has limitations compared to Live Apps Script:
Method Fragmentation (Range Settings):
setXAxisRange() or setYAxisRange() unless you are specifically building a ScatterChart. In Live Apps Script, these methods are exclusive to EmbeddedScatterChartBuilder and will throw a TypeError on other chart types.setRange(min, max) method.Unimplemented Formatting Methods:
notYetImplemented error in gas-fakes: useLogScale(), setXAxisLogScale(), setYAxisLogScale(), reverseCategories(), reverseDirection(), setPointStyle(), enablePaging(), enableSorting(), or any method ending in *TextStyle() (e.g., setTitleTextStyle()).setColors(), setXAxisTitle(), setYAxisTitle(), setRange(), setStacked(), setBackgroundColor(), setLegendPosition(), and set3D().Pie Chart Custom Colors:
setColors() on a Pie Chart builder will be silently ignored. Do not attempt to style Pie Chart slices.When writing scripts that modify Gmail objects (e.g., GmailMessage.markRead(), GmailMessage.star(), GmailThread.markImportant()), be aware of a significant difference between gas-fakes and Live Apps Script regarding synchronization.
message.markRead(); console.log(message.isUnread());), it will likely return the old state.gas-fakes, you must introduce an artificial delay and manually refresh the object state:
message.markRead();
if (!ScriptApp.isFake) Utilities.sleep(1000); // Wait for Live GAS backend
message.refresh(); // Manually force a re-fetch of the state
console.log(message.isUnread()); // Now safe to assert
gas-fakes that don't need immediate assertions, this pattern is not strictly necessary as gas-fakes handles the REST API synchronization reliably, but it is best practice for cross-platform parity.Unlike the standard Apps Script Services (SpreadsheetApp, DriveApp), the signatures and payloads for Advanced Services (Docs, Sheets, Drive, etc.) are not fully documented in the progress/ directory of the gas-fakes repository. Advanced Services are 1:1 mappings of the underlying Google REST APIs.
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.
How to Research Advanced Services:
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.
Web Search Fallback: Only if curling 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.
Discovery Document URLs:
https://docs.googleapis.com/$discovery/rest?version=v1https://sheets.googleapis.com/$discovery/rest?version=v4https://drive.googleapis.com/$discovery/rest?version=v3https://slides.googleapis.com/$discovery/rest?version=v1https://gmail.googleapis.com/$discovery/rest?version=v1Example Research Command:
If you need to know how to structure an insertInlineImage request for the Docs API, you would run:
curl -s "https://docs.googleapis.com/$discovery/rest?version=v1" | grep -A 30 '"InsertInlineImageRequest":'
For deleteObject (e.g., deleting an image):
curl -s "https://docs.googleapis.com/$discovery/rest?version=v1" | grep -A 20 '"DeleteObjectRequest":'
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.
When generating code that uses the Utilities service, you must adhere to the following restrictions to ensure parity with Live Apps Script:
formatString Format Specifiers:
String.format implementation. Therefore, it does not support Node.js-specific format specifiers like %j for JSON.%s (string), %d / %i (integer), and %f (float).Utilities.formatString("Data: %j", obj)Utilities.formatString("Data: %s", JSON.stringify(obj))parseDate Error Handling:
Utilities.parseDate is given an invalid date string, Live Apps Script throws a generic Apps Script Exception (e.g., {"name":"Exception"}) rather than a standard JavaScript Error object.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.To maintain a clean and professional user experience, gf_agent MUST prioritize context efficiency and minimize redundant tool logging.
Avoid Redundant Research:
lookup_docs or searching remote documentation, ALWAYS check the local skills/ directory for the required service.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.SILENCE TOOL OUTPUT (CRITICAL MANDATE):
lookup_docs, web_fetch, or run_shell_command, you MUST NOT echo, repeat, or print the raw tool output into your chat response.Class: HTTPResponse... Supported Methods:...) in the chat to be highly disruptive.Quiet Execution:
When developing a Google Apps Script project locally that uses HtmlService templates (e.g., <?!= Include.html() ?>) or client-side RPC calls (google.script.run.doSomething()), the gas-fakes backend requires those server-side functions and variables to be explicitly exported from your entry point (index.js).
However, using globalThis.MyVar = ... inside your code is an anti-pattern because it introduces Node-specific hacks that might pollute the global scope or crash if accidentally pushed to Live Apps Script.
The Solution (100% Parity):
Google Apps Script (specifically the V8 engine and the Clasp pusher) completely ignores ES6 export statements in standard .gs / .js files. You can safely append exports to the bottom of your source files to expose them to Node.js, while Live GAS will naturally treat them as part of the monolithic global scope.
Step 1: Append export to the source file
// File: Utils.js
var Utils = (function() { return { html: () => "hi" } })();
function doSomething() { return true; }
// Add this to the very bottom.
// Node.js will read it. Live Apps Script will ignore it.
export { Utils, doSomething };
Step 2: Re-export from the entry point
// File: index.js (Local entry point for `gas-fakes serve`)
import '@mcpher/gas-fakes';
// Directly re-export them so gas-fakes can bridge them to the template/RPC workers
export { Utils, doSomething } from './Utils.js';
export const main = () => {
return HtmlService.createTemplateFromFile('index.html').evaluate();
}
This pattern ensures your templates and google.script.run calls can seamlessly find your backend methods locally, while keeping the source code perfectly compliant with Live Apps Script.
This knowledge file outlines the preferred method for discovering documentation, methods, interfaces, and signatures for Google Apps Script (GAS) within our local environment.
The definitive source for all Google Apps Script documentation is the local JSON file:
/Users/brucemcpherson/Documents/repos/gas-fakes/doccreation/gi-fake-all.json
This file contains a complete, comprehensive duplicate of all official Apps Script documentation, including methods, classes, parameters, return types, and descriptions.
Relying on the local JSON file provides significant advantages over performing external web searches:
The agent must prioritize searching and reading gi-fake-all.json before initiating any external web searches for GAS documentation.
When a query requires knowledge of a GAS method, class, or interface, follow these steps:
grep, jq, or internal file parsing capabilities) to query gi-fake-all.json.In summary: Treat gi-fake-all.json as the authoritative, real-time documentation database for all Google Apps Script interactions.
This directory contains modular markdown files representing the "Lessons Learned & Best Practices" for the gf_agent skill.
To prevent Git merge conflicts on the monolithic gf_agent/SKILL.md file, collaborators should never edit gf_agent/SKILL.md directly.
Instead, to add new knowledge or instructions to the agent:
06-new-feature.md).Do not attempt to compile the SKILL.md file yourself.
When your Pull Request is merged into the core gas-fakes repository, the maintainer will run the overarching npm run docs pipeline. The builder.js script will automatically read all files in this directory, sort them, and cleanly generate the final gf_agent/SKILL.md artifact for all users.