HomeAbout MeBook a Call

Automating Technical Debt Audits in Apps Script with AI Agents

By Vo Tu Duc
May 06, 2026
Automating Technical Debt Audits in Apps Script with AI Agents

Google Apps Script makes automation incredibly accessible, but this ease-of-use conceals a critical pitfall that can cripple your projects as they scale.

image 0

The Hidden Scalability Trap in Apps Script

[AI Powered Cover Letter [Automated Job Creation in Real Time Jobber and Google Sheets Integration from Gmail](https://votuduc.com/Automated-Job-Creation-in-Jobber-from-Gmail-p115606) Engine](https://votuduc.com/AI-Powered-Cover-Letter-Automated Quote Generation and Delivery System for Jobber-Engine-p111092) is, without a doubt, one of the most powerful low-code platforms available. Its magic lies in its accessibility. With a bit of JavaScript knowledge and a browser tab, you can glue together [Automatically create new folders in Google Drive, generate templates in new folders, fill out text automatically in new files, and save info in [Automated Web Scraping with [Multilingual Text-to-Speech Tool with SocialSheet Streamline Your Social Media Posting 123](https://votuduc.com/Multilingual-Text-to-Speech-Tool-with-Google-Workspace-p809282)](https://votuduc.com/Automated-Web-Scraping-with-Google-Sheets-p292968)](https://workspace.google.com/marketplace/app/auto_create_folder_and_files/430076014869) services, automate tedious reports, and build simple web apps that solve real business problems—often in a matter of hours. This rapid development cycle is its greatest strength. It’s also the source of its most insidious trap.

The trap isn’t about server load or concurrent users; Google’s serverless infrastructure handles that with incredible grace. The scalability problem in Apps Script is one of complexity, maintainability, and organizational knowledge. Scripts that start as quick, tactical solutions often evolve into mission-critical, yet fragile, business processes. As they grow, they accumulate a hidden “debt” that can bring productivity to a grinding halt.

When Quick Automations Become Long-Term Problems

Every problematic Apps Script project starts with the best intentions.

Imagine a simple script written by a marketing analyst to pull data from a Google Sheet, format it, and email a daily report. It’s a 50-line masterpiece of efficiency that saves them an hour every morning. The team loves it. Soon, they ask for more: can it also pull data from a second Sheet? Can it cross-reference with a contact list? Can it generate a chart and embed it in a Google Doc?

With each request, the script grows.

image 1

Fast forward a year. The analyst has moved to a new role. The script is now a 1,000-line behemoth that is central to the team’s weekly reporting. But one day, it silently fails. No one knows why. The new analyst opens the Code.gs file and is confronted with an unreadable, undocumented tangle of logic. What was once a time-saver is now a source of risk and anxiety. Any attempt to fix one part might break another.

This is the lifecycle of technical debt in Apps Script. It’s like building a garden shed without a blueprint. It works perfectly for storing a lawnmower, but when you try to add a second floor and plumbing, the structural weaknesses become painfully obvious. The “quick win” has become a long-term liability.

Defining Technical Debt in a Serverless Context

In traditional software engineering, technical debt is the implied cost of rework caused by choosing an easy solution now instead of using a better approach that would take longer. It’s a loan against future development speed.

In the serverless world of Apps Script, this concept takes on a unique flavor. We aren’t worried about unpatched servers or memory leaks in the traditional sense. Instead, technical debt manifests in ways specific to the platform:

  • Quota & Performance Debt: This is the most common form. Using inefficient patterns like calling sheet.getRange().getValue() inside a loop instead of a single sheet.getDataRange().getValues() call outside the loop. While it works for 10 rows, it will time out or exhaust API quotas when the Sheet grows to 10,000 rows. The “interest payment” here is a hard execution failure.

  • Security & Scopes Debt: When initializing a project, it’s easy to grant it overly permissive OAuth scopes. A script that only needs to read a single spreadsheet might request full Drive access. This creates an unnecessarily large security blast radius if the script is ever compromised or has a bug.

  • Architectural Debt: This involves creating monolithic Code.gs files that handle dozens of unrelated tasks. There’s no separation of concerns, making the code impossible to test, debug, or reuse. You can’t take the “emailing” function and use it in another project because it’s tightly coupled with spreadsheet logic.

  • Dependency & “Bit Rot” Debt: Hardcoding IDs for files, folders, and calendars, or relying on deprecated APIs. When a user deletes a file or Google updates an API, the script breaks. The code “rots” over time because its external dependencies are not managed robustly.

  • Readability Debt: Using cryptic variable names, inconsistent formatting, and a complete lack of comments. The code might work, but it’s a black box. The next person (or you, in six months) will have to spend hours just to understand what it does before they can even think about changing it.

Why Manual Code Reviews Fail to Keep Pace

For professional development teams, the standard defense against technical debt is the manual code review. A teammate reviews your code before it’s merged, catching potential issues. This works well in a structured environment. The Apps Script ecosystem, however, is anything but.

  1. The Rise of the Citizen Developer: The beauty of Apps Script is that you don’t need to be a professional developer to use it. Marketers, analysts, teachers, and admins are building solutions. They aren’t working in Git, they don’t create pull requests, and there’s often no formal review process. Their code goes directly from idea to “production.”

  2. **Lack of Visibility and Scale: In a large organization, there could be thousands of container-bound scripts scattered across countless Google Docs, Sheets, and Forms. A central IT or development team has no easy way to even find all these scripts, let alone review them. The sheer volume makes manual oversight impossible.

  3. The Tedium Factor: Manually scanning hundreds of lines of code for suboptimal patterns like getValue() in a loop is inefficient and soul-crushing. Humans are great at spotting logical flaws but terrible at consistently catching repetitive, stylistic, or minor performance issues. One reviewer might flag it, another might miss it. This leads to inconsistent quality.

Manual reviews are essential for complex, mission-critical applications. But for providing a baseline of quality, security, and performance across an entire organization’s sprawling, decentralized script inventory, they simply don’t scale. We need an automated approach to audit code at scale—a way to shine a light on the hidden debt before it brings critical processes to a halt.

Architecting an AI Agent for Code Complexity Audits

With the “why” established, let’s dive into the “how.” Building our AI agent isn’t about creating a monolithic, complex application. Instead, we’ll architect a lean, effective system by orchestrating a few powerful Google services. The workflow is straightforward: fetch the code, send it to an AI for analysis, and log the results. This section breaks down the essential components and the step-by-step process for wiring them together.

Core Components: The Apps Script API, Gemini, and Google Sheets

Our agent is a synergistic trio of technologies, each playing a distinct and critical role.

  • **The Apps Script API: This is our gateway to the source code. While an Apps Script project can easily read its own code, it cannot natively access the code of other projects. The Apps Script API is a REST API that provides programmatic access to create, read, and modify Apps Script projects. For our agent, its sole purpose is to act as a “librarian,” fetching the .gs files from any target project we want to audit. This requires enabling the API in your Google Cloud Platform (GCP) project.

  • Gemini: This is the analytical engine—the “brain” of our operation. We will use a powerful Gemini model (e.g., Gemini 1.0 Pro) via its API. We won’t just ask it if the code is “good”; we’ll provide it with a specific set of instructions (a prompt) to evaluate functions based on concrete software engineering principles like cyclomatic complexity and coupling. Its ability to reason about code and return structured data (like JSON) is what makes this Automated Work Order Processing for UPS possible.

  • Google Sheets: This is our Architecting a Centralized HQ Dashboard with Google Sheets and Apps Script and data store. While you could use a more robust database, Google Sheets offers the path of least resistance within the AC2F Streamline Your Google Drive Workflow ecosystem. It’s simple, visual, and easily manipulated. Our agent will log its findings here, creating a row for each analyzed function. This turns abstract technical debt into a concrete, sortable, and filterable dataset that your team can act on.

Step 1: Programmatically Accessing Your Codebase

Before our agent can analyze anything, it needs to read the code. This is where the Apps Script API comes in. The first step is to ensure the API is enabled for the Google Cloud project associated with your auditor script.

Once enabled, you’ll need to update your script’s manifest file (appsscript.json) to include the necessary OAuth scope. This grants your script permission to call the API.


{

"timeZone": "America/New_York",

"dependencies": {},

"exceptionLogging": "STACKDRIVER",

"runtimeVersion": "V8",

"oauthScopes": [

"https://www.googleapis.com/auth/script.projects",

"https://www.googleapis.com/auth/spreadsheets"

]

}

With the permissions in place, you can use a simple function to fetch all code files from a target project using its ID.


/**

* Fetches all code files from a given Apps Script project.

* @param {string} projectId The ID of the target Apps Script project.

* @returns {Array<Object>} An array of file objects from the project content.

* @throws {Error} If the API call fails.

*/

function getProjectCode(projectId) {

const SCRIPT_API_URL = `https://script.googleapis.com/v1/projects/${projectId}/content`;

const options = {

method: 'get',

headers: {

'Authorization': `Bearer ${ScriptApp.getOAuthToken()}`

},

muteHttpExceptions: true

};

const response = UrlFetchApp.fetch(SCRIPT_API_URL, options);

const responseCode = response.getResponseCode();

const responseBody = response.getContentText();

if (responseCode === 200) {

const content = JSON.parse(responseBody);

// Filter for actual code files, ignoring the manifest

return content.files.filter(file => file.type === 'SERVER_JS');

} else {

throw new Error(`Failed to fetch project content. Response: ${responseBody}`);

}

}

// Example Usage:

// const targetProjectId = "YOUR_TARGET_PROJECT_ID_HERE";

// const codeFiles = getProjectCode(targetProjectId);

// codeFiles.forEach(file => {

//   console.log(`File Name: ${file.name}`);

//   console.log(`--- Code ---\n${file.source}\n`);

// });

This function authenticates using the user’s OAuth token, calls the Apps Script API’s projects.getContent endpoint, and returns an array of file objects, each containing the file’s name and its source code.

Step 2: Prompting Gemini to Analyze Function Complexity and Coupling

This is where the magic happens. We’ll send the fetched code, function by function, to Gemini for analysis. The quality of the output depends almost entirely on the quality of the prompt. We need to be explicit in our request. We’re not just asking for an opinion; we’re asking for a structured analysis.

Here is a robust prompt designed to get a consistent JSON output:


You are an expert senior software engineer specializing in code quality and technical debt analysis for [Genesis Engine AI Powered Content to Video Production Pipeline](https://votuduc.com/Genesis-Engine-AI-Powered-Content-to-Video-Production-Pipeline-p452744).

Your task is to analyze the following Apps Script function and provide a structured analysis in JSON format.

Evaluate the function based on two key metrics:

1.  **Cyclomatic Complexity:** Estimate how many distinct paths exist through the function. A high score (10) means it's very complex with many nested conditionals and loops. A low score (1) means it's a simple, linear function.

2.  **Coupling:** Estimate how tightly coupled the function is to other parts of the system (e.g., global variables, specific spreadsheet ranges, other functions). A high score (10) means it's highly dependent and not reusable. A low score (1) means it's a pure, self-contained function.

The JSON output MUST follow this exact structure:

{

"functionName": "string",

"cyclomaticComplexityScore": "integer (1-10)",

"couplingScore": "integer (1-10)",

"justification": "A brief, one-to-two sentence explanation for the scores provided.",

"recommendation": "A concise, actionable recommendation for refactoring or improvement. If no improvement is needed, state 'None'."

}

Analyze this function:

[INSERT FUNCTION CODE HERE]

Now, let’s write the Apps Script function to call the Gemini API with this prompt.


/**

* Analyzes a single function's code using the Gemini API.

* @param {string} functionCode The source code of the function to analyze.

* @param {string} functionName The name of the function.

* @returns {Object} The parsed JSON object from the Gemini API response.

*/

function analyzeFunctionWithGemini(functionCode, functionName) {

const GEMINI_API_KEY = "YOUR_GEMINI_API_KEY_HERE";

const GEMINI_API_URL = `https://generativelanguage.googleapis.com/v1beta/models/gemini-pro:generateContent?key=${GEMINI_API_KEY}`;

// This is a simplified approach. A more robust solution would parse the function name.

// For this example, we assume the function name is passed in.

const prompt = `

You are an expert senior software engineer specializing in code quality and technical debt analysis for [Architecting Multi Tenant AI Workflows in [Building Modular Agentic Apps Script with Gemini Function Calling](https://votuduc.com/building-modular-agentic-apps-script-with-gemini-function-calling-p-20260322917321)](https://votuduc.com/architecting-multi-tenant-ai-workflows-in-google-apps-script-p-20260321290501).

Your task is to analyze the following Apps Script function and provide a structured analysis in JSON format.

Evaluate the function based on two key metrics:

1.  **Cyclomatic Complexity:** Estimate how many distinct paths exist through the function. A high score (10) means it's very complex with many nested conditionals and loops. A low score (1) means it's a simple, linear function.

2.  **Coupling:** Estimate how tightly coupled the function is to other parts of the system (e.g., global variables, specific spreadsheet ranges, other functions). A high score (10) means it's highly dependent and not reusable. A low score (1) means it's a pure, self-contained function.

The JSON output MUST follow this exact structure:

{

"functionName": "${functionName}",

"cyclomaticComplexityScore": "integer (1-10)",

"couplingScore": "integer (1-10)",

"justification": "A brief, one-to-two sentence explanation for the scores provided.",

"recommendation": "A concise, actionable recommendation for refactoring or improvement. If no improvement is needed, state 'None'."

}

Analyze this function:

${functionCode}

`;

const payload = {

"contents": [{

"parts": [{

"text": prompt

}]

}]

};

const options = {

method: 'post',

contentType: 'application/json',

payload: JSON.stringify(payload),

muteHttpExceptions: true

};

const response = UrlFetchApp.fetch(GEMINI_API_URL, options);

const responseBody = response.getContentText();

// Clean the response to extract the JSON block

const jsonString = responseBody.match(/```json\n([\s\S]*?)\n```/)[1];

return JSON.parse(jsonString);

}

Note: This code requires a method to parse individual functions from a file. A simple regex or a more advanced parser could be used for this, but is omitted here for brevity.

Step 3: Logging Actionable Insights into a Centralized Dashboard

The final piece of the puzzle is to take the structured JSON output from Gemini and log it in our Google Sheet. This transforms the analysis from an ephemeral API response into a persistent, trackable record.

First, set up your Google Sheet with the following headers in the first row:

Timestamp | Project ID | File Name | Function Name | Complexity Score | Coupling Score | Justification | Recommendation

Next, create a simple utility function to write a new row to this sheet.


/**

* Logs the analysis results to a designated Google Sheet.

* @param {string} projectId The ID of the project that was audited.

* @param {string} fileName The name of the file containing the function.

* @param {Object} analysisData The JSON object returned from the Gemini analysis.

*/

function logToDashboard(projectId, fileName, analysisData) {

const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Audit Log");

if (!sheet) {

throw new Error("'Audit Log' sheet not found!");

}

sheet.appendRow([

new Date(),

projectId,

fileName,

analysisData.functionName,

analysisData.cyclomaticComplexityScore,

analysisData.couplingScore,

analysisData.justification,

analysisData.recommendation

]);

}

// Example Usage (tying it all together):

// const projectId = "YOUR_TARGET_PROJECT_ID_HERE";

// const fileName = "Code.gs";

// const functionName = "processUserData";

// const functionCode = "function processUserData() { /* ... complex code ... */ }";

//

// const analysis = analyzeFunctionWithGemini(functionCode, functionName);

// logToDashboard(projectId, fileName, analysis);

By appending each result, you create a historical log. You can now run this agent weekly or monthly, sort by complexity score to find the most problematic functions, and track how these scores change over time as your team refactors the code. You’ve successfully turned an abstract concept—technical debt—into a measurable KPI.

A Practical Implementation Walkthrough

With the conceptual framework in place, let’s roll up our sleeves and translate theory into practice. This section provides a step-by-step guide to building the core components of our automated audit system. We’ll cover everything from authenticating with the necessary APIs to the orchestrator script that ties it all together, and finally, how to make sense of the results.

Setting Up Authentication and API Access

Before we can write a single line of orchestration code, we need to establish a secure and authorized communication channel between our Apps Script environment, the project we want to audit, and the generative AI model.

1. Enabling the Google Apps Script API

To programmatically read the source code of another Apps Script project, we must first enable the Apps Script API.

  1. Open the Apps Script project you intend to audit.

  2. Navigate to Project Settings (the gear icon ⚙️ on the left).

  3. Under the “Google Cloud Platform (GCP) Project” section, copy the Project Number.

  4. Go to the Google Cloud Console.

  5. In the project selector at the top of the page, ensure you have selected the project corresponding to the Project Number you just copied.

  6. In the navigation menu, go to APIs & Services > Library.

  7. Search for “Google Apps Script API” and click Enable.

2. Obtaining a Generative AI API Key

Next, we need credentials for our AI agent. We’ll use the Google Gemini API for this example.

  1. Navigate to Google AI Studio.

  2. Click on “Get API key” and follow the prompts to create a new API key within a new or existing Google Cloud project.

  3. Crucial Security Note: Never hardcode your API key directly in your script. This is a significant security risk. We will use Apps Script’s PropertiesService to store it securely.

In your auditor script (the one that will run the analysis), add the following utility functions. Run storeApiKey once from the editor to save your key.


// Run this function once to securely store your API key

function storeApiKey() {

const apiKey = 'YOUR_GEMINI_API_KEY_HERE'; // Paste your key here for this one-time run

PropertiesService.getScriptProperties().setProperty('GEMINI_API_KEY', apiKey);

console.log('API Key stored successfully.');

}

// This function will be used by our main script to retrieve the key

function getApiKey() {

const apiKey = PropertiesService.getScriptProperties().getProperty('GEMINI_API_KEY');

if (!apiKey) {

throw new Error('Gemini API key not found. Please run the storeApiKey() function.');

}

return apiKey;

}

3. Configuring OAuth Scopes in the Manifest

Finally, we must declare the permissions our auditor script needs. Open the auditor script’s manifest file (appsscript.json) by going to Project Settings > “Show ‘appsscript.json’ manifest file in editor”. Ensure your oauthScopes array includes the following:


{

"timeZone": "America/New_York",

"dependencies": {},

"exceptionLogging": "STACKDRIVER",

"runtimeVersion": "V8",

"oauthScopes": [

"https://www.googleapis.com/auth/script.projects.readonly",

"https://www.googleapis.com/auth/spreadsheets",

"https://www.googleapis.com/auth/script.external_request"

]

}

  • script.projects.readonly: Allows reading the source code of other Apps Script projects.

  • spreadsheets: Allows writing the final report to a Google Sheet.

  • script.external_request: Allows calling the external Gemini API.

After saving the manifest, the script will ask for user authorization for these scopes upon its next run.

The Main Orchestrator Script: A Code Breakdown

This is the heart of our system. The orchestrator script is responsible for fetching the code, prompting the AI, and recording the analysis. Below is a detailed breakdown of the main function.


const SCRIPT_ID_TO_AUDIT = 'ID_OF_THE_APPS_SCRIPT_PROJECT_TO_AUDIT';

const SPREADSHEET_ID = 'ID_OF_THE_GOOGLE_SHEET_FOR_THE_REPORT';

const SHEET_NAME = 'Audit Report';

/**

* Main function to orchestrate the technical debt audit.

*/

function runTechnicalDebtAudit() {

try {

// 1. Fetch the project source code

const files = fetchProjectCode(SCRIPT_ID_TO_AUDIT);

if (!files || files.length === 0) {

console.log('No code files found in the project.');

return;

}

// 2. Prepare the prompt and call the AI model

const aiResponse = analyzeCodeWithAI(files);

// 3. Parse the response and write to Google Sheets

const issues = JSON.parse(aiResponse);

writeReportToSheet(issues);

console.log('Audit complete. Report generated in Google Sheets.');

} catch (error) {

console.error('An error occurred during the audit:', error.toString(), error.stack);

}

}

/**

* Fetches all .gs and .html files from a given Apps Script project.

*/

function fetchProjectCode(scriptId) {

const url = `https://script.googleapis.com/v1/projects/${scriptId}/content`;

const options = {

method: 'get',

headers: {

'Authorization': `Bearer ${ScriptApp.getOAuthToken()}`

},

muteHttpExceptions: true

};

const response = UrlFetchApp.fetch(url, options);

const responseCode = response.getResponseCode();

const responseBody = response.getContentText();

if (responseCode === 200) {

const content = JSON.parse(responseBody);

// Filter for script and HTML files only

return content.files.filter(file => file.type === 'SERVER_JS' || file.type === 'HTML');

} else {

throw new Error(`Failed to fetch project code. Status: ${responseCode}, Body: ${responseBody}`);

}

}

/**

* Sends the code to the Gemini API for analysis.

*/

function analyzeCodeWithAI(files) {

const apiKey = getApiKey();

const url = `https://generativelanguage.googleapis.com/v1beta/models/gemini-pro:generateContent?key=${apiKey}`;

const systemPrompt = `

You are an expert Google Apps Script developer and senior software engineer performing a technical debt audit.

Analyze the following Apps Script files. For each file, identify potential technical debt.

Focus on issues like:

- Hardcoded "magic" strings or numbers that should be constants.

- Deeply nested loops or conditionals (high cyclomatic complexity).

- Functions that are too long or do too many things (violating Single Responsibility Principle).

- Poor variable or function names.

- Inefficient use of [Automated Client Onboarding with Google Forms and Google Drive.](https://votuduc.com/Automated-Client-Onboarding-with-Google-Forms-and-Google-Drive-p440350) service calls inside loops.

- Lack of comments for complex logic.

- Redundant or dead code.

For each issue you find, provide the following details:

- fileName: The name of the file.

- lineNumber: The approximate line number where the issue occurs.

- issueType: A short category for the issue (e.g., "Hardcoded Value", "High Complexity", "Inefficient Loop").

- description: A clear, concise explanation of the problem and why it's considered technical debt.

- suggestedRefactoring: A concrete code snippet or detailed description of how to fix the issue.

- effortEstimate: An integer from 1 (very easy) to 5 (very complex) to fix.

- priority: A string value of "Low", "Medium", or "High".

IMPORTANT: Your entire response MUST be a single, valid JSON array of objects, with each object representing one identified issue. Do not include any text or markdown formatting before or after the JSON array.

Example: [{"fileName": "Code.gs", "lineNumber": 15, ...}, {"fileName": "Utils.gs", "lineNumber": 42, ...}]

`;

const codeContent = files.map(file => `

// FILE: ${file.name}

${file.source}

`).join('\n\n---\n\n');

const payload = {

"contents": [{

"parts": [{

"text": `${systemPrompt}\n\n${codeContent}`

}]

}]

};

const options = {

method: 'post',

contentType: 'application/json',

payload: JSON.stringify(payload),

muteHttpExceptions: true

};

const response = UrlFetchApp.fetch(url, options);

const responseBody = response.getContentText();

const responseCode = response.getResponseCode();

if (responseCode === 200) {

const result = JSON.parse(responseBody);

return result.candidates[0].content.parts[0].text;

} else {

throw new Error(`AI API call failed. Status: ${responseCode}, Body: ${responseBody}`);

}

}

/**

* Writes the parsed issues to the specified Google Sheet.

*/

function writeReportToSheet(issues) {

const ss = SpreadsheetApp.openById(SPREADSHEET_ID);

let sheet = ss.getSheetByName(SHEET_NAME);

if (!sheet) {

sheet = ss.insertSheet(SHEET_NAME);

}

sheet.clear(); // Clear old data

const headers = ['File Name', 'Line Number', 'Issue Type', 'Description', 'Suggested Refactoring', 'Effort (1-5)', 'Priority', 'Status'];

sheet.appendRow(headers).getRange('A1:H1').setFontWeight('bold');

const rows = issues.map(issue => [

issue.fileName,

issue.lineNumber,

issue.issueType,

issue.description,

issue.suggestedRefactoring,

issue.effortEstimate,

issue.priority,

'To Do' // Default status

]);

if (rows.length > 0) {

sheet.getRange(2, 1, rows.length, rows[0].length).setValues(rows);

sheet.autoResizeColumns(1, headers.length);

}

}

Code Walkthrough:

  1. runTechnicalDebtAudit(): This is our main entry point. It follows a simple three-step process: fetch, analyze, and write. The try...catch block ensures any failure in the pipeline is logged gracefully.

  2. fetchProjectCode(): This function makes an authenticated GET request to the Apps Script API endpoint. It uses ScriptApp.getOAuthToken() to automatically handle the authorization header and UrlFetchApp to perform the request. It returns an array of file objects containing the source code.

  3. analyzeCodeWithAI(): This is where the magic happens.

It constructs a detailed* system prompt**, which is critical for guiding the AI to produce a structured and relevant analysis. Notice how we explicitly define the output format (a JSON array of objects) and the exact fields we want.

  • It concatenates all the fetched code files into a single string to send to the AI.

  • It makes a POST request to the Gemini API with the combined prompt and code.

  • It parses the API’s response to extract the generated text, which should be our clean JSON string.

  1. writeReportToSheet(): This function takes the array of issue objects, opens the target Google Sheet, clears any old data, writes a header row, and then appends each issue as a new row. We also add a “Status” column to help turn this report into an actionable task list.

Interpreting the AI-Generated Refactoring Report in Sheets

The script’s output is not just data; it’s a strategic blueprint for improving your codebase. When the script finishes, you’ll have a Google Sheet that looks something like this:

| File Name | Line Number | Issue Type | Description | Suggested Refactoring | Effort (1-5) | Priority | Status |

| :--- | :--- | :--- | :--- | :--- | :--- | :--- | :--- |

| Mail.gs | 25 | Hardcoded Value | The subject line “Monthly Report” is hardcoded. This makes it difficult to update and reuse the function for different reports. | const REPORT_SUBJECT = 'Monthly Report'; ... MailApp.sendEmail(..., REPORT_SUBJECT, ...); | 1 | Low | To Do |

| DataProcessor.gs | 78 | Inefficient Loop | SpreadsheetApp.getActiveSheet().getRange(i, 1).getValue() is called inside a loop, leading to multiple slow API calls. | Fetch the entire data range into an array before the loop: const data = sheet.getDataRange().getValues(); then iterate over the array. | 3 | High | To Do |

| Main.gs | 42 | High Complexity | This function has 4 nested if/else statements, making it hard to read, test, and maintain. | Refactor using early returns (guard clauses) or break the logic into smaller, more focused helper functions. | 4 | Medium | To Do |

How to Use This Report:

  • Triage and Prioritize: This is no longer an amorphous blob of “technical debt.” You have a quantified and qualified list. Use the sorting and filtering features in Google Sheets to your advantage. A great place to start is with tasks that are High Priority and have a Low Effort estimate—these are your quick wins.

  • Validate, Don’t Blindly Trust: The AI is a powerful assistant, not an infallible oracle. For each line item, a human developer should perform a quick review. Read the Description and Suggested Refactoring. Does the AI’s suggestion make sense in the full context of your application? In 90% of cases, it will be spot-on or a great starting point, but human oversight is essential.

  • Create an Action Plan: The report is now your technical debt backlog. Use the Status column to track progress (To Do, In Progress, Done). You can even add an Assigned To column if you’re working in a team. This transforms a static audit into a living document that drives continuous improvement.

Strategic Benefits for Engineering Leadership

Moving beyond the immediate technical wins of cleaner code, integrating AI-driven audits into your Apps Script ecosystem unlocks significant strategic advantages. For engineering managers, tech leads, and directors, this isn’t just about managing code; it’s about managing risk, optimizing resources, and building a more resilient engineering culture. The shift from manual, sporadic checks to continuous, automated analysis provides the leverage needed to lead more effectively.

Building a Data-Driven Roadmap for Refactoring

Let’s be honest: refactoring roadmaps are often built on a combination of gut feelings, developer complaints, and which part of the codebase caused the last production fire. While this approach can work, it’s reactive and prone to bias. The “squeaky wheel” gets the grease, while more sinister, silent problems fester in other parts of the system.

An AI agent transforms this process from subjective art to data-driven science. By continuously scanning your Apps Script projects, it generates objective metrics on:

  • Code Complexity: Pinpointing functions and files with high cyclomatic complexity that are difficult to maintain and prone to bugs.

  • Dependency Mapping: Visualizing tangled dependencies and identifying modules that violate architectural boundaries, creating a “heat map” of your most critical and fragile code.

  • Anti-Pattern Detection: Automatically flagging common Apps Script pitfalls, like inefficient use of getRange() in a loop or improper handling of API quotas.

With this data, you can stop guessing. You can build a prioritized backlog for technical debt repayment based on quantifiable risk and business impact. The conversation shifts from “We think we should refactor the old reporting script” to “The reporting module has the highest complexity score and is coupled to three other critical services. Addressing it will mitigate our top two production risks and unblock the Q4 feature roadmap.”

Enforcing Code Quality Standards at Scale

As teams grow, maintaining a consistent standard of code quality becomes exponentially harder. Manual code reviews are essential, but they are also a bottleneck. Senior engineers spend valuable time pointing out stylistic issues or recurring anti-patterns, time that could be better spent on complex architectural decisions. Furthermore, the quality of a review can vary depending on the reviewer’s mood, workload, or familiarity with the code.

An AI agent acts as a tireless, objective gatekeeper. It becomes the baseline for quality, integrated directly into your development workflow.

  • **Automated Pre-Reviews: The agent can automatically scan pull requests or code pushes, flagging violations of your team’s established coding standards before a human reviewer even sees the code. This frees up your senior talent to focus on the logic and design, not the syntax.

  • Consistent Enforcement: The AI applies the same rules, every single time, across every project and every developer. This eliminates the “but it works on my machine” and “so-and-so let me do it last time” arguments, creating a level playing field and a shared understanding of what “good” looks like.

  • Educational Tooling: When the agent flags an issue, it can provide context and links to documentation, turning a “rejection” into a learning opportunity for junior and mid-level developers, effectively upskilling your team over time.

This approach doesn’t replace human reviewers; it empowers them. It institutionalizes your best practices and ensures that your quality bar doesn’t drop, even as you scale your team and your codebase.

Justifying Architectural Investments to Stakeholders

One of the most persistent challenges for engineering leaders is articulating the value of non-feature work to business stakeholders. Explaining why you need to pause feature development for two sprints to “refactor the authentication service” is a tough sell when framed in purely technical terms.

This is where AI-driven audits become your most powerful communication tool. The reports and trend data generated by the agent allow you to translate technical debt into business risk and ROI.

Instead of saying: “This code is messy and hard to work with.”

You can now say: “Our automated analysis shows a 30% increase in code complexity in our core data processing library over the last quarter. This directly correlates with a 50% increase in bug-related tickets for features that depend on it. By investing 80 engineering hours now to reduce this complexity, we project a 20% reduction in future bug-fix time and an acceleration of our Q3 feature delivery.”

This data-backed narrative changes everything. You can present stakeholders with:

  • Trend Reports: Show how debt is accumulating over time and where the hotspots are.

  • Risk Analysis: Connect poorly written code to specific business functions (e.g., “The payment processing script has a high vulnerability score”).

  • **Cost of Delay: Quantify the impact of not addressing the debt, such as slower feature development, increased onboarding time for new engineers, and higher risk of critical failures.

By grounding your arguments in objective data, you shift the conversation from a technical plea to a strategic business decision, making it far easier to secure the resources and time needed to keep your technical foundation strong.

Conclusion: Your Path to Maintainable Architecture

We’ve journeyed from the conceptual problem of technical debt to a tangible, AI-driven solution within the Google Apps Script environment. The agent we’ve designed is more than just a clever script; it’s a foundational step towards transforming how you manage, scale, and perceive your Automated Discount Code Management System automations. This isn’t about achieving perfect code—it’s about establishing a sustainable process for continuous improvement. By automating the audit process, you free up your developers to focus on what they do best: creating value, not untangling yesterday’s shortcuts. You’re building a system that makes the right way the easy way.

Recap: From Spaghetti Code to a Strategic Asset

Let’s distill our journey down to its core. We began by acknowledging a common reality: Apps Script projects, often born from urgent business needs, can quickly devolve into “spaghetti code”—a tangled mess of hardcoded IDs, inefficient loops, and undocumented logic. This technical debt isn’t just a technical problem; it’s a business risk that stifles innovation and inflates maintenance costs.

Our solution was to architect an AI agent that acts as an objective, tireless code reviewer. By leveraging the analytical power of a Large Language Model, we’ve demonstrated how to:

  1. Systematically Ingest and parse Apps Script code files.

  2. Apply a Custom Prompt that directs the AI to analyze the code against established best practices for maintainability, performance, and security.

  3. Generate Actionable Reports that pinpoint specific issues, explain the “why” behind the problem, and suggest concrete remediation steps.

Through this process, you transform your codebase from a liability into a well-documented, strategic asset. You gain a clear, data-driven understanding of your application’s health, enabling you to prioritize refactoring efforts and make informed architectural decisions.

Future Enhancements for Your AI Audit Agent

The agent we’ve built is a powerful starting point, but its potential is far greater. As you integrate this tool into your workflow, consider these next-level enhancements to create a truly sophisticated governance system:

  • Automated Ticketing Integration: Connect your agent’s output directly to your project management system (e.g., Jira, Asana, or even Google Tasks). When the agent identifies a high-severity issue, it can automatically create a ticket, assign it to the relevant team, and populate it with all the necessary context, streamlining the entire remediation lifecycle.

  • Custom Rule-Set Ingestion: Elevate the agent’s intelligence by enabling it to analyze code against your organization’s specific style guides and architectural patterns. Instead of relying solely on general best practices, the agent can learn and enforce your team’s unique coding conventions.

  • Performance and Quota Analysis: Fine-tune your prompt to have the AI specifically hunt for common Apps Script performance killers. This includes identifying redundant API calls within loops, inefficient data handling with getValues()/setValues(), and patterns that risk exceeding Google’s daily quotas.

  • Historical Trend Reporting: Don’t just audit—analyze. Store the results of each audit in a Google Sheet or BigQuery. This allows you to build dashboards in Looker Studio to track your “technical debt score” over time, identify recurring anti-patterns, and measure the impact of your refactoring initiatives.

Scaling Your Automated Email Journey with Google Sheets and Google Analytics Architecture

A single AI-audited project is a win. An entire ecosystem governed by these principles is a competitive advantage. The true power of this approach is realized when you scale it across your entire Automated Google Slides Generation with Text Replacement development practice.

Think bigger. Instead of running this agent on a project-by-project basis, build a centralized “Governance Hub.” This master Apps Script project could use the Apps Script API to programmatically access and audit all designated projects within your organization, providing a single pane of glass view of your entire automation landscape’s health.

The ultimate step is to integrate this AI audit into your CI/CD (Continuous Integration/Continuous Deployment) pipeline. Using tools like clasp and GitHub Actions, you can trigger the AI agent to run automatically on every pull request. A build that introduces significant technical debt or violates core architectural principles can be automatically flagged or even blocked from merging. This shifts your posture from reactive cleanup to proactive quality assurance, ensuring that your architecture remains robust and maintainable as it grows. By embedding intelligence directly into your development process, you foster a culture of quality and build a foundation that can truly scale.


Tags

Apps ScriptTechnical DebtAI AgentsAutomationCode QualityGoogle WorkspaceSoftware Development

Share


Previous Article
Automating Terraform HCL from Google Sheets with Gemini Pro
Vo Tu Duc

Vo Tu Duc

A Google Developer Expert, Google Cloud Innovator

Stop Doing Manual Work. Scale with AI.

Hi, I'm Vo Tu Duc (Danny), a recognised Google Developer Expert (GDE). I architect custom AI agents and Google Workspace solutions that help businesses eliminate chaos and save thousands of hours.

Want to turn these blog concepts into production-ready reality for your team?
Book a Discovery Call

Table Of Contents

Portfolios

AI Agentic Workflows
Cloud Engineering
AppSheet Solutions
Change Management
Strategy Playbooks
Product Showcase
Uncategorized
Workspace Automation

Related Posts

Automate Site Defect Punch Lists with Gemini and Google Chat
May 22, 2026
© 2026, All Rights Reserved.
Powered By

Quick Links

Book a CallAbout MeVolunteer Legacy

Social Media