feat: Add google-reviews-ai-manager kit - #286
Conversation
:robot_face: AgentKit Structural ValidationNew Contributions Detected
Check Results
|
WalkthroughChangesThe PR adds a Google Reviews AI Manager kit with a Lamatic reply-generation flow, a Next.js dashboard using Google OAuth and Google Business Profile APIs, reply drafting and publishing actions, project metadata, and automated Lamatic flow synchronization. Google Reviews AI Manager
Suggested reviewers: 🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (2 warnings)
✅ Passed checks (3 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Warning There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure. 🔧 Biome (2.5.6)kits/google-reviews-ai-manager/apps/app/globals.cssFile contains syntax errors that prevent linting: Line 8: Tailwind-specific syntax is disabled. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 22
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.github/workflows/lamatic-update.yml:
- Around line 17-20: Pin both actions in the workflow—actions/checkout and
Lamatic/sync-flows-to-lamatic—to full immutable commit SHAs instead of the
mutable v4 and v1 tags, preserving their existing action versions and workflow
behavior.
- Around line 1-25: Add a top-level permissions configuration to the workflow
granting only contents read access, so the detect-flow-changes job and its
checkout/sync steps do not inherit broader GITHUB_TOKEN permissions. Keep the
existing triggers, job conditions, and action inputs unchanged.
- Around line 3-14: Add workflow-level concurrency to the Lamatic sync workflow,
using a stable group for the main-branch sync jobs and preventing overlapping
runs so only the latest relevant run proceeds. Place it alongside the top-level
on/jobs configuration without changing the existing trigger or
detect-flow-changes condition.
- Around line 16-17: Update the actions/checkout@v4 step in the Checkout
repository workflow step to set persist-credentials to false, preventing the
repository token from being retained in the workspace.
In `@kits/google-reviews-ai-manager/agent.md`:
- Around line 3-15: Update the Markdown in agent.md by inserting a blank line
immediately after the headings Role, Tone & Style, and Capabilities, while
preserving all existing text and list content.
In `@kits/google-reviews-ai-manager/apps/app/actions/gmb.ts`:
- Around line 19-21: Add a shared fetch helper in gmb.ts that applies an
AbortSignal timeout and converts timeout aborts into one consistent timeout
error, then route all four Google API fetches through it:
kits/google-reviews-ai-manager/apps/app/actions/gmb.ts lines 19-21, 37-39,
61-63, and 86-93. Preserve each request’s existing URL, headers, and response
handling while replacing direct fetch calls with the helper.
In `@kits/google-reviews-ai-manager/apps/app/actions/orchestrate.ts`:
- Around line 53-60: Remove the raw response logging around resText and replace
it with redacted, non-content metadata only. In the JSON.parse error path within
the orchestration action, stop including resText in the returned error and
return a generic client-facing parse failure message instead.
- Around line 40-51: Update the fetch call in the orchestrate action to use an
AbortController-based timeout, aborting stalled Lamatic requests after the
configured duration. Catch timeout aborts and return the action’s existing
controlled error response, while preserving normal response handling for
successful or non-timeout failures.
- Around line 4-12: Add an authenticated-session check at the start of
generateReply, before reading or sending review data to Lamatic. Use the
existing server-session mechanism and return an appropriate error when no
session is present; preserve the current environment-variable validation for
authenticated callers.
- Around line 8-12: Update the `apiUrl` configuration in the orchestration flow
to remove the hardcoded tenant-specific fallback; require `LAMATIC_API_URL` and
include it in the existing missing-configuration validation so execution fails
fast when it is unset.
- Around line 63-74: Update the executeWorkflow result handling around anyData
so it fails fast unless anyData?.status is exactly "success". Only return a
reply when the selected response field is a string; for successful payloads
without a string reply, return the JSON-serialized anyData as the review
response instead of treating arbitrary values as a reply.
In `@kits/google-reviews-ai-manager/apps/app/api/auth/`[...nextauth]/route.ts:
- Around line 20-28: The NextAuth callbacks in jwt and session currently expose
the Google bearer token and omit renewal metadata. Keep access and refresh
credentials plus expiry state in the server-side JWT, stop assigning
token.accessToken in session, and update the GMB actions to obtain and refresh
the provider token from the JWT/server-side auth state rather than
session.accessToken.
In `@kits/google-reviews-ai-manager/apps/app/components/ReviewList.tsx`:
- Around line 181-408: Refactor the main ReviewList render into sibling
components for the top-level sections: extract the metrics row into MetricsBar,
filters into FilterBar, each mapped review into ReviewCard, and the location
selector overlay into LocationModal. Move each section’s required data,
callbacks, and state handlers into explicit props while preserving the existing
behavior, styling, and conditional rendering in ReviewList.
In `@kits/google-reviews-ai-manager/apps/app/globals.css`:
- Around line 22-26: Update the global body font-family declaration to use the
configured --font-geist-sans variable first, retaining the existing fallback
fonts afterward. Remove Arial as the primary font so the Geist font loaded by
layout.tsx is applied globally.
In `@kits/google-reviews-ai-manager/apps/app/layout.tsx`:
- Around line 15-18: Update the exported metadata object in layout.tsx,
replacing the default “Create Next App” title and generated description with
Google Reviews AI Manager-specific title and description values.
In `@kits/google-reviews-ai-manager/apps/app/page.tsx`:
- Around line 1-13: Update the Home function’s getServerSession call to pass the
shared authOptions configuration used by app/actions/gmb.ts, ensuring this page
validates sessions with the same NextAuth setup.
In `@kits/google-reviews-ai-manager/apps/package.json`:
- Around line 11-18: Replace the react-icons dependency with lucide-react in the
package configuration, then update icon imports and usages in ReviewList.tsx to
use Lucide equivalents while preserving the existing UI behavior. Regenerate the
lockfile so it reflects the dependency swap and removes react-icons.
In `@kits/google-reviews-ai-manager/apps/README.md`:
- Around line 1-36: Replace the scaffold content in the README with kit-specific
setup instructions covering dependency installation, copying .env.example to the
active environment file, configuring Google OAuth credentials and callback URL,
setting the Lamatic project and flow variables, starting the application, and
updating NEXTAUTH_URL for deployments. Remove the generic create-next-app
guidance and document the required environment variable names using the
repository’s existing configuration symbols.
In `@kits/google-reviews-ai-manager/prompts/my-first-flow_llm-node_user_1.md`:
- Line 1: Update the prompt text in the user message to replace the literal
[starRating variable] and [reviewText variable] placeholders with Lamatic
trigger interpolation using trigger.output.starRating and
trigger.output.reviewText, so the LLM receives the actual review values.
In `@kits/google-reviews-ai-manager/README.md`:
- Around line 38-43: Update the Next.js version in the README’s “Tech Stack”
section to match the shipped version declared in the apps package.json: 16.2.10.
Leave the other stack entries unchanged.
- Around line 1-72: Update the README Markdown structure to satisfy the
configured lint rules: add a Markdown H1 (or explicitly adjust the lint
configuration), and insert required blank lines before and after headings and
fenced code blocks. Preserve the existing content and presentation while
ensuring all sections pass Markdown linting.
In `@lamatic/flows/MyFirstFlow.ts`:
- Around line 42-52: Update the user prompt content in the prompts configuration
to use Lamatic {{...}} interpolation for the starRating and reviewText fields
instead of bracketed placeholders, ensuring the rendered prompt contains the
actual values. Add a render test covering both interpolated values in the final
prompt.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI (base), Organization UI (inherited)
Review profile: ASSERTIVE
Plan: Pro
Run ID: a10b704a-ab3a-49ac-acaf-add362087ce3
⛔ Files ignored due to path filters (8)
kits/google-reviews-ai-manager/apps/app/favicon.icois excluded by!**/*.icokits/google-reviews-ai-manager/apps/package-lock.jsonis excluded by!**/package-lock.jsonkits/google-reviews-ai-manager/apps/public/file.svgis excluded by!**/*.svgkits/google-reviews-ai-manager/apps/public/globe.svgis excluded by!**/*.svgkits/google-reviews-ai-manager/apps/public/logo.pngis excluded by!**/*.pngkits/google-reviews-ai-manager/apps/public/next.svgis excluded by!**/*.svgkits/google-reviews-ai-manager/apps/public/vercel.svgis excluded by!**/*.svgkits/google-reviews-ai-manager/apps/public/window.svgis excluded by!**/*.svg
📒 Files selected for processing (28)
.github/workflows/lamatic-update.ymlkits/google-reviews-ai-manager/README.mdkits/google-reviews-ai-manager/agent.mdkits/google-reviews-ai-manager/apps/.env.examplekits/google-reviews-ai-manager/apps/.gitignorekits/google-reviews-ai-manager/apps/AGENTS.mdkits/google-reviews-ai-manager/apps/CLAUDE.mdkits/google-reviews-ai-manager/apps/README.mdkits/google-reviews-ai-manager/apps/app/actions/gmb.tskits/google-reviews-ai-manager/apps/app/actions/orchestrate.tskits/google-reviews-ai-manager/apps/app/api/auth/[...nextauth]/route.tskits/google-reviews-ai-manager/apps/app/components/ReviewList.tsxkits/google-reviews-ai-manager/apps/app/globals.csskits/google-reviews-ai-manager/apps/app/layout.tsxkits/google-reviews-ai-manager/apps/app/page.tsxkits/google-reviews-ai-manager/apps/eslint.config.mjskits/google-reviews-ai-manager/apps/next.config.tskits/google-reviews-ai-manager/apps/package.jsonkits/google-reviews-ai-manager/apps/postcss.config.mjskits/google-reviews-ai-manager/apps/tsconfig.jsonkits/google-reviews-ai-manager/constitutions/default.mdkits/google-reviews-ai-manager/flows/my-first-flow.tskits/google-reviews-ai-manager/lamatic.config.tskits/google-reviews-ai-manager/model-configs/my-first-flow_llm-node_generative-model-name.tskits/google-reviews-ai-manager/prompts/my-first-flow_llm-node_system_0.mdkits/google-reviews-ai-manager/prompts/my-first-flow_llm-node_user_1.mdlamatic/flows/MyFirstFlow.tslamatic/project.json
There was a problem hiding this comment.
Caution
Inline review comments failed to post. This is likely due to GitHub's internal server error or limits when posting large numbers of comments. If you are seeing this consistently it is likely a permissions issue. Please check "Moderation" -> "Code review limits" under your organization settings.
🛑 Comments failed to post (22)
.github/workflows/lamatic-update.yml (4)
1-25: 🔒 Security & Privacy | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash set -euo pipefail printf '--- .github/workflows/lamatic-update.yml ---\n' cat -n .github/workflows/lamatic-update.yml printf '\n--- workflows with explicit permissions ---\n' rg -n "^\s*permissions:" .github/workflows || trueRepository: Lamatic/AgentKit
Length of output: 245
🏁 Script executed:
#!/bin/bash set -euo pipefail python3 - <<'PY' from pathlib import Path p = Path('.github/workflows/lamatic-update.yml') text = p.read_text() print("has permissions block:", 'permissions:' in text) print("uses checkout persist-credentials explicitly:", 'persist-credentials' in text) print("workflow trigger:", text.splitlines()[:15]) PYRepository: Lamatic/AgentKit
Length of output: 582
Mission directive: lock down the workflow token permissions. Add
permissions: contents: readhere so this job doesn’t inherit broader defaultGITHUB_TOKENaccess than it needs for checkout and sync.🧰 Tools
🪛 YAMLlint (1.37.1)
[warning] 3-3: truthy value should be one of [false, true]
(truthy)
🪛 zizmor (1.26.1)
[warning] 16-17: credential persistence through GitHub Actions artifacts (artipacked): does not set persist-credentials: false
(artipacked)
[warning] 1-27: overly broad permissions (excessive-permissions): default permissions used due to no permissions: block
(excessive-permissions)
[error] 17-17: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)
(unpinned-uses)
[error] 20-20: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)
(unpinned-uses)
[info] 11-11: workflow or action definition without a name (anonymous-definition): this job
(anonymous-definition)
[warning] 3-8: insufficient job-level concurrency limits (concurrency-limits): workflow is missing concurrency setting
(concurrency-limits)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In @.github/workflows/lamatic-update.yml around lines 1 - 25, Add a top-level permissions configuration to the workflow granting only contents read access, so the detect-flow-changes job and its checkout/sync steps do not inherit broader GITHUB_TOKEN permissions. Keep the existing triggers, job conditions, and action inputs unchanged.Source: Linters/SAST tools
3-14: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash set -euo pipefail # Inspect the workflow and nearby references to concurrency/cancellation behavior. git ls-files '.github/workflows/*' | sed -n '1,120p' printf '\n--- workflow ---\n' cat -n .github/workflows/lamatic-update.yml printf '\n--- search concurrency/cancel/safe markers ---\n' rg -n "concurrency|cancel-in-progress|LAMATIC-COMMIT|lamatic-flow-sync|cancellation-safe|cancel safe|queue runs" .github/workflows . -g '!**/node_modules/**' -g '!**/dist/**' -g '!**/build/**' || trueRepository: Lamatic/AgentKit
Length of output: 2838
Serialize Lamatic sync jobs. Add a workflow-level concurrency group here so only one
mainpush sync runs at a time; otherwise an older run can finish after a newer one and overwrite the latest Lamatic state.⏱️ Proposed hardening
on: push: branches: - main paths: - '**/lamatic/flows/**' + +concurrency: + group: lamatic-flow-sync + cancel-in-progress: false📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.on: push: branches: - main paths: - '**/lamatic/flows/**' concurrency: group: lamatic-flow-sync cancel-in-progress: false jobs: detect-flow-changes: environment: main runs-on: ubuntu-latest if: "!contains(github.event.head_commit.message, '[LAMATIC-COMMIT]')"🧰 Tools
🪛 YAMLlint (1.37.1)
[warning] 3-3: truthy value should be one of [false, true]
(truthy)
🪛 zizmor (1.26.1)
[info] 11-11: workflow or action definition without a name (anonymous-definition): this job
(anonymous-definition)
[warning] 3-8: insufficient job-level concurrency limits (concurrency-limits): workflow is missing concurrency setting
(concurrency-limits)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In @.github/workflows/lamatic-update.yml around lines 3 - 14, Add workflow-level concurrency to the Lamatic sync workflow, using a stable group for the main-branch sync jobs and preventing overlapping runs so only the latest relevant run proceeds. Place it alongside the top-level on/jobs configuration without changing the existing trigger or detect-flow-changes condition.Source: Linters/SAST tools
16-17: 🔒 Security & Privacy | 🟡 Minor | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
sed -n '1,120p' .github/workflows/lamatic-update.ymlRepository: Lamatic/AgentKit
Length of output: 850
🌐 Web query:
actions/checkout persist-credentials default local git config third-party action security💡 Result:
The persist-credentials input in actions/checkout is enabled by default [1][2][3]. When set to true, it configures the repository's local git config with the provided token or SSH key, allowing subsequent steps in the same job to execute authenticated git commands (e.g., git fetch, git push) without manual configuration [1][2][4]. Security Considerations: 1. Credential Exposure: Historically, actions/checkout stored these credentials directly in the.git/config file [1][5]. This created a risk where, if a later step in the workflow unintentionally exposed the repository's files (such as by uploading artifacts or logs), the credentials could be compromised [5]. 2. Mitigation: In newer versions (e.g., actions/checkout v4 and later), credentials are stored in a separate file under $RUNNER_TEMP rather than directly in.git/config, which improves security by reducing the likelihood of accidental exposure [1][3]. 3. Principle of Least Privilege: Security best practices, including guidance from the OWASP Foundation, recommend setting persist-credentials: false unless specifically required for git operations [6]. Disabling this feature prevents the credentials from being persisted to the environment, thereby limiting the risk of exposure if the workflow environment is compromised [6][5]. 4. Token Access: It is important to note that even when persist-credentials is set to false, the GITHUB_TOKEN itself remains available to other actions in the job unless job-level permissions are restricted [7][8]. Therefore, while setting persist-credentials to false is a recommended hardening step, it should be part of a broader security strategy that includes limiting GITHUB_TOKEN permissions [7][5]. For sensitive workflows, you can explicitly opt-out of this behavior by adding the following configuration to your workflow YAML [1][5]: - name: Checkout repository uses: actions/checkout@v4 with: persist-credentials: false
Citations:
- 1: https://github.com/actions/checkout
- 2: https://github.com/actions/checkout/blob/master/adrs/0153-checkout-v2.md
- 3: https://github.com/actions/checkout/tree/v6.0.0
- 4: https://github.com/marketplace/actions/checkout?version=v3.6.0
- 5: GHSA-3959-6v5q-45q2
- 6: https://cheatsheetseries.owasp.org/cheatsheets/GitHub_Actions_Security_Cheat_Sheet.html
- 7: actions/checkout#485
- 8: actions/checkout#2312
🌐 Web query:
GitHub Actions checkout v4 persist-credentials token accessible to later action same job security💡 Result:
When using actions/checkout@v4, the persist-credentials input defaults to true [1][2]. When enabled, the action configures the local Git repository's configuration files (.git/config) with the authentication token (usually the GITHUB_TOKEN) used to perform the checkout [1][3]. Security Implications: 1. Accessibility: Because the token is written to the disk in cleartext within the workspace, any subsequent steps or actions running within the same job have the ability to read the token from the.git/config file [4][3]. 2. Artifact Leakage (ArtiPACKED): A significant security risk arises if a later step in the same job uploads build artifacts (e.g., using actions/upload-artifact) [3]. If the.git directory or its configuration files are included in the uploaded artifacts, the persisted token may be leaked to anyone with access to those artifacts [5][3]. This is a known attack vector often referred to as ArtiPACKED [5][3]. 3. Token Scope: While the GITHUB_TOKEN is scoped to the repository and expires at the end of the job, a compromised token can still be used maliciously within that timeframe, such as to push code, modify releases, or access other secrets if the token has sufficient permissions [5][6]. Recommendation: To enhance security, it is best practice to set persist-credentials to false unless it is strictly necessary for your workflow to perform authenticated Git operations [1][3]: - uses: actions/checkout@v4 with: persist-credentials: false If you must use persist-credentials: true, ensure that no subsequent steps in the job include the.git directory in any artifacts uploaded to GitHub or other services [3]. Additionally, always adhere to the principle of least privilege by configuring appropriate permissions for the GITHUB_TOKEN in your workflow file [4].
Citations:
- 1: https://github.com/actions/checkout/blob/v4/README.md
- 2: https://github.com/actions/checkout/blob/v4/action.yml
- 3: GHSA-3959-6v5q-45q2
- 4: actions/checkout#485
- 5: https://nvd.nist.gov/vuln/detail/cve-2026-40313
- 6: https://github.com/github/docs/blob/main/content/actions/concepts/security/compromised-runners.md
🌐 Web query:
actions/checkout v4 persist-credentials where token stored .git/config runner temp README💡 Result:
In versions of actions/checkout up to and including v5, the persist-credentials input (which defaults to true) causes the authentication token or SSH key to be stored directly in the local.git/config file of the checked-out repository [1][2][3]. This behavior is designed to allow subsequent scripts in the workflow to run authenticated git commands [1][4]. Starting with actions/checkout v6, this mechanism was updated to store these credentials in a temporary file located within the directory specified by the $RUNNER_TEMP environment variable, rather than in.git/config [2][3]. This change helps mitigate risks associated with credential leakage, such as the accidental inclusion of the token in workflow artifacts that might be uploaded from the workspace [3][5]. Regardless of the storage location, the action is responsible for removing the credentials during the post-job cleanup phase [1][6][7]. To prevent credentials from being persisted entirely, you can set the persist-credentials input to false [1][3][5]: - uses: actions/checkout@v4 with: persist-credentials: false
Citations:
- 1: https://github.com/actions/checkout/blob/v4/README.md
- 2: actions/checkout@v5.0.1...v6.0.0
- 3: https://sisaku-security.github.io/lint/docs/rules/artipacked/
- 4: https://github.com/actions/checkout/blob/v4/action.yml
- 5: https://yossarian.net/til/post/actions-checkout-can-leak-github-credentials/
- 6: https://github.com/actions/checkout
- 7: https://github.com/actions/checkout/tree/cbb722410c2e876e24abbe8de2cc27693e501dcb
Disable checkout credential persistence
actions/checkout@v4still persists the repo token by default, so a compromised Lamatic step could read it from the workspace. Setpersist-credentials: falsehere.🧰 Tools
🪛 zizmor (1.26.1)
[warning] 16-17: credential persistence through GitHub Actions artifacts (artipacked): does not set persist-credentials: false
(artipacked)
[error] 17-17: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)
(unpinned-uses)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In @.github/workflows/lamatic-update.yml around lines 16 - 17, Update the actions/checkout@v4 step in the Checkout repository workflow step to set persist-credentials to false, preventing the repository token from being retained in the workspace.Source: Linters/SAST tools
17-20: 🔒 Security & Privacy | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash set -euo pipefail printf 'File: .github/workflows/lamatic-update.yml\n' cat -n .github/workflows/lamatic-update.yml printf '\nNearby action pins in workflows:\n' rg -n "uses:\s*(actions/checkout|Lamatic/sync-flows-to-lamatic)@" .github/workflows -nRepository: Lamatic/AgentKit
Length of output: 1570
🏁 Script executed:
#!/bin/bash set -euo pipefail python3 - <<'PY' from pathlib import Path import re path = Path('.github/workflows/lamatic-update.yml') text = path.read_text() for m in re.finditer(r'uses:\s*([^\s]+)', text): print(m.group(1)) PYRepository: Lamatic/AgentKit
Length of output: 207
🏁 Script executed:
#!/bin/bash set -euo pipefail # Show the workflow with surrounding context and line numbers. sed -n '1,120p' .github/workflows/lamatic-update.yml | cat -nRepository: Lamatic/AgentKit
Length of output: 1032
Pin both workflow actions to immutable SHAs in
.github/workflows/lamatic-update.yml:17-20.
actions/checkout@v4andLamatic/sync-flows-to-lamatic@v1are mutable refs; full commit pins reduce supply-chain risk in a workflow that has repo access and deployment credentials.🧰 Tools
🪛 zizmor (1.26.1)
[error] 17-17: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)
(unpinned-uses)
[error] 20-20: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)
(unpinned-uses)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In @.github/workflows/lamatic-update.yml around lines 17 - 20, Pin both actions in the workflow—actions/checkout and Lamatic/sync-flows-to-lamatic—to full immutable commit SHAs instead of the mutable v4 and v1 tags, preserving their existing action versions and workflow behavior.Source: Linters/SAST tools
kits/google-reviews-ai-manager/agent.md (1)
3-15: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win
Mission detail: clear the configured Markdown lint warnings.
Insert blank lines after the headings on Lines 3, 6, and 11.
🧰 Tools
🪛 markdownlint-cli2 (0.23.0)
[warning] 3-3: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below(MD022, blanks-around-headings)
[warning] 6-6: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below(MD022, blanks-around-headings)
[warning] 11-11: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below(MD022, blanks-around-headings)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@kits/google-reviews-ai-manager/agent.md` around lines 3 - 15, Update the Markdown in agent.md by inserting a blank line immediately after the headings Role, Tone & Style, and Capabilities, while preserving all existing text and list content.Source: Linters/SAST tools
kits/google-reviews-ai-manager/apps/app/actions/gmb.ts (1)
19-21: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash set -euo pipefail echo "== gmb.ts ==" sed -n '1,220p' kits/google-reviews-ai-manager/apps/app/actions/gmb.ts echo echo "== search for abort/timeout helpers in app ==" rg -n "AbortController|signal:|timeout|bounded fetch|fetchWith|withTimeout|deadline" kits/google-reviews-ai-manager/apps/app -g '!**/node_modules/**' || true echo echo "== next docs present? ==" fd -a "app-router.mdx" node_modules/next/dist/docs 2>/dev/null | head -n 20 || trueRepository: Lamatic/AgentKit
Length of output: 3996
Put a deadline on the Google API fetches Route the four
fetchcalls inkits/google-reviews-ai-manager/apps/app/actions/gmb.tsthrough a shared helper that attaches anAbortSignaltimeout and returns a consistent timeout error.📍 Affects 1 file
kits/google-reviews-ai-manager/apps/app/actions/gmb.ts#L19-L21(this comment)kits/google-reviews-ai-manager/apps/app/actions/gmb.ts#L37-L39kits/google-reviews-ai-manager/apps/app/actions/gmb.ts#L61-L63kits/google-reviews-ai-manager/apps/app/actions/gmb.ts#L86-L93🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@kits/google-reviews-ai-manager/apps/app/actions/gmb.ts` around lines 19 - 21, Add a shared fetch helper in gmb.ts that applies an AbortSignal timeout and converts timeout aborts into one consistent timeout error, then route all four Google API fetches through it: kits/google-reviews-ai-manager/apps/app/actions/gmb.ts lines 19-21, 37-39, 61-63, and 86-93. Preserve each request’s existing URL, headers, and response handling while replacing direct fetch calls with the helper.kits/google-reviews-ai-manager/apps/app/actions/orchestrate.ts (5)
4-12: 🔒 Security & Privacy | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
set -e printf '\n== file list ==\n' git ls-files 'kits/google-reviews-ai-manager/apps/app/actions/*' 'kits/google-reviews-ai-manager/apps/app/**/*' | sed -n '1,200p' printf '\n== orchestrate.ts outline ==\n' ast-grep outline kits/google-reviews-ai-manager/apps/app/actions/orchestrate.ts --view expanded || true printf '\n== read orchestrate.ts ==\n' cat -n kits/google-reviews-ai-manager/apps/app/actions/orchestrate.ts | sed -n '1,220p' printf '\n== search for generateReply usages ==\n' rg -n "generateReply\(" kits/google-reviews-ai-manager/apps/app -S || true printf '\n== search for auth/session/middleware references ==\n' rg -n "middleware|auth\\(|session|getServerSession|next-auth|clerk|supabase|tenant|authorize|authorization" kits/google-reviews-ai-manager/apps/app -S || trueRepository: Lamatic/AgentKit
Length of output: 5913
🏁 Script executed:
set -e printf '\n== page.tsx ==\n' cat -n kits/google-reviews-ai-manager/apps/app/page.tsx | sed -n '1,220p' printf '\n== ReviewList.tsx ==\n' cat -n kits/google-reviews-ai-manager/apps/app/components/ReviewList.tsx | sed -n '1,260p' printf '\n== middleware/auth boundary search ==\n' git ls-files 'kits/google-reviews-ai-manager/apps/**/middleware.ts' 'kits/google-reviews-ai-manager/apps/**/middleware.js' 'kits/google-reviews-ai-manager/apps/**/middleware.tsx' | sed -n '1,200p' rg -n "getServerSession\\(|middleware|authOptions|SessionProvider|useSession\\(" kits/google-reviews-ai-manager/apps/app -S || trueRepository: Lamatic/AgentKit
Length of output: 15114
Add a session check inside
generateReply. The page gatesReviewListbehindgetServerSession(), but this Server Action still needs its own caller check before it spends Lamatic quota or accepts review text.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@kits/google-reviews-ai-manager/apps/app/actions/orchestrate.ts` around lines 4 - 12, Add an authenticated-session check at the start of generateReply, before reading or sending review data to Lamatic. Use the existing server-session mechanism and return an appropriate error when no session is present; preserve the current environment-variable validation for authenticated callers.
8-12: 🔒 Security & Privacy | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash set -euo pipefail echo "== target file ==" sed -n '1,220p' kits/google-reviews-ai-manager/apps/app/actions/orchestrate.ts | cat -n echo echo "== search for LAMATIC_API_URL and fallback host ==" rg -n --hidden --no-ignore-vcs 'LAMATIC_API_URL|toufiqsorganization806-toufiqsproject110\.lamatic\.dev|lamatic\.dev/graphql' kits/google-reviews-ai-manager/apps -S echo echo "== next docs candidates ==" fd -a 'README.md' node_modules/next/dist/docs 2>/dev/null | head -n 20Repository: Lamatic/AgentKit
Length of output: 3444
🏁 Script executed:
#!/bin/bash set -euo pipefail python3 - <<'PY' from pathlib import Path p = Path('kits/google-reviews-ai-manager/apps/app/actions/orchestrate.ts') text = p.read_text() for i, line in enumerate(text.splitlines(), 1): if 1 <= i <= 220: print(f"{i:4d}: {line}") PYRepository: Lamatic/AgentKit
Length of output: 2992
Mission control: remove the hardcoded tenant fallback.
If
LAMATIC_API_URLis unset, the review payload and bearer token go tohttps://toufiqsorganization806-toufiqsproject110.lamatic.dev/graphql. Make the URL required, or use only a documented environment-neutral default and fail fast on missing config.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@kits/google-reviews-ai-manager/apps/app/actions/orchestrate.ts` around lines 8 - 12, Update the `apiUrl` configuration in the orchestration flow to remove the hardcoded tenant-specific fallback; require `LAMATIC_API_URL` and include it in the existing missing-configuration validation so execution fails fast when it is unset.
40-51: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash set -euo pipefail echo "== orchestrate.ts ==" sed -n '1,220p' kits/google-reviews-ai-manager/apps/app/actions/orchestrate.ts echo echo "== search for timeout/abort handling in app actions ==" rg -n "AbortController|signal:|timeout|setTimeout|clearTimeout|fetch\\(" kits/google-reviews-ai-manager/apps/app -g '*.ts' -g '*.tsx' -g '*.js' -g '*.jsx'Repository: Lamatic/AgentKit
Length of output: 3484
Bound the Lamatic fetch with a timeout. A stalled upstream can leave the Server Action and dashboard request hanging indefinitely. Abort the request and return a controlled error on timeout.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@kits/google-reviews-ai-manager/apps/app/actions/orchestrate.ts` around lines 40 - 51, Update the fetch call in the orchestrate action to use an AbortController-based timeout, aborting stalled Lamatic requests after the configured duration. Catch timeout aborts and return the action’s existing controlled error response, while preserving normal response handling for successful or non-timeout failures.
53-60: 🔒 Security & Privacy | 🟠 Major | ⚡ Quick win
Mission-critical: stop logging and echoing raw provider responses.
resTextmay contain customer review text, generated replies, PII, or internal diagnostics. It is written verbatim to server logs and partially returned to the browser on parse failure. Log only redacted metadata and return a generic client-facing error.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@kits/google-reviews-ai-manager/apps/app/actions/orchestrate.ts` around lines 53 - 60, Remove the raw response logging around resText and replace it with redacted, non-content metadata only. In the JSON.parse error path within the orchestration action, stop including resText in the returned error and return a generic client-facing parse failure message instead.
63-74: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash set -euo pipefail printf '\n== File map ==\n' git ls-files 'kits/google-reviews-ai-manager/apps/app/actions/orchestrate.ts' 'kits/google-reviews-ai-manager/apps/app/**' 'kits/google-reviews-ai-manager/**/ReviewList*' 'kits/google-reviews-ai-manager/**/review*' | sed -n '1,200p' printf '\n== Outline of orchestrate.ts ==\n' ast-grep outline kits/google-reviews-ai-manager/apps/app/actions/orchestrate.ts --view expanded || true printf '\n== Relevant occurrences ==\n' rg -n "executeWorkflow|result\.reply|result\.error|status ===|Lamatic Workflow Error|GraphQL Error|pending|success|failed|error" kits/google-reviews-ai-manager/apps/app kits/google-reviews-ai-manager -g '!**/node_modules/**' || true printf '\n== File size ==\n' wc -l kits/google-reviews-ai-manager/apps/app/actions/orchestrate.ts || trueRepository: Lamatic/AgentKit
Length of output: 13566
🏁 Script executed:
#!/bin/bash set -euo pipefail # Read the specific action and consumer files in small slices if they exist. for f in \ kits/google-reviews-ai-manager/apps/app/actions/orchestrate.ts \ $(rg -l "result\.reply|result\.error" kits/google-reviews-ai-manager/apps/app -g '!**/node_modules/**' || true) do [ -f "$f" ] || continue echo "===== $f =====" nl -ba "$f" | sed -n '1,220p' doneRepository: Lamatic/AgentKit
Length of output: 270
🏁 Script executed:
#!/bin/bash set -euo pipefail read_file() { f="$1" echo "===== $f =====" awk '{printf "%4d %s\n", NR, $0}' "$f" | sed -n '1,220p' echo } read_file kits/google-reviews-ai-manager/apps/app/actions/orchestrate.ts read_file kits/google-reviews-ai-manager/apps/app/components/ReviewList.tsxRepository: Lamatic/AgentKit
Length of output: 13628
🌐 Web query:
Lamatic executeWorkflow GraphQL status success error result response generatedResponse documentation💡 Result:
In Lamatic.ai, the executeWorkflow mutation is the primary GraphQL method used to trigger flows programmatically [1][2]. Key details regarding the execution and response are as follows: Structure of the GraphQL Mutation To execute a flow, you send a POST request to your project's GraphQL endpoint with the following mutation [1][2]: query ExecuteWorkflow($workflowId: String!, $payload: JSON) { executeWorkflow(workflowId: $workflowId, payload: $payload) { status result } } The payload variable should contain the specific input data required by your workflow, and the workflowId is the unique identifier for the flow you wish to trigger [1][3][2]. Response Structure The response from the server follows a standard structure that includes the status of the execution and the result [1][2]: { "data": { "executeWorkflow": { "status": "success", "result": { // Your custom output as configured in the Schema } } } } The status field typically returns success upon a successful execution [1][2]. The result field contains the output generated by your flow, which is dynamically configured within the Schema of the GraphQL Response node in your workflow [1][2]. Error Handling If an error occurs, the GraphQL response will include an errors array or specific error details within the response body [3][4]. Developers are encouraged to check for the presence of the errors field in the JSON response or handle rejection in their client code (e.g., using.catch in JavaScript) to capture and manage API or flow-related failures [3][4]. Detailed error codes and troubleshooting information are available in the official integration documentation [5][6].
Citations:
- 1: https://lamatic.ai/docs/api-integration/integration-guide
- 2: https://lamatic.ai/docs/api-overview
- 3: https://lamatic.ai/docs/studio/studio-keys
- 4: https://github.com/lamatic/docs/blob/main/pages/docs/flow-integration.mdx
- 5: https://lamatic.ai/docs/sdk/integration-guide
- 6: https://lamatic.ai/docs/flow-integration
🏁 Script executed:
#!/bin/bash set -euo pipefail printf '== package references ==\n' rg -n '"lamatic"|from "lamatic"|executeWorkflow|status|generatedResponse|response' \ kits/google-reviews-ai-manager/apps/package.json \ kits/google-reviews-ai-manager/apps/package-lock.json \ kits/google-reviews-ai-manager/apps/app \ -g '!**/node_modules/**' || true printf '\n== next docs presence ==\n' fd -a 'next' kits/google-reviews-ai-manager/apps/node_modules 2>/dev/null | sed -n '1,40p' || true fd -a 'docs' kits/google-reviews-ai-manager/apps/node_modules/next/dist 2>/dev/null | sed -n '1,80p' || trueRepository: Lamatic/AgentKit
Length of output: 2263
Reject anything but an explicit successful workflow reply.
executeWorkflowis expected to returnstatus: "success"on completion, so this should fail fast on any non-success payload and only return{ reply }when the reply field is a string; otherwiseJSON.stringify(anyData)can be posted as the review response.kits/google-reviews-ai-manager/apps/app/actions/orchestrate.ts:67-74🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@kits/google-reviews-ai-manager/apps/app/actions/orchestrate.ts` around lines 63 - 74, Update the executeWorkflow result handling around anyData so it fails fast unless anyData?.status is exactly "success". Only return a reply when the selected response field is a string; for successful payloads without a string reply, return the JSON-serialized anyData as the review response instead of treating arbitrary values as a reply.kits/google-reviews-ai-manager/apps/app/api/auth/[...nextauth]/route.ts (1)
20-28: 🔒 Security & Privacy | 🟠 Major | 🏗️ Heavy lift
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash set -euo pipefail # Map the target file and nearby NextAuth/Next.js context. git ls-files 'kits/google-reviews-ai-manager/apps/app/api/auth/[...nextauth]/route.ts' \ 'kits/google-reviews-ai-manager/apps/app/api/**' \ 'kits/google-reviews-ai-manager/apps/**' | sed -n '1,120p' echo '--- FILE: route.ts ---' cat -n 'kits/google-reviews-ai-manager/apps/app/api/auth/[...nextauth]/route.ts' echo '--- SEARCH: nextauth/session usage ---' rg -n "accessToken|refreshToken|jwt\\(|session\\(" 'kits/google-reviews-ai-manager/apps' -g '!**/node_modules/**' || true echo '--- NEXT DOCS (if present) ---' fd -a 'auth' 'node_modules/next/dist/docs' 2>/dev/null | sed -n '1,80p' || true fd -a 'next-auth' 'node_modules/next/dist/docs' 2>/dev/null | sed -n '1,80p' || trueRepository: Lamatic/AgentKit
Length of output: 3372
🏁 Script executed:
#!/bin/bash set -euo pipefail # If the docs exist, inspect the relevant Next.js auth guidance lightly. if [ -d 'node_modules/next/dist/docs' ]; then echo '--- DOCS TREE ---' fd -a '' 'node_modules/next/dist/docs' | sed -n '1,120p' fiRepository: Lamatic/AgentKit
Length of output: 154
🏁 Script executed:
#!/bin/bash set -euo pipefail # Read the target file and the minimal surrounding app structure. echo '--- route.ts ---' cat -n 'kits/google-reviews-ai-manager/apps/app/api/auth/[...nextauth]/route.ts' echo '--- related auth files ---' fd -a '' 'kits/google-reviews-ai-manager/apps/app/api/auth' | sed -n '1,120p' echo '--- next docs snippets under node_modules/next/dist/docs ---' if [ -d 'node_modules/next/dist/docs' ]; then fd -a '' 'node_modules/next/dist/docs' | sed -n '1,120p' else echo 'node_modules/next/dist/docs not present' fiRepository: Lamatic/AgentKit
Length of output: 1615
🏁 Script executed:
#!/bin/bash set -euo pipefail # Inspect the Google Business actions and auth-related helpers. echo '--- gmb.ts ---' cat -n 'kits/google-reviews-ai-manager/apps/app/actions/gmb.ts' echo '--- search for getServerSession / auth usage ---' rg -n "getServerSession|useSession|getSession|authOptions|session.accessToken|accessToken" 'kits/google-reviews-ai-manager/apps/app' -g '!**/node_modules/**'Repository: Lamatic/AgentKit
Length of output: 5891
🏁 Script executed:
#!/bin/bash set -euo pipefail echo '--- app/page.tsx ---' cat -n 'kits/google-reviews-ai-manager/apps/app/page.tsx' echo '--- AGENTS.md ---' cat -n 'kits/google-reviews-ai-manager/apps/AGENTS.md' echo '--- nextauth package version ---' node - <<'JS' const p = require('./kits/google-reviews-ai-manager/apps/package.json'); console.log(p.dependencies?.['next-auth'] || p.devDependencies?.['next-auth'] || 'missing'); console.log(p.dependencies?.next || p.devDependencies?.next || 'missing'); JSRepository: Lamatic/AgentKit
Length of output: 1681
🏁 Script executed:
#!/bin/bash set -euo pipefail echo '--- app/page.tsx ---' cat -n 'kits/google-reviews-ai-manager/apps/app/page.tsx' echo '--- AGENTS.md ---' cat -n 'kits/google-reviews-ai-manager/apps/AGENTS.md' echo '--- nextauth package version ---' node - <<'JS' const p = require('./kits/google-reviews-ai-manager/apps/package.json'); console.log('next-auth:', p.dependencies?.['next-auth'] || p.devDependencies?.['next-auth'] || 'missing'); console.log('next:', p.dependencies?.next || p.devDependencies?.next || 'missing'); JSRepository: Lamatic/AgentKit
Length of output: 1698
Keep the Google bearer token out of
session.session.accessTokenis exposed through the NextAuth session response, and the JWT callback still drops refresh/expiry state, so the token cannot be renewed safely before it expires. Keep the provider credential server-side only, persist refresh metadata, and have the GMB actions read the refreshed token there instead of fromsession.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@kits/google-reviews-ai-manager/apps/app/api/auth/`[...nextauth]/route.ts around lines 20 - 28, The NextAuth callbacks in jwt and session currently expose the Google bearer token and omit renewal metadata. Keep access and refresh credentials plus expiry state in the server-side JWT, stop assigning token.accessToken in session, and update the GMB actions to obtain and refresh the provider token from the JWT/server-side auth state rather than session.accessToken.kits/google-reviews-ai-manager/apps/app/components/ReviewList.tsx (1)
181-408: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚖️ Poor tradeoff
Agent, this safehouse has three floors crammed into one room.
The render method mixes top bar, metrics, filter bar, review feed, and a location modal in one 400+ line component. Extracting
MetricsBar,FilterBar,ReviewCard, andLocationModalas siblings would make future missions (edits) far less risky.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@kits/google-reviews-ai-manager/apps/app/components/ReviewList.tsx` around lines 181 - 408, Refactor the main ReviewList render into sibling components for the top-level sections: extract the metrics row into MetricsBar, filters into FilterBar, each mapped review into ReviewCard, and the location selector overlay into LocationModal. Move each section’s required data, callbacks, and state handlers into explicit props while preserving the existing behavior, styling, and conditional rendering in ReviewList.kits/google-reviews-ai-manager/apps/app/globals.css (1)
22-26: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
Mission note: apply the configured Geist font.
layout.tsxloads Geist and exposes--font-geist-sans, but this declaration forces Arial globally. Use the Geist variable first so the configured application typography is actually visible.Suggested fix
body { background: var(--background); color: var(--foreground); - font-family: Arial, Helvetica, sans-serif; + font-family: var(--font-geist-sans), Arial, Helvetica, sans-serif; }📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.body { background: var(--background); color: var(--foreground); font-family: var(--font-geist-sans), Arial, Helvetica, sans-serif; }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@kits/google-reviews-ai-manager/apps/app/globals.css` around lines 22 - 26, Update the global body font-family declaration to use the configured --font-geist-sans variable first, retaining the existing fallback fonts afterward. Remove Arial as the primary font so the Geist font loaded by layout.tsx is applied globally.kits/google-reviews-ai-manager/apps/app/layout.tsx (1)
15-18: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
Mission-critical branding: replace the default metadata.
The deployed application will display “Create Next App” in browser tabs and link previews. Use Google Reviews AI Manager-specific title and description values.
Suggested fix
export const metadata: Metadata = { - title: "Create Next App", - description: "Generated by create next app", + title: "Google Reviews AI Manager", + description: "Generate and publish AI-assisted replies to Google Reviews.", };📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.export const metadata: Metadata = { title: "Google Reviews AI Manager", description: "Generate and publish AI-assisted replies to Google Reviews.", };🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@kits/google-reviews-ai-manager/apps/app/layout.tsx` around lines 15 - 18, Update the exported metadata object in layout.tsx, replacing the default “Create Next App” title and generated description with Google Reviews AI Manager-specific title and description values.kits/google-reviews-ai-manager/apps/app/page.tsx (1)
1-13: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash set -euo pipefail # Locate the relevant files and inspect the surrounding code. git ls-files 'kits/google-reviews-ai-manager/apps/app/page.tsx' \ 'kits/google-reviews-ai-manager/apps/**/gmb.ts' \ 'kits/google-reviews-ai-manager/apps/**/route.ts' \ 'kits/google-reviews-ai-manager/apps/**/[...nextauth]/*' \ 'kits/google-reviews-ai-manager/apps/**/authOptions*' \ 'node_modules/next/dist/docs/**/*' | sed -n '1,200p' printf '\n--- page.tsx ---\n' cat -n kits/google-reviews-ai-manager/apps/app/page.tsx | sed -n '1,120p' printf '\n--- gmb.ts candidates ---\n' for f in $(git ls-files 'kits/google-reviews-ai-manager/apps/**/gmb.ts'); do echo "### $f" cat -n "$f" | sed -n '1,200p' done printf '\n--- nextauth route candidates ---\n' for f in $(git ls-files 'kits/google-reviews-ai-manager/apps/**/route.ts' 'kits/google-reviews-ai-manager/apps/**/[...nextauth]/*'); do case "$f" in *route.ts|*[[]...nextauth[]]/*) echo "### $f" cat -n "$f" | sed -n '1,220p' ;; esac done printf '\n--- next docs candidates ---\n' fd -a 'getServerSession|NextAuth' node_modules/next/dist/docs 2>/dev/null | sed -n '1,120p' EOFRepository: Lamatic/AgentKit
Length of output: 7293
🏁 Script executed:
#!/bin/bash set -euo pipefail # Locate the relevant files and inspect the surrounding code. git ls-files 'kits/google-reviews-ai-manager/apps/app/page.tsx' \ 'kits/google-reviews-ai-manager/apps/**/gmb.ts' \ 'kits/google-reviews-ai-manager/apps/**/route.ts' \ 'kits/google-reviews-ai-manager/apps/**/[...nextauth]/*' \ 'kits/google-reviews-ai-manager/apps/**/authOptions*' \ 'node_modules/next/dist/docs/**/*' | sed -n '1,200p' printf '\n--- page.tsx ---\n' cat -n kits/google-reviews-ai-manager/apps/app/page.tsx | sed -n '1,120p' printf '\n--- gmb.ts candidates ---\n' for f in $(git ls-files 'kits/google-reviews-ai-manager/apps/**/gmb.ts'); do echo "### $f" cat -n "$f" | sed -n '1,200p' done printf '\n--- nextauth route candidates ---\n' for f in $(git ls-files 'kits/google-reviews-ai-manager/apps/**/route.ts' 'kits/google-reviews-ai-manager/apps/**/[...nextauth]/*'); do case "$f" in *route.ts|*[[]...nextauth[]]/*) echo "### $f" cat -n "$f" | sed -n '1,220p' ;; esac done printf '\n--- next docs candidates ---\n' fd -a 'getServerSession|NextAuth' node_modules/next/dist/docs 2>/dev/null | sed -n '1,120p'Repository: Lamatic/AgentKit
Length of output: 7293
🏁 Script executed:
#!/bin/bash set -euo pipefail # Read the relevant NextAuth/Next.js local docs and type definitions if present. printf '\n--- next docs around server session ---\n' fd -a 'server session|getServerSession|authOptions|NextAuth' node_modules/next/dist/docs 2>/dev/null | sed -n '1,200p' printf '\n--- next-auth type definitions ---\n' fd -a 'next-auth' node_modules 2>/dev/null | sed -n '1,200p'Repository: Lamatic/AgentKit
Length of output: 195
🌐 Web query:
next-auth v4 getServerSession authOptions app router docs💡 Result:
In NextAuth.js v4, the getServerSession function is the recommended way to retrieve the session object within the Next.js App Router [1][2]. Unlike the older getSession method, getServerSession does not perform an additional network request, which improves performance [1][3]. Setup and Usage To use getServerSession in the App Router, you must first define and export your authentication configuration (authOptions) in your Route Handler file [1][4]. 1. Configure authOptions: Define your NextAuth configuration in app/api/auth/[...nextauth]/route.ts [4][5]. // app/api/auth/[...nextauth]/route.ts import NextAuth from "next-auth"; export const authOptions = { // your providers and callbacks }; const handler = NextAuth(authOptions); export { handler as GET, handler as POST }; 2. Use getServerSession in Server Components: Import both getServerSession and your authOptions to retrieve the session [1][6]. // app/page.tsx (or any Server Component) import { getServerSession } from "next-auth"; import { authOptions } from "./api/auth/[...nextauth]/route"; export default async function Page { const session = await getServerSession(authOptions); if (!session) { return
Access Denied; } returnWelcome, {session.user?.name}; } Key Considerations - Server Components: getServerSession is designed to run in server-side contexts, including Server Components and Route Handlers [1][3]. - Middleware Limitations: You cannot use getServerSession inside Next.js Middleware because Middleware runs on the Edge Runtime, which does not support the necessary Node.js APIs [7]. For protecting routes at the middleware level in v4, you typically use the provided withAuth middleware [7]. - Client Components: While getServerSession is for the server, you should continue to use the useSession hook for client-side components to manage session state across your application [2][3]. - Migration Note: If you are planning to migrate to NextAuth.js (Auth.js) v5, note that the API has changed significantly, replacing getServerSession with a simpler auth method [7][8]. The v4 approach described above is specific to the v4 lifecycle [7].Citations:
- 1: https://next-auth.js.org/configuration/nextjs
- 2: https://next-auth.js.org/getting-started/client
- 3: https://next-auth.js.org/tutorials/securing-pages-and-api-routes
- 4: https://next-auth.js.org/configuration/initialization
- 5: https://next-auth.js.org/getting-started/example
- 6: https://stackoverflow.com/questions/75413452/how-do-i-use-next-auth-getserversession-in-next-js-13-beta-server-component-in-a
- 7: https://stackoverflow.com/questions/77975247/can-nextauth-middleware-work-to-protect-pages-when-using-nextjs-14-and-the-app-r
- 8: https://authjs.dev/reference/nextjs
Pass
authOptionsintogetServerSession— this page should use the same NextAuth config asapp/actions/gmb.ts; otherwise the session check can fail and signed-in users get sent back to the sign-in screen.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@kits/google-reviews-ai-manager/apps/app/page.tsx` around lines 1 - 13, Update the Home function’s getServerSession call to pass the shared authOptions configuration used by app/actions/gmb.ts, ensuring this page validates sessions with the same NextAuth setup.kits/google-reviews-ai-manager/apps/package.json (1)
11-18: 📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash set -euo pipefail printf '\n== Relevant files ==\n' git ls-files 'kits/google-reviews-ai-manager/apps/**' | sed 's#^`#-` #' printf '\n== package.json ==\n' cat -n kits/google-reviews-ai-manager/apps/package.json printf '\n== lucide/react-icons usage ==\n' rg -n --hidden --glob '!**/node_modules/**' --glob '!**/.git/**' '\b(lucide-react|react-icons)\b' kits/google-reviews-ai-manager/apps kits/google-reviews-ai-manager -g '!**/package-lock.json' -g '!**/pnpm-lock.yaml' -g '!**/yarn.lock' printf '\n== icon import statements ==\n' rg -n --hidden --glob '!**/node_modules/**' --glob '!**/.git/**' 'from [\"\x27](lucide-react|react-icons)[\"\x27]' kits/google-reviews-ai-manager/apps kits/google-reviews-ai-managerRepository: Lamatic/AgentKit
Length of output: 3336
🏁 Script executed:
#!/bin/bash set -euo pipefail printf '\n== package.json ==\n' cat -n kits/google-reviews-ai-manager/apps/package.json printf '\n== icon-related files ==\n' rg -n --hidden --glob '!**/node_modules/**' --glob '!**/.git/**' '\b(lucide-react|react-icons)\b' kits/google-reviews-ai-manager/apps kits/google-reviews-ai-managerRepository: Lamatic/AgentKit
Length of output: 2434
🏁 Script executed:
#!/bin/bash set -euo pipefail cat -n kits/google-reviews-ai-manager/apps/package.jsonRepository: Lamatic/AgentKit
Length of output: 968
🌐 Web query:
lucide-react kit standard replace react-icons Next.js app package.json💡 Result:
Migrating from react-icons to lucide-react in a Next.js application is a recommended practice in 2026 for improved bundle size, better tree-shaking, and a consistent design language [1][2]. Installation and Configuration To begin the transition, install the package using your preferred package manager [3][4]: npm install lucide-react For Next.js applications, especially when using the App Router, ensuring efficient tree-shaking is critical. In your next.config.js, you can optimize package imports to prevent bloat [5]: // next.config.js /
@type{import('next').NextConfig} */ const nextConfig = { experimental: { optimizePackageImports: ['lucide-react'], }, }; module.exports = nextConfig; If you encounter issues with dynamic imports or specific build setups, you can also add the package to transpilePackages [6]: // next.config.js const nextConfig = { transpilePackages: ['lucide-react'], }; Migration Strategy 1. Identify Replacements: Lucide-react uses a naming convention similar to the Feather icon set (which is commonly used within react-icons). Often, a one-to-one migration is possible by simply removing the prefix used by react-icons (e.g., FiSearch becomes Search) [7]. 2. Refactor Imports: Replace your react-icons import statements with named imports from lucide-react [7]: // Before: react-icons import { FiSearch, FiSettings } from 'react-icons/fi'; // After: lucide-react import { Search, Settings } from 'lucide-react'; 3. Handle Missing Icons: Lucide does not include brand logos or niche icon sets found in react-icons [1][8]. For these, keep the specific icons you need or use dedicated SVG files to avoid maintaining large legacy dependencies [1][7]. Benefits - Bundle Size: Lucide-react is fully tree-shakable, significantly reducing the production bundle compared to the CJS-heavy react-icons [1][7]. - Modern API: It provides a consistent interface where you can control size, color, and stroke width directly via props, making it highly compatible with Tailwind CSS utilities [9][10]. - TypeScript Support: It offers first-class TypeScript support, reducing runtime errors associated with icon prop mismatches [1][9].Citations:
- 1: https://iconsearch.info/blog/react-icons-vs-lucide-react-2026
- 2: https://medium.nkcroft.com/the-hidden-bundle-cost-of-react-icons-why-lucide-wins-in-2026-1ddb74c1a86c
- 3: https://lucide.dev/guide/installation
- 4: https://github.com/lucide-icons/lucide/blob/main/packages/lucide-react/README.md
- 5: https://devradar.dev/check/lucide-react-icons-with-nextjs-bundle-size
- 6: lucide-icons/lucide@c5cfbed
- 7: https://iconsearch.info/blog/icon-subsetting-nextjs-bundle-size-optimization
- 8: shadcn-ui/ui#2603
- 9: https://lucide.dev/guide/react
- 10: https://codingarchitect.dev/blog/choosing-the-right-icons-for-next-js-with-tailwind-css-project/
🏁 Script executed:
#!/bin/bash set -euo pipefail printf '\n== kit guidance files ==\n' for f in kits/google-reviews-ai-manager/apps/AGENTS.md kits/google-reviews-ai-manager/apps/CLAUDE.md kits/google-reviews-ai-manager/apps/README.md; do if [ -f "$f" ]; then echo "--- $f" cat -n "$f" | sed -n '1,260p' fi done printf '\n== lucide usage across repo ==\n' rg -n --hidden --glob '!**/node_modules/**' --glob '!**/.git/**' '\blucide-react\b' . printf '\n== react-icons usage across repo ==\n' rg -n --hidden --glob '!**/node_modules/**' --glob '!**/.git/**' '\breact-icons\b' .Repository: Lamatic/AgentKit
Length of output: 50374
Swap
react-iconsforlucide-reactReplace the dependency here and update the imports inkits/google-reviews-ai-manager/apps/app/components/ReviewList.tsx(and the lockfile) to match the kit’s Lucide icon standard.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@kits/google-reviews-ai-manager/apps/package.json` around lines 11 - 18, Replace the react-icons dependency with lucide-react in the package configuration, then update icon imports and usages in ReviewList.tsx to use Lucide equivalents while preserving the existing UI behavior. Regenerate the lockfile so it reflects the dependency swap and removes react-icons.Source: Coding guidelines
kits/google-reviews-ai-manager/apps/README.md (1)
1-36: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win
Mission brief: replace scaffold documentation with kit setup instructions.
This README never explains copying
.env.example, configuring Google OAuth and its callback URL, setting Lamatic project/flow variables, or updatingNEXTAUTH_URLfor deployment. Add those steps before merge so the application is actually operable from the documented procedure.🧰 Tools
🪛 markdownlint-cli2 (0.23.0)
[warning] 1-1: First line in a file should be a top-level heading
(MD041, first-line-heading, first-line-h1)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@kits/google-reviews-ai-manager/apps/README.md` around lines 1 - 36, Replace the scaffold content in the README with kit-specific setup instructions covering dependency installation, copying .env.example to the active environment file, configuring Google OAuth credentials and callback URL, setting the Lamatic project and flow variables, starting the application, and updating NEXTAUTH_URL for deployments. Remove the generic create-next-app guidance and document the required environment variable names using the repository’s existing configuration symbols.kits/google-reviews-ai-manager/prompts/my-first-flow_llm-node_user_1.md (1)
1-1: 🎯 Functional Correctness | 🔴 Critical | ⚡ Quick win
🧩 Analysis chain
🌐 Web query:
Lamatic Studio LLM node prompt reference trigger input variable syntax curly braces💡 Result:
In Lamatic Studio, you use double curly braces
{{ }}to reference input variables within LLM node prompt templates [1][2]. Key syntax and usage details: - Variable Reference: To inject a dynamic variable, enclose the variable path in double curly braces, such as{{triggerNode_1.output.chatMessage}}[1][2]. - Insertion Method: You can either manually type{{to trigger a variable selection menu in the prompt editor or use the interface's built-in "insert Variable" button to select available variables [1][2][3]. - YAML Configuration: When configuring nodes via YAML, the variable syntax remains the same within thepromptTemplatestring (e.g.,promptTemplate: "Prompt text here {{triggerNode_1.output.input}}"), though in some contexts, such as theattachmentsfield or certain templates, a dollar sign prefix might appear in documentation examples (e.g.,${{triggerNode_1.output.topic}}), though the standard variable reference is{{variableName}}[4][5][6][7]. For best practice, utilize the Prompt IDE or editor interface to select variables, which ensures the correct pathing is automatically applied [1][2][3].Citations:
- 1: https://lamatic.ai/guides/tutorials/prompt-engineering-with-lamatic
- 2: https://github.com/lamatic/docs/blob/main/pages/guides/tutorials/prompt-engineering-with-lamatic.mdx
- 3: https://lamatic.ai/guides/tutorials/get-started
- 4: https://lamatic.ai/docs/nodes/ai/multimodal-node
- 5: https://lamatic.ai/docs/flows/flow-config
- 6: https://lamatic.ai/docs/nodes/ai/generate-image-node
- 7: https://lamatic.ai/docs/nodes/ai/generate-json-node
🏁 Script executed:
#!/bin/bash set -euo pipefail printf '\n== Files ==\n' git ls-files 'kits/google-reviews-ai-manager/**' | sed 's#^`#-` #' printf '\n== Prompt file ==\n' sed -n '1,80p' 'kits/google-reviews-ai-manager/prompts/my-first-flow_llm-node_user_1.md' | cat -n printf '\n== Flow file references ==\n' rg -n --hidden --no-ignore-vcs 'my-first-flow_llm-node_user_1\.md|reviewText|starRating|promptTemplate|prompts/' 'kits/google-reviews-ai-manager' -S printf '\n== Nearby prompt files ==\n' find 'kits/google-reviews-ai-manager/prompts' -maxdepth 1 -type f | sortRepository: Lamatic/AgentKit
Length of output: 4612
🏁 Script executed:
#!/bin/bash set -euo pipefail printf '\n== Flow outline ==\n' ast-grep outline 'kits/google-reviews-ai-manager/flows/my-first-flow.ts' --view expanded printf '\n== Prompt usage in flow ==\n' sed -n '1,140p' 'kits/google-reviews-ai-manager/flows/my-first-flow.ts' | cat -n printf '\n== Any curly-brace variable examples in this kit ==\n' rg -n --hidden --no-ignore-vcs '\{\{[^}]+\}\}' 'kits/google-reviews-ai-manager' -SRepository: Lamatic/AgentKit
Length of output: 4801
Replace the literal review placeholders with Lamatic interpolation —
[starRating variable]and[reviewText variable]are plain text here, so the LLM never sees the trigger values. Use the trigger fields instead, e.g.{{trigger.output.starRating}}and{{trigger.output.reviewText}}.🧰 Tools
🪛 markdownlint-cli2 (0.23.0)
[warning] 1-1: First line in a file should be a top-level heading
(MD041, first-line-heading, first-line-h1)
[warning] 1-1: Files should end with a single newline character
(MD047, single-trailing-newline)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@kits/google-reviews-ai-manager/prompts/my-first-flow_llm-node_user_1.md` at line 1, Update the prompt text in the user message to replace the literal [starRating variable] and [reviewText variable] placeholders with Lamatic trigger interpolation using trigger.output.starRating and trigger.output.reviewText, so the LLM receives the actual review values.kits/google-reviews-ai-manager/README.md (2)
1-72: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win
Mission detail: clear the configured Markdown lint warnings.
Add a Markdown H1 or adjust the lint configuration, then add the required blank lines around headings and fenced blocks.
🧰 Tools
🪛 markdownlint-cli2 (0.23.0)
[warning] 1-1: First line in a file should be a top-level heading
(MD041, first-line-heading, first-line-h1)
[warning] 17-17: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below(MD022, blanks-around-headings)
[warning] 20-20: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below(MD022, blanks-around-headings)
[warning] 38-38: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below(MD022, blanks-around-headings)
[warning] 49-49: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below(MD022, blanks-around-headings)
[warning] 50-50: Fenced code blocks should be surrounded by blank lines
(MD031, blanks-around-fences)
[warning] 59-59: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below(MD022, blanks-around-headings)
[warning] 61-61: Fenced code blocks should be surrounded by blank lines
(MD031, blanks-around-fences)
[warning] 63-63: Fenced code blocks should be surrounded by blank lines
(MD031, blanks-around-fences)
[warning] 68-68: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below(MD022, blanks-around-headings)
[warning] 69-69: Fenced code blocks should be surrounded by blank lines
(MD031, blanks-around-fences)
[warning] 71-71: Fenced code blocks should be surrounded by blank lines
(MD031, blanks-around-fences)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@kits/google-reviews-ai-manager/README.md` around lines 1 - 72, Update the README Markdown structure to satisfy the configured lint rules: add a Markdown H1 (or explicitly adjust the lint configuration), and insert required blank lines before and after headings and fenced code blocks. Preserve the existing content and presentation while ensuring all sections pass Markdown linting.Source: Linters/SAST tools
38-43: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win
Mission detail: correct the declared framework version.
Line 39 says Next.js 15, while
kits/google-reviews-ai-manager/apps/package.jsondeclares 16.2.10. Update the stack description to the shipped version.🧰 Tools
🪛 markdownlint-cli2 (0.23.0)
[warning] 38-38: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below(MD022, blanks-around-headings)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@kits/google-reviews-ai-manager/README.md` around lines 38 - 43, Update the Next.js version in the README’s “Tech Stack” section to match the shipped version declared in the apps package.json: 16.2.10. Leave the other stack entries unchanged.lamatic/flows/MyFirstFlow.ts (1)
42-52: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash set -euo pipefail # Inspect the target file with line numbers sed -n '1,180p' lamatic/flows/MyFirstFlow.ts | cat -n # Search for prompt interpolation / variable syntax examples in the repo rg -n "\[.*variable\]|\{\{.*\}\}|\$\{.*\}|prompt|interpolat|template" lamatic -SRepository: Lamatic/AgentKit
Length of output: 5533
🏁 Script executed:
#!/bin/bash set -euo pipefail # Search the repository for docs/examples that mention prompt variable syntax or interpolation rg -n "\[\w+ variable\]|\{\{\w+.*\}\}|\bvariable\b|\binterpolation\b|\btemplate\b|\bprompt\b" . -S --glob '!*.log' --glob '!node_modules/**' # Look for any README/docs in the repo that mention Lamatic or prompt formatting fd -a -t f 'README*|*.md|*.mdx|*.txt' .Repository: Lamatic/AgentKit
Length of output: 50373
🌐 Web query:
Lamatic prompt variable interpolation syntax [name variable] {{variable}} prompts documentation💡 Result:
Lamatic uses double curly brace syntax {{variableName}} for variable interpolation within prompts and configurations [1][2][3]. Key details regarding this syntax include: Interpolation Syntax: To inject dynamic variables into a prompt template, use the format {{variableName}} [1][4]. Usage in Prompts: You can type {{ directly in the prompt editor to trigger a variable selection menu [1]. These variables are used to parameterize prompts or personalize content [1]. Usage in Workflow Nodes: When referencing the output of another node within a flow configuration, the syntax is {{nodeId.output.field}} [2][3]. Variable Management: The Variable Node allows you to define custom variables, which can then be referenced in other nodes using syntax such as {{variables.variableName}} [3]. In YAML flow configurations, this syntax is used within the values section, such as in the promptTemplate field [2]. Always ensure that node identifiers match the defined node in your workflow when using output references [3].
Citations:
- 1: https://lamatic.ai/guides/tutorials/prompt-engineering-with-lamatic
- 2: https://lamatic.ai/docs/flows/flow-config
- 3: https://lamatic.ai/docs/nodes/logic/variable-node
- 4: https://lamatic.ai/guides/tutorials/get-started
Use Lamatic interpolation for the review fields.
[starRating variable]and[reviewText variable]read as literal text here; switch to Lamatic’s{{...}}syntax so the prompt receives the actual rating and review, and add a render test that checks both values appear in the final prompt.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@lamatic/flows/MyFirstFlow.ts` around lines 42 - 52, Update the user prompt content in the prompts configuration to use Lamatic {{...}} interpolation for the starRating and reviewText fields instead of bracketed placeholders, ensuring the rendered prompt contains the actual values. Add a render test covering both interpolated values in the final prompt.
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@kits/google-reviews-ai-manager/.env.example`:
- Line 9: Replace the truthy placeholder value for LAMATIC_API_URL in the
environment example with an empty value, allowing orchestrate.ts to use its
fallback URL; alternatively, document only the actual deployed GraphQL endpoint
rather than a dummy URL.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI (base), Organization UI (inherited)
Review profile: ASSERTIVE
Plan: Pro
Run ID: dbb8bbb1-b69b-44cb-914e-0ad991e0d377
📒 Files selected for processing (1)
kits/google-reviews-ai-manager/.env.example
|
Hi @ToufiqQureshi! 👋 Before this PR can be reviewed by maintainers, please resolve all comments and requested changes from the CodeRabbit automated review. Steps to follow:
This helps keep the review process efficient for everyone. Thank you! 🙏 |
|
@ToufiqQureshi the PR is not up to the mark. Please check contributing.md and the github copilot comments |
|
@coderabbitai review |
✅ Action performedReview finished.
|
|
@coderabbitai review |
✅ Action performedReview finished.
|
|
@coderabbitai review |
✅ Action performedReview finished.
|
|
@coderabbitai review |
✅ Action performedReview finished.
|
|
@coderabbitai review |
✅ Action performedReview finished.
|
|
@coderabbitai review |
|
|
@coderabbitai review |
|
|
@coderabbitai review |
|
|
Note GitHub couldn't provide a complete incremental comparison for this pull request, so CodeRabbit is performing a full review instead. This review may take a little longer. |
There was a problem hiding this comment.
Actionable comments posted: 25
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.github/workflows/lamatic-update.yml:
- Around line 10-24: Update jobs.detect-flow-changes to grant only contents:
read permissions, pin both actions/checkout and Lamatic/sync-flows-to-lamatic to
their full immutable commit SHAs, and set persist-credentials: false on the
Checkout repository step. Do not leave either action referenced by a mutable
tag.
- Around line 3-14: Add workflow-level concurrency configuration before the
detect-flow-changes job, using a branch-scoped group based on the workflow ref
and setting cancel-in-progress to false. Preserve the existing deployment
trigger and job conditions.
In `@kits/google-reviews-ai-manager/apps/app/actions/gmb.ts`:
- Around line 79-93: Add UTF-8 byte-length validation for replyText at the start
of postGMBReply, before getAccessToken or the reply fetch, enforcing the
4096-byte Comment limit. Return the existing validation-error result for
oversized text and preserve the API request for valid replies.
- Around line 34-46: Update getGMBLocations() to iterate over every account,
fetch its locations, and attach that account’s accountName to each returned
location instead of using only accounts[0]. Update the location-selection UI to
pass the selected location’s accountName into getGMBReviews(), and revise the
action contract and downstream review/reply logic to use that account when
selecting reviews or posting replies.
In `@kits/google-reviews-ai-manager/apps/app/actions/orchestrate.ts`:
- Line 4: Add input validation at the start of generateReply before calling
Lamatic: reject empty or oversized reviewText values and reject starRating
values outside the valid Google rating range. Ensure invalid serialized payloads
fail early and no Lamatic request is sent.
- Around line 39-60: Update the orchestration flow around the raw response
logging and error returns to prevent upstream review data, workflow results,
GraphQL messages, and exception details from reaching logs or the browser.
Replace full-body logging with safe status metadata plus a correlation ID, and
return stable generic error messages for all failure paths while preserving
successful response handling.
- Around line 4-12: Add a server-side authentication guard at the start of
generateReply, using getServerSession or the project’s established server
authorization helper, and return the existing unauthorized response shape before
reading configuration or invoking the Lamatic workflow when no valid session
exists.
- Around line 5-12: Remove the hard-coded default from the apiUrl initialization
in the action’s configuration setup, require LAMATIC_API_URL alongside apiKey,
projectId, and flowId in the existing validation, and preserve the
missing-configuration error path so the flow cannot run without an explicit
endpoint.
- Around line 40-51: Update generateReply’s Lamatic fetch request to use an
AbortController with a finite server-side timeout, clearing the timer after
completion. Catch aborts caused by that timeout and return the established
controlled timeout error instead of leaving the review row loading indefinitely;
preserve existing handling for other fetch failures.
- Around line 40-74: The generateReply response-handling flow must validate
response.ok before processing the body and return an error for any non-2xx
Lamatic response, including bodies without GraphQL errors. After extracting the
workflow result, enforce that the reply is a string; return an error instead of
{ reply: ... } when the output is an object or otherwise invalid, while
preserving valid string replies.
In `@kits/google-reviews-ai-manager/apps/app/api/auth/`[...nextauth]/route.ts:
- Around line 20-28: The NextAuth callbacks in route.ts must stop placing Google
bearer credentials in JWT/session data; persist access, refresh, and expiry
metadata in a server-side credential store keyed to the authenticated user,
while keeping the session free of token fields. Update getAccessToken() in
gmb.ts to read that store, refresh expired access tokens using the stored
refresh token before Google Business Profile calls, persist refreshed
credentials, and return the valid server-side access token.
In `@kits/google-reviews-ai-manager/apps/app/components/ReviewList.tsx`:
- Around line 114-142: Wrap the Server Action calls in handleGenerate and
handlePostReply with try/catch/finally so rejected calls are handled without
leaving buttons disabled. In each catch, set an actionable reply/error message
for the affected review, and move the corresponding setLoading or setPosting
reset into finally; preserve the existing success and authorization behavior.
- Around line 6-7: Replace the react-icons imports in ReviewList with equivalent
named icons from lucide-react, updating JSX usage as needed while preserving the
existing icon meanings and behavior. Declare lucide-react in the app package
dependencies, then remove react-icons from both package.json and
package-lock.json.
- Around line 211-254: Update the dashboard controls in ReviewList to be
responsive: replace the fixed four-column metrics grid with responsive grid
variants, make the search area full-width on small screens and constrained on
larger screens, and stack the search field above the filter controls on narrow
screens while preserving the existing horizontal layout on wider screens. Ensure
metric labels and filter buttons remain usable without overflow.
- Around line 92-112: Update selectLocation to track the latest location request
using a ref or cancellation mechanism, and only commit reviews, errorMsg, and
loadingReviews when the response belongs to the current selection. Ensure stale
success, error, and catch paths from earlier locations cannot overwrite the
state for the newest selected location.
- Around line 321-333: Add react-hook-form and a Zod schema to the reply editor
in ReviewList, validating the reply’s UTF-8 byte length with TextEncoder against
the 4,096-byte limit before handlePostReply can call postGMBReply. Bind the
textarea to the form, display the schema validation error beside it, and prevent
publishing while the reply is invalid.
In `@kits/google-reviews-ai-manager/apps/app/globals.css`:
- Around line 22-25: Update the body font-family declaration in the body rule to
use the configured --font-geist-sans variable first, while retaining Arial,
Helvetica, and sans-serif as fallbacks.
In `@kits/google-reviews-ai-manager/apps/app/layout.tsx`:
- Around line 15-18: Update the exported metadata object in layout.tsx to
replace the default “Create Next App” title and generated description with
product-specific title and description identifying Google Reviews AI Manager.
In `@kits/google-reviews-ai-manager/apps/app/page.tsx`:
- Around line 16-20: Replace the direct Tailwind palette utilities in page.tsx
lines 16-20 with the established semantic CSS-variable-backed tokens for page
background, text, and sign-in button styling. Apply the same token set
throughout ReviewList.tsx lines 181-405, covering the dashboard, controls,
cards, and modal states; both sites require direct changes and should preserve
their existing layout and interaction styles.
- Around line 1-5: Update the Home function to use the shared NextAuth
configuration: import authOptions from ../api/auth/[...nextauth]/route and pass
it to getServerSession(authOptions), preserving the existing session handling.
In `@kits/google-reviews-ai-manager/apps/package.json`:
- Around line 11-18: Replace react-icons usage in ReviewList.tsx with equivalent
lucide-react imports, update the package dependency from react-icons to
lucide-react in package.json, and remove all react-icons references while
preserving the existing icon behavior.
In `@kits/google-reviews-ai-manager/apps/README.md`:
- Around line 1-36: Replace the default Next.js README content with an
application-specific setup guide headed “Google Reviews AI Manager.” Document
copying .env.example, configuring Google OAuth credentials and redirect URI,
setting Lamatic credentials and flow identifiers, and starting the app with the
appropriate development command.
In `@kits/google-reviews-ai-manager/flows/my-first-flow.ts`:
- Around line 83-88: Update the prompt referenced by the user-role content in
my-first-flow so the review text and star rating placeholders use Lamatic’s
double-curly interpolation syntax, mapping to the executeWorkflow payload fields
reviewText and starRating via input.reviewText and input.starRating.
In `@kits/google-reviews-ai-manager/prompts/my-first-flow_llm-node_system_0.md`:
- Line 1: Update the system prompt in
kits/google-reviews-ai-manager/prompts/my-first-flow_llm-node_system_0.md:1-1 to
explicitly treat review text as customer content only and ignore any
instructions embedded within it. Update
kits/google-reviews-ai-manager/prompts/my-first-flow_llm-node_user_1.md:1-1 to
wrap the [reviewText variable] in clear data delimiters, with no direct change
required elsewhere.
In `@lamatic/flows/MyFirstFlow.ts`:
- Around line 42-52: Update the user prompt content in the prompts configuration
to replace the bracketed starRating and reviewText placeholders with Lamatic
double-curly trigger variables, using {{llmNode.trigger.starRating}} and
{{llmNode.trigger.reviewText}} or the documented trigger-node input names, so
the LLM receives the actual review data.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI (base), Organization UI (inherited)
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 1bbc7d13-978e-492b-9793-8d01dffe3491
⛔ Files ignored due to path filters (8)
kits/google-reviews-ai-manager/apps/app/favicon.icois excluded by!**/*.icokits/google-reviews-ai-manager/apps/package-lock.jsonis excluded by!**/package-lock.jsonkits/google-reviews-ai-manager/apps/public/file.svgis excluded by!**/*.svgkits/google-reviews-ai-manager/apps/public/globe.svgis excluded by!**/*.svgkits/google-reviews-ai-manager/apps/public/logo.pngis excluded by!**/*.pngkits/google-reviews-ai-manager/apps/public/next.svgis excluded by!**/*.svgkits/google-reviews-ai-manager/apps/public/vercel.svgis excluded by!**/*.svgkits/google-reviews-ai-manager/apps/public/window.svgis excluded by!**/*.svg
📒 Files selected for processing (29)
.github/workflows/lamatic-update.ymlkits/google-reviews-ai-manager/.env.examplekits/google-reviews-ai-manager/README.mdkits/google-reviews-ai-manager/agent.mdkits/google-reviews-ai-manager/apps/.env.examplekits/google-reviews-ai-manager/apps/.gitignorekits/google-reviews-ai-manager/apps/AGENTS.mdkits/google-reviews-ai-manager/apps/CLAUDE.mdkits/google-reviews-ai-manager/apps/README.mdkits/google-reviews-ai-manager/apps/app/actions/gmb.tskits/google-reviews-ai-manager/apps/app/actions/orchestrate.tskits/google-reviews-ai-manager/apps/app/api/auth/[...nextauth]/route.tskits/google-reviews-ai-manager/apps/app/components/ReviewList.tsxkits/google-reviews-ai-manager/apps/app/globals.csskits/google-reviews-ai-manager/apps/app/layout.tsxkits/google-reviews-ai-manager/apps/app/page.tsxkits/google-reviews-ai-manager/apps/eslint.config.mjskits/google-reviews-ai-manager/apps/next.config.tskits/google-reviews-ai-manager/apps/package.jsonkits/google-reviews-ai-manager/apps/postcss.config.mjskits/google-reviews-ai-manager/apps/tsconfig.jsonkits/google-reviews-ai-manager/constitutions/default.mdkits/google-reviews-ai-manager/flows/my-first-flow.tskits/google-reviews-ai-manager/lamatic.config.tskits/google-reviews-ai-manager/model-configs/my-first-flow_llm-node_generative-model-name.tskits/google-reviews-ai-manager/prompts/my-first-flow_llm-node_system_0.mdkits/google-reviews-ai-manager/prompts/my-first-flow_llm-node_user_1.mdlamatic/flows/MyFirstFlow.tslamatic/project.json
| on: | ||
| push: | ||
| branches: | ||
| - main | ||
| paths: | ||
| - '**/lamatic/flows/**' | ||
|
|
||
| jobs: | ||
| detect-flow-changes: | ||
| environment: main | ||
| runs-on: ubuntu-latest | ||
| if: "!contains(github.event.head_commit.message, '[LAMATIC-COMMIT]')" |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== file list =="
git ls-files .github/workflows || true
echo "== target workflow =="
if [ -f .github/workflows/lamatic-update.yml ]; then
cat -n .github/workflows/lamatic-update.yml
else
echo "missing .github/workflows/lamatic-update.yml"
fi
echo "== occurrences of concurrency in workflows =="
rg -n "concurrency:|cancel-in-progress:" .github/workflows || true
echo "== Lamatic update occurrences =="
rg -n "lamatic|LAMATIC|flows" .github/workflows . || trueRepository: Lamatic/AgentKit
Length of output: 50373
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== workflow matches =="
rg -n "^(on:|concurrency:|jobs:|detect-flow-changes:|sync|deploy|lamatic-update)" .github/workflows || true
echo "== target file exact =="
if [ -f .github/workflows/lamatic-update.yml ]; then
sed -n '1,120p' .github/workflows/lamatic-update.yml | cat -n
fi
echo "== all workflow concurrency blocks =="
python3 - <<'PY'
from pathlib import Path
for p in sorted(Path(".github/workflows").glob("*.yml")) + sorted(Path(".github/workflows").glob("*.yaml")):
text = p.read_text()
if "concurrency:" in text:
print(f"{p.parent / p}: found concurrency")
lines = text.splitlines()
for i,l in enumerate(lines,1):
if "concurrency:" in l:
print(f" line {i}: {l}")
for j in range(i, min(i+8, len(lines)+1)):
print(f" line {j}: {lines[j-1]}")
PYRepository: Lamatic/AgentKit
Length of output: 1780
🌐 Web query:
GitHub Actions concurrent workflows same branch last finished order stale artifacts deployment
💡 Result:
To manage concurrent workflows and prevent stale deployments in GitHub Actions, use the concurrency configuration to enforce execution order and cancellation rules [1][2]. Core Strategy The concurrency keyword defines a group name. When a new workflow run starts, GitHub checks if another run in the same group is already active or pending [1][3]. Key Configurations 1. cancel-in-progress: true Use this for non-production environments or stateless workflows (e.g., CI/Test runs) [4][5]. If a new run starts, the previous in-flight run is immediately cancelled, ensuring only the most recent commit is tested [6][7]. 2. cancel-in-progress: false Use this for production deployments [5]. This forces workflows to queue and execute sequentially. It ensures that an in-flight deployment finishes completely before the next one starts, preventing race conditions, migration collisions, and partial updates [4][8]. Defining the Group To ensure concurrency rules apply correctly, the concurrency group string must be specific enough to avoid unintended cancellations across different contexts, but general enough to capture the intended "lane" [4][7]. Recommended naming patterns: - For Branch-Specific workflows: group: ${{ github.workflow }}-${{ github.ref }} [6][7]. - For Deployment environments: group: deploy-${{ github.ref_name }}-production [4][8]. Common Pitfalls - Avoiding Unique Keys: Never include github.sha or github.run_id in the concurrency group string [6][9]. These are unique to every run, which effectively disables concurrency limiting because every run lands in its own unique group [6][7]. - Deadlocks: If a workflow contains jobs that depend on each other (via needs), ensure the concurrency group is applied at the workflow level, not the individual job level, to avoid creating dependencies that cannot be satisfied [8]. - Global Locks: Avoid using a single global concurrency group for your entire repository, as this will serialize all workflows, including unrelated tests and linters, severely slowing down development [4][5]. Always scope locks to specific environments or workflow types [4][7]. For complex requirements where native concurrency is insufficient, such as waiting for multiple disparate workflows to finish before starting a final deployment, you may need third-party actions, although GitHub natively supports standard queuing through the concurrency configuration [10].
Citations:
- 1: https://docs.github.com/en/actions/how-tos/write-workflows/choose-when-workflows-run/control-workflow-concurrency
- 2: https://docs.github.com/actions/writing-workflows/choosing-what-your-workflow-does/control-the-concurrency-of-workflows-and-jobs
- 3: https://docs.github.com/en/actions/concepts/workflows-and-actions/concurrency
- 4: https://how2.sh/posts/use-github-actions-concurrency-prevent-overlapping-deploys/
- 5: https://how2.sh/posts/how-to-prevent-overlapping-deploys-github-actions-concurrency/
- 6: https://gitspider.com/guides/github-actions-concurrency-cancel-in-progress
- 7: https://latchkey.dev/learn/github-actions/gha-concurrency-canceled-in-progress
- 8: https://latchkey.dev/learn/github-actions/github-actions-concurrency-deploy-deadlock
- 9: https://dev.to/ace2932/cancel-duplicate-github-actions-runs-with-one-block-and-the-one-place-you-shouldnt-2m3k
- 10: https://github.com/actions-marketplace-validations/ygqygq2_workflow-wait-action
Mission directive: Serialize Lamatic deployments.
This workflow has no concurrency control, so two pushes to main can run two deployments at once. If the older deployment completes after the newer one, it can write stale flow content back to Lamatic. Add a workflow-level branch-scoped concurrency group before jobs. Keep cancel-in-progress false so the latest commit waits for the active deployment to complete instead of cancelling it.
🧰 Tools
🪛 YAMLlint (1.37.1)
[warning] 3-3: truthy value should be one of [false, true]
(truthy)
🪛 zizmor (1.29.0)
[info] 11-11: workflow or action definition without a name (anonymous-definition): this job
(anonymous-definition)
[warning] 3-8: insufficient job-level concurrency limits (concurrency-limits): workflow is missing concurrency setting
(concurrency-limits)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.github/workflows/lamatic-update.yml around lines 3 - 14, Add workflow-level
concurrency configuration before the detect-flow-changes job, using a
branch-scoped group based on the workflow ref and setting cancel-in-progress to
false. Preserve the existing deployment trigger and job conditions.
Source: Linters/SAST tools
| jobs: | ||
| detect-flow-changes: | ||
| environment: main | ||
| runs-on: ubuntu-latest | ||
| if: "!contains(github.event.head_commit.message, '[LAMATIC-COMMIT]')" | ||
| steps: | ||
| - name: Checkout repository | ||
| uses: actions/checkout@v4 | ||
|
|
||
| - name: Sync Flows to lamatic | ||
| uses: Lamatic/sync-flows-to-lamatic@v1 | ||
| with: | ||
| lamatic-endpoint: ${{ secrets.LAMATIC_PROJECT_ENDPOINT }} | ||
| api-key: ${{ secrets.LAMATIC_PROJECT_API_KEY }} | ||
| project-id: ${{ secrets.LAMATIC_PROJECT_ID }} |
There was a problem hiding this comment.
🔒 Security & Privacy | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/usr/bin/env bash
set -euo pipefail
git ls-remote https://github.com/actions/checkout.git \
'refs/tags/v4' 'refs/tags/v4^{}'
git ls-remote https://github.com/Lamatic/sync-flows-to-lamatic.git \
'refs/tags/v1' 'refs/tags/v1^{}'Repository: Lamatic/AgentKit
Length of output: 262
🏁 Script executed:
#!/usr/bin/env bash
set -euo pipefail
echo "== workflow =="
cat -n .github/workflows/lamatic-update.yml
echo
echo "== github workflow perms in workflows =="
rg -n "permissions:|persist-credentials:|concurrency:" .github/workflows -S || trueRepository: Lamatic/AgentKit
Length of output: 1386
Mission directive: Lock down the workflow action trust boundary.
Pin actions/checkout and Lamatic/sync-flows-to-lamatic to full commit SHAs. In jobs.detect-flow-changes, set permissions: contents: read and add persist-credentials: false to the actions/checkout step. Mutable tags can move action code and scope this job’s credentials to code that does not need repository writes. Do not execute this mission unless the tags are immutable.
🧰 Tools
🪛 zizmor (1.29.0)
[warning] 16-17: credential persistence through GitHub Actions artifacts (artipacked): does not set persist-credentials: false
(artipacked)
[error] 17-17: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)
(unpinned-uses)
[error] 20-20: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)
(unpinned-uses)
[info] 11-11: workflow or action definition without a name (anonymous-definition): this job
(anonymous-definition)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.github/workflows/lamatic-update.yml around lines 10 - 24, Update
jobs.detect-flow-changes to grant only contents: read permissions, pin both
actions/checkout and Lamatic/sync-flows-to-lamatic to their full immutable
commit SHAs, and set persist-credentials: false on the Checkout repository step.
Do not leave either action referenced by a mutable tag.
Source: Linters/SAST tools
| // 2. Fetch Locations for the first account (ideally we should loop all accounts, but this covers most users) | ||
| const accountName = accounts[0].name; | ||
|
|
||
| const locationsRes = await fetch(`https://mybusinessbusinessinformation.googleapis.com/v1/${accountName}/locations?readMask=name,title,storeCode,storefrontAddress`, { | ||
| headers: { Authorization: `Bearer ${token}` } | ||
| }); | ||
|
|
||
| if (!locationsRes.ok) { | ||
| throw new Error(`Failed to fetch locations: ${locationsRes.statusText}`); | ||
| } | ||
|
|
||
| const locationsData = await locationsRes.json(); | ||
| return { locations: locationsData.locations || [], accountName }; |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | 🏗️ Heavy lift
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Trace the location payload and account-name contract through the UI.
ast-grep outline kits/google-reviews-ai-manager/apps/app/components/ReviewList.tsx --items all
rg -n -C4 '\bgetGMBLocations\s*\(|\bgetGMBReviews\s*\(|accountName|locationName' \
kits/google-reviews-ai-manager/apps/appRepository: Lamatic/AgentKit
Length of output: 17965
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Inspect the relevant GMB action interface and the review list UI contract around location selection and listing.
sed -n '1,95p' kits/google-reviews-ai-manager/apps/app/actions/gmb.ts
printf '\n--- ReviewList location state and selection contract ---\n'
sed -n '38,105p' kits/google-reviews-ai-manager/apps/app/components/ReviewList.tsx
printf '\n--- ReviewList location modal and list rendering ---\n'
sed -n '374,402p' kits/google-reviews-ai-manager/apps/app/components/ReviewList.tsxRepository: Lamatic/AgentKit
Length of output: 8290
Mission objective: Return each location with its owning account.
getGMBLocations() always uses accounts[0], so users with locations under another account cannot manage them. Return each location with its accountName, then pass that value from the location selection UI to getGMBReviews() and update the action contract before selecting reviews or posting replies.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@kits/google-reviews-ai-manager/apps/app/actions/gmb.ts` around lines 34 - 46,
Update getGMBLocations() to iterate over every account, fetch its locations, and
attach that account’s accountName to each returned location instead of using
only accounts[0]. Update the location-selection UI to pass the selected
location’s accountName into getGMBReviews(), and revise the action contract and
downstream review/reply logic to use that account when selecting reviews or
posting replies.
| export async function postGMBReply(accountName: string, locationName: string, reviewId: string, replyText: string) { | ||
| try { | ||
| const token = await getAccessToken(); | ||
| const accountId = accountName.split('/')[1]; | ||
| const locationId = locationName.split('/')[1]; | ||
| const rId = reviewId.includes('/') ? reviewId.split('/').pop() : reviewId; | ||
|
|
||
| const replyRes = await fetch(`https://mybusiness.googleapis.com/v4/accounts/${accountId}/locations/${locationId}/reviews/${rId}/reply`, { | ||
| method: 'PUT', | ||
| headers: { | ||
| 'Authorization': `Bearer ${token}`, | ||
| 'Content-Type': 'application/json' | ||
| }, | ||
| body: JSON.stringify({ comment: replyText }) | ||
| }); |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== locate gmb action file =="
fd -a 'gmb\.ts$' . || true
echo "== relevant excerpts =="
file="kits/google-reviews-ai-manager/apps/app/actions/gmb.ts"
if [ -f "$file" ]; then
wc -l "$file"
sed -n '1,140p' "$file" | cat -n
fi
echo "== search reply validation/usages =="
rg -n "postGMBReply|Comment|max-length|byteLength|TextEncoder|4096|replyText" kits/google-reviews-ai-manager/apps/app -S || trueRepository: Lamatic/AgentKit
Length of output: 5458
🌐 Web query:
Google My Business API v4 accounts locations reviews reply comment max length 4096
💡 Result:
In the Google Business Profile API v4, the maximum length for the comment field in a ReviewReply object is 4096 bytes [1][2]. This field, which represents the location owner's or manager's reply to a customer review, must be provided as plain text [1][3]. While the technical limit imposed by the API is 4096 bytes, users should be aware that Google's automated content moderation systems may reject replies based on other criteria, such as the use of boilerplate text, prohibited content, or specific patterns, regardless of whether the reply is within the character limit [4]. Top results: [1][2][4]
Citations:
- 1: https://developers.google.com/my-business/reference/rest/v4/accounts.locations.reviews
- 2: https://developers.google.com/my-business/reference/rpc/google.mybusiness.v4
- 3: https://developers.google.cn/my-business/reference/rest/v4/accounts.locations.reviews
- 4: https://gmbapi.com/news/google-rejected-review-replies-analysis/
Reject over-long reply text before calling the My Business reply API.
Comment supports up to 4096 bytes. Add UTF-8 byte-length validation in postGMBReply before sending { comment: replyText }; return the validation error instead of relying on the API error path.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@kits/google-reviews-ai-manager/apps/app/actions/gmb.ts` around lines 79 - 93,
Add UTF-8 byte-length validation for replyText at the start of postGMBReply,
before getAccessToken or the reply fetch, enforcing the 4096-byte Comment limit.
Return the existing validation-error result for oversized text and preserve the
API request for valid replies.
| "use server"; | ||
| import { Lamatic } from "lamatic"; | ||
|
|
||
| export async function generateReply(reviewText: string, starRating: string) { |
There was a problem hiding this comment.
🔒 Security & Privacy | 🟠 Major | ⚡ Quick win
Validate server-action inputs before calling Lamatic.
TypeScript types do not validate serialized server-action payloads. Reject empty or oversized reviewText values and reject starRating values outside the Google rating range before sending the request. This limits prompt and cost abuse and prevents malformed replies.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@kits/google-reviews-ai-manager/apps/app/actions/orchestrate.ts` at line 4,
Add input validation at the start of generateReply before calling Lamatic:
reject empty or oversized reviewText values and reject starRating values outside
the valid Google rating range. Ensure invalid serialized payloads fail early and
no Lamatic request is sent.
| "dependencies": { | ||
| "lamatic": "^0.3.2", | ||
| "next": "16.2.10", | ||
| "next-auth": "^4.24.14", | ||
| "react": "19.2.4", | ||
| "react-dom": "19.2.4", | ||
| "react-icons": "^5.7.0" | ||
| }, |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Identify every icon import that must migrate before dependency removal.
rg -n -C2 --glob '*.{ts,tsx,js,jsx}' 'react-icons|lucide-react' kits/google-reviews-ai-manager/appsRepository: Lamatic/AgentKit
Length of output: 889
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "Package manager files and app package:"
for f in package.json kits/google-reviews-ai-manager/apps/package.json; do
if [ -f "$f" ]; then
echo "--- $f"
sed -n '1,80p' "$f"
fi
done
echo
echo "App entry points and icons across all tracked files:"
rg -n --glob '*.{ts,tsx,js,jsx,json}' 'icons/|lucide-react|react-icons' packages kits || trueRepository: Lamatic/AgentKit
Length of output: 50372
Mission icon swap: Replace react-icons with lucide-react.
kits/google-reviews-ai-manager/apps/package.json declares react-icons, and ReviewList.tsx imports react-icons/fi and react-icons/bs. Replace both package references and the icon imports; then remove react-icons from dependencies.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@kits/google-reviews-ai-manager/apps/package.json` around lines 11 - 18,
Replace react-icons usage in ReviewList.tsx with equivalent lucide-react
imports, update the package dependency from react-icons to lucide-react in
package.json, and remove all react-icons references while preserving the
existing icon behavior.
Source: Coding guidelines
| This is a [Next.js](https://nextjs.org) project bootstrapped with [`create-next-app`](https://nextjs.org/docs/app/api-reference/cli/create-next-app). | ||
|
|
||
| ## Getting Started | ||
|
|
||
| First, run the development server: | ||
|
|
||
| ```bash | ||
| npm run dev | ||
| # or | ||
| yarn dev | ||
| # or | ||
| pnpm dev | ||
| # or | ||
| bun dev | ||
| ``` | ||
|
|
||
| Open [http://localhost:3000](http://localhost:3000) with your browser to see the result. | ||
|
|
||
| You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file. | ||
|
|
||
| This project uses [`next/font`](https://nextjs.org/docs/app/building-your-application/optimizing/fonts) to automatically optimize and load [Geist](https://vercel.com/font), a new font family for Vercel. | ||
|
|
||
| ## Learn More | ||
|
|
||
| To learn more about Next.js, take a look at the following resources: | ||
|
|
||
| - [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API. | ||
| - [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial. | ||
|
|
||
| You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js) - your feedback and contributions are welcome! | ||
|
|
||
| ## Deploy on Vercel | ||
|
|
||
| The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js. | ||
|
|
||
| Check out our [Next.js deployment documentation](https://nextjs.org/docs/app/building-your-application/deploying) for more details. |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win
Mission requirement: replace the default README with an application setup guide.
Add a top-level Google Reviews AI Manager heading. Document how to copy .env.example, configure Google OAuth, set Lamatic credentials and flow identifiers, configure the redirect URI, and start the app. The current README does not explain how to run the advertised integration.
🧰 Tools
🪛 markdownlint-cli2 (0.23.2)
[warning] 1-1: First line in a file should be a top-level heading
(MD041, first-line-heading, first-line-h1)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@kits/google-reviews-ai-manager/apps/README.md` around lines 1 - 36, Replace
the default Next.js README content with an application-specific setup guide
headed “Google Reviews AI Manager.” Document copying .env.example, configuring
Google OAuth credentials and redirect URI, setting Lamatic credentials and flow
identifiers, and starting the app with the appropriate development command.
Source: Linters/SAST tools
| "content": "@prompts/my-first-flow_llm-node_system_0.md" | ||
| }, | ||
| { | ||
| "id": "83ec945a-2afb-4230-9d75-7967d01058d8", | ||
| "role": "user", | ||
| "content": "@prompts/my-first-flow_llm-node_user_1.md" |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
rg -n -C 3 '\[[A-Za-z_][A-Za-z0-9_]* variable\]|\{\{[^}]+\}\}' \
kits/google-reviews-ai-manager/prompts \
kits/google-reviews-ai-manager/flows
rg -n -C 5 'executeWorkflow|reviewText|starRating' \
kits/google-reviews-ai-manager/apps/app/actions/orchestrate.tsRepository: Lamatic/AgentKit
Length of output: 2504
🌐 Web query:
Lamatic prompt variable interpolation [variable] syntax executeWorkflow
💡 Result:
In Lamatic, variable interpolation is primarily handled using the double curly brace syntax: {{variableName}} [1][2]. Prompt Variable Interpolation To inject dynamic variables into prompts, you use the {{variable}} syntax [1]. In the Lamatic Studio prompt editor, you can type {{ to trigger a variable selection menu [1]. These variables are used to parameterize prompts, such as {{userName}} or {{topic}} [1]. Workflow Variables and Nodes - Variable Node: You can define variables with specific types (e.g., string, number, boolean) and assign them values that are either static or dynamic references to other nodes' outputs [2]. - Dynamic Referencing: When referencing the output of a specific node, use the syntax {{nodeId.output.field}} [2][3]. - Usage: Once mapped in a Variable Node, these variables can be referenced in subsequent nodes using their assigned names (e.g., variables.a) [2][3]. Execution (executeWorkflow) The executeWorkflow operation is typically invoked via GraphQL, where you pass a payload object containing the input variables required by your workflow [4][5]. - GraphQL Syntax: You send a mutation or query (e.g., executeWorkflow) with the workflow ID and a JSON payload [4][5]. - Payload Mapping: The payload object should match the input schema defined in your workflow [4]. For example, if your workflow expects a prompt or input variable, you define it within the payload object in your GraphQL variables [4][5]. - SDK Usage: When using the Lamatic SDK, you pass these parameters as a standard JavaScript object to the executeFlow method, which the SDK then handles for the API request [6].
Citations:
- 1: https://lamatic.ai/guides/tutorials/prompt-engineering-with-lamatic
- 2: https://lamatic.ai/docs/nodes/logic/variable-node
- 3: https://github.com/lamatic/docs/blob/main/pages/docs/nodes/logic/variable-node.mdx
- 4: https://lamatic.ai/docs/api-integration/integration-guide
- 5: https://lamatic.ai/docs/api-overview
- 6: https://lamatic.ai/docs/api-integration/sdk
Mission: Update Lamatic prompt placeholders to {{...}}.
The executeWorkflow payload sends reviewText and starRating, but kits/google-reviews-ai-manager/prompts/my-first-flow_llm-node_user_1.md still uses [reviewText variable] and [starRating variable]. Lamatic prompt interpolation uses double-curlies such as {{input.reviewText}}, so these literals may reach the model.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@kits/google-reviews-ai-manager/flows/my-first-flow.ts` around lines 83 - 88,
Update the prompt referenced by the user-role content in my-first-flow so the
review text and star rating placeholders use Lamatic’s double-curly
interpolation syntax, mapping to the executeWorkflow payload fields reviewText
and starRating via input.reviewText and input.starRating.
| @@ -0,0 +1 @@ | |||
| You are a professional customer support agent for a local business. Draft polite, contextual, and on-brand replies to Google Reviews. Maintain a warm tone for positive reviews. Express understanding and offer resolution steps for negative reviews. No newline at end of file | |||
There was a problem hiding this comment.
🔒 Security & Privacy | 🟠 Major | ⚡ Quick win
Mission: Treat review content as untrusted data.
A reviewer can include adversarial instructions in the review text. The current prompts do not tell the model to ignore instructions embedded in that text.
kits/google-reviews-ai-manager/prompts/my-first-flow_llm-node_system_0.md#L1-L1: instruct the model to treat review text only as customer content and never as instructions.kits/google-reviews-ai-manager/prompts/my-first-flow_llm-node_user_1.md#L1-L1: place[reviewText variable]inside explicit data delimiters.
🧰 Tools
🪛 markdownlint-cli2 (0.23.2)
[warning] 1-1: First line in a file should be a top-level heading
(MD041, first-line-heading, first-line-h1)
[warning] 1-1: Files should end with a single newline character
(MD047, single-trailing-newline)
📍 Affects 2 files
kits/google-reviews-ai-manager/prompts/my-first-flow_llm-node_system_0.md#L1-L1(this comment)kits/google-reviews-ai-manager/prompts/my-first-flow_llm-node_user_1.md#L1-L1
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@kits/google-reviews-ai-manager/prompts/my-first-flow_llm-node_system_0.md` at
line 1, Update the system prompt in
kits/google-reviews-ai-manager/prompts/my-first-flow_llm-node_system_0.md:1-1 to
explicitly treat review text as customer content only and ignore any
instructions embedded within it. Update
kits/google-reviews-ai-manager/prompts/my-first-flow_llm-node_user_1.md:1-1 to
wrap the [reviewText variable] in clear data delimiters, with no direct change
required elsewhere.
| "prompts": [ | ||
| { | ||
| "id": "40452419-1237-4f27-9e33-5f86f0114276", | ||
| "role": "system", | ||
| "content": "You are a professional customer support agent for a local business. Draft polite, contextual, and on-brand replies to Google Reviews. Maintain a warm tone for positive reviews. Express understanding and offer resolution steps for negative reviews." | ||
| }, | ||
| { | ||
| "id": "83ec945a-2afb-4230-9d75-7967d01058d8", | ||
| "role": "user", | ||
| "content": "Please write a short reply to this Google Review. The customer gave a rating of [starRating variable] stars. Their review: '[reviewText variable]'." | ||
| } |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/usr/bin/env bash
set -euo pipefail
ast-grep outline lamatic/flows/MyFirstFlow.ts --items all
rg -n -C 4 --glob '*.ts' \
'reviewText|starRating|generatedResponse|advance_schema|outputMapping' \
lamatic kitsRepository: Lamatic/AgentKit
Length of output: 50373
🏁 Script executed:
#!/usr/bin/env bash
set -euo pipefail
echo "== target flow relevant sections =="
sed -n '1,120p' lamatic/flows/MyFirstFlow.ts
echo
echo "== focused symbol searches =="
rg -n --glob '*.ts' \
'"reviewText"|"starRating"|starRating variable|reviewText variable|LLMNode_.*output.generatedResponse|\\.generatedResponse\\b|render|handlebars|mustache|prompt template' \
lamatic packages apps core sdk 2>/dev/null | head -n 200 || true
echo
echo "== flow file bracket token occurrences =="
rg -n '\[[A-Za-z0-9_ ]+\]' lamatic/flows/MyFirstFlow.ts || true
echo
echo "== broader template interpolation syntax occurrences =="
rg -n --glob '*.ts' --glob '*.json' --glob '*.yaml' --glob '*.yml' \
'\{\{\s*[A-Za-z0-9_.]+\s*\}\}|\{\{\s*[A-Za-z0-9_.]+\.[A-Za-z0-9_.]+\s*\}\}' \
lamatic packages apps core sdk 2>/dev/null | head -n 300 || trueRepository: Lamatic/AgentKit
Length of output: 4156
🌐 Web query:
Lamatic flows LLM prompt variable syntax trigger inputs reviewText starRating
💡 Result:
In Lamatic.ai, dynamic variables are injected into LLM prompts using double curly brace syntax: {{variableName}} [1][2]. To reference outputs from preceding nodes, the standard syntax is {{nodeId.output.fieldName}} [3][4]. For example, if a flow is triggered by an event containing reviewText and starRating, you would reference these in your prompt template as follows: {{triggerNode_1.output.reviewText}} {{triggerNode_1.output.starRating}} Key points for variable usage in Lamatic: 1. Injection Syntax: You can type {{ directly in the prompt editor to open a variable selection menu or use the UI panel to insert them [1]. 2. Referencing Node Outputs: Always use the specific nodeId (e.g., triggerNode_1) followed by.output and the desired field name [4]. 3. Variable Nodes: For internal workflow variables, you can define them in a Variable Node and reference them elsewhere using the syntax {{variables.variableName}} [4]. 4. Validation: Ensure that the field names (such as reviewText) match the schema defined in your flow's trigger or preceding nodes to avoid errors [4]. If you are programmatically triggering a flow via the SDK or API, ensure your payload object includes these fields (e.g., { "reviewText": "Excellent service", "starRating": 5 }) so they are accessible to the trigger node [5][2].
Citations:
- 1: https://lamatic.ai/guides/tutorials/prompt-engineering-with-lamatic
- 2: https://lamatic.ai/guides/tutorials/get-started
- 3: https://lamatic.ai/docs/flows/flow-config
- 4: https://lamatic.ai/docs/nodes/logic/variable-node
- 5: https://lamatic.ai/docs/api-integration/sdk
Mission failed: replace bracket prompt placeholders with double-curlies.
Lines 46 and 51 send [starRating variable] and [reviewText variable] to the LLM because Lamatic prompt variables use {{...}}. Use {{llmNode.trigger.reviewText}} / {{llmNode.trigger.starRating}} or the documented trigger-node input variable names; otherwise the response template receives literal placeholder text instead of review data.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@lamatic/flows/MyFirstFlow.ts` around lines 42 - 52, Update the user prompt
content in the prompts configuration to replace the bracketed starRating and
reviewText placeholders with Lamatic double-curly trigger variables, using
{{llmNode.trigger.starRating}} and {{llmNode.trigger.reviewText}} or the
documented trigger-node input names, so the LLM receives the actual review data.
Description
This PR introduces the Google Reviews AI Manager Kit. It is a complete Next.js application that integrates with the Google My Business API and Lamatic.ai Edge Engine to automatically generate context-aware replies to Google Reviews.
Features:
(Note: All PR Checklist items have been verified and tested locally.)
.github/workflows/lamatic-update.ymlto sync Lamatic flows when**/lamatic/flows/**changes. The workflow skips commits that contain[LAMATIC-COMMIT].kits/google-reviews-ai-manager/README.mdkits/google-reviews-ai-manager/agent.mdkits/google-reviews-ai-manager/constitutions/default.mdkits/google-reviews-ai-manager/lamatic.config.ts.env.examplefileskits/google-reviews-ai-manager/apps/:ReviewList.tsxwith location selection, review retrieval, search and status filters, AI reply generation, reply editing, and reply publishing.generateReply()to call the LamaticexecuteWorkflowGraphQL API.kits/google-reviews-ai-manager/flows/my-first-flow.tslamatic/flows/MyFirstFlow.tslamatic/project.jsonreviewTextandstarRatingthrough a GraphQLtriggerNode.dynamicNodethat uses the configured DeepSeek model and review-response prompts.responseNode.