Skip to content

Conversation

@dannyroosevelt
Copy link
Collaborator

@dannyroosevelt dannyroosevelt commented Sep 29, 2025

WHY

Summary by CodeRabbit

  • New Features
    • Added safety/permission hints (destructive, read-only, open-world) to many Slack actions to improve UI clarity and guardrails; action versions incremented to reflect metadata updates.
  • Documentation
    • Added README describing the annotation tool and usage patterns.
  • Chores
    • Added a utility to batch-apply annotations and bump patch versions, with validation, progress reporting, and CLI options.

@vercel
Copy link

vercel bot commented Sep 29, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

2 Skipped Deployments
Project Deployment Preview Comments Updated (UTC)
pipedream-docs Ignored Ignored Sep 29, 2025 10:59pm
pipedream-docs-redirect-do-not-edit Ignored Ignored Sep 29, 2025 10:59pm

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Sep 29, 2025

Caution

Review failed

The pull request is closed.

Walkthrough

Adds an annotations metadata field and bumps patch versions across many Slack action modules. Introduces a new CLI utility and README to apply annotations from a CSV to action files. No runtime logic changes in actions; the script handles CSV parsing, file updates, version increments, and reporting.

Changes

Cohort / File(s) Summary
Slack actions — Read-only or listing actions
components/slack/actions/find-message/...mjs, components/slack/actions/find-user-by-email/...mjs, components/slack/actions/get-file/...mjs, components/slack/actions/list-channels/...mjs, components/slack/actions/list-files/...mjs, components/slack/actions/list-group-members/...mjs, components/slack/actions/list-members-in-channel/...mjs, components/slack/actions/list-replies/...mjs, components/slack/actions/list-users/...mjs, components/slack/actions/verify-slack-signature/...mjs
Added annotations object (destructiveHint/openWorldHint/readOnlyHint as documented) and bumped patch version. No runtime or control-flow changes.
Slack actions — Non-destructive write/send operations
components/slack/actions/add-emoji-reaction/...mjs, components/slack/actions/approve-workflow/...mjs, components/slack/actions/create-channel/...mjs, components/slack/actions/create-reminder/...mjs, components/slack/actions/invite-user-to-channel/...mjs, components/slack/actions/reply-to-a-message/...mjs, components/slack/actions/send-block-kit-message/...mjs, components/slack/actions/send-large-message/...mjs, components/slack/actions/send-message-advanced/...mjs, components/slack/actions/send-message-to-channel/...mjs, components/slack/actions/send-message-to-user-or-group/...mjs, components/slack/actions/send-message/...mjs, components/slack/actions/set-channel-description/...mjs, components/slack/actions/upload-file/...mjs
Added annotations object and bumped patch version. No changes to runtime logic.
Slack actions — Potentially destructive or mutating actions
components/slack/actions/archive-channel/...mjs, components/slack/actions/delete-file/...mjs, components/slack/actions/delete-message/...mjs, components/slack/actions/kick-user/...mjs, components/slack/actions/set-channel-topic/...mjs, components/slack/actions/set-status/...mjs, components/slack/actions/update-group-members/...mjs, components/slack/actions/update-message/...mjs, components/slack/actions/update-profile/...mjs
Added annotations object (many set destructiveHint: true) and bumped patch version. No runtime or control-flow changes.
Tooling — Annotation application utility
scripts/tool-annotations/apply-annotations.js, scripts/tool-annotations/README.md
New AnnotationApplier CLI script (CSV-driven) that locates action files, injects indentation-aware annotations blocks after version, increments patch versions, supports batching/limit/offset/verbose, reports results; plus README documenting usage and CSV format.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor U as User
  participant CLI as apply-annotations.js
  participant G as Git
  participant CSV as CSV Loader
  participant FS as File System
  participant AP as AnnotationApplier

  U->>CLI: Run with --csv, --limit/--offset, --verbose
  CLI->>G: Check working tree status
  G-->>CLI: Status result
  CLI->>AP: Instantiate with options
  AP->>CSV: Load & parse CSV -> map(actionKey -> hints)
  AP->>FS: Discover action files under components/*/actions/
  loop Batch processing
    AP->>FS: Read next file
    AP->>AP: Extract actionKey, detect existing annotations
    alt Needs update
      AP->>AP: Increment patch version
      AP->>AP: Build indent-aware annotations block
      AP->>FS: Write updated file
    else Skip
      AP-->>AP: Record skip reason
    end
  end
  AP-->>CLI: Summary (modified/processed/skipped/errors)
  CLI-->>U: Print report
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Poem

I twitch my whiskers, patch by patch,
Little hints now neatly match.
CSV crumbs lead me to the file,
I nibble versions, leave a smile.
Annotated rows, a tidy batch—
Hop! The repo gets a gentle patch. 🐰✨

Pre-merge checks and finishing touches

❌ Failed checks (1 warning, 1 inconclusive)
Check name Status Explanation Resolution
Description Check ⚠️ Warning The pull request description only contains the placeholder for the WHY section and no substantive explanation of the motivation, scope, or impact of the changes, making it impossible to understand the purpose of the updates. Please complete the WHY section by detailing the rationale behind applying annotations, how the new script operates, and the expected effects on the Slack actions to give reviewers clear context and justification for merging.
Title Check ❓ Inconclusive The title “updated tool annotations output” is too vague to convey the primary purpose of the pull request, which includes both adding annotations and bumping versions across many Slack action files as well as introducing a new annotation application script; it does not clearly summarize the main changes or intent. Please revise the title to succinctly capture the core update, for example by mentioning the addition of annotations to Slack actions and the new tool for applying them, so that reviewers immediately understand the PR’s scope.
✅ Passed checks (1 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c85d9c2 and b1157fc.

📒 Files selected for processing (1)
  • scripts/tool-annotations/apply-annotations.js (1 hunks)

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.

❤️ Share
🧪 Early access (Sonnet 4.5): enabled

We are currently testing the Sonnet 4.5 model, which is expected to improve code review quality. However, this model may lead to increased noise levels in the review comments. Please disable the early access features if the noise level causes any inconvenience.

Note:

  • Public repositories are always opted into early access features.
  • You can enable or disable early access features from the CodeRabbit UI or by updating the CodeRabbit configuration file.

Comment @coderabbitai help to get the list of available commands and usage tips.

@dannyroosevelt dannyroosevelt marked this pull request as ready for review September 29, 2025 22:49
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (2)
scripts/tool-annotations/apply-annotations.js (2)

247-279: Consider validating modified files.

The script writes modified content without verifying the result is syntactically valid JavaScript. A malformed regex match or indentation issue could produce broken files.

Add basic syntax validation after modification:

 // Apply changes
 const modifiedContent = this.applyAnnotations(fileContent, annotations);
+
+// Basic syntax check - verify the file is still valid
+try {
+  // Quick syntax validation without executing
+  new Function(modifiedContent);
+} catch (syntaxError) {
+  throw new Error(`Modified file has syntax error: ${syntaxError.message}`);
+}
+
 fs.writeFileSync(filePath, modifiedContent, 'utf8');

202-210: Semver assumption holds for current files but lacks strict validation.

All version fields in components/slack/actions follow a simple X.Y.Z pattern, so incrementVersion works today—but it still doesn’t enforce that each segment is numeric or handle prerelease/build metadata. Recommend either adding explicit numeric checks or switching to a dedicated semver library to future-proof version increments.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between eb96c25 and c85d9c2.

⛔ Files ignored due to path filters (2)
  • scripts/tool-annotations/registry-action-chatgpt-2025-09-25.csv is excluded by !**/*.csv
  • scripts/tool-annotations/registry-actions-claude-2025-09-29.csv is excluded by !**/*.csv
📒 Files selected for processing (35)
  • components/slack/actions/add-emoji-reaction/add-emoji-reaction.mjs (1 hunks)
  • components/slack/actions/approve-workflow/approve-workflow.mjs (1 hunks)
  • components/slack/actions/archive-channel/archive-channel.mjs (1 hunks)
  • components/slack/actions/create-channel/create-channel.mjs (1 hunks)
  • components/slack/actions/create-reminder/create-reminder.mjs (1 hunks)
  • components/slack/actions/delete-file/delete-file.mjs (1 hunks)
  • components/slack/actions/delete-message/delete-message.mjs (1 hunks)
  • components/slack/actions/find-message/find-message.mjs (1 hunks)
  • components/slack/actions/find-user-by-email/find-user-by-email.mjs (1 hunks)
  • components/slack/actions/get-file/get-file.mjs (1 hunks)
  • components/slack/actions/invite-user-to-channel/invite-user-to-channel.mjs (1 hunks)
  • components/slack/actions/kick-user/kick-user.mjs (1 hunks)
  • components/slack/actions/list-channels/list-channels.mjs (1 hunks)
  • components/slack/actions/list-files/list-files.mjs (1 hunks)
  • components/slack/actions/list-group-members/list-group-members.mjs (1 hunks)
  • components/slack/actions/list-members-in-channel/list-members-in-channel.mjs (1 hunks)
  • components/slack/actions/list-replies/list-replies.mjs (1 hunks)
  • components/slack/actions/list-users/list-users.mjs (1 hunks)
  • components/slack/actions/reply-to-a-message/reply-to-a-message.mjs (1 hunks)
  • components/slack/actions/send-block-kit-message/send-block-kit-message.mjs (1 hunks)
  • components/slack/actions/send-large-message/send-large-message.mjs (1 hunks)
  • components/slack/actions/send-message-advanced/send-message-advanced.mjs (1 hunks)
  • components/slack/actions/send-message-to-channel/send-message-to-channel.mjs (1 hunks)
  • components/slack/actions/send-message-to-user-or-group/send-message-to-user-or-group.mjs (1 hunks)
  • components/slack/actions/send-message/send-message.mjs (1 hunks)
  • components/slack/actions/set-channel-description/set-channel-description.mjs (1 hunks)
  • components/slack/actions/set-channel-topic/set-channel-topic.mjs (1 hunks)
  • components/slack/actions/set-status/set-status.mjs (1 hunks)
  • components/slack/actions/update-group-members/update-group-members.mjs (1 hunks)
  • components/slack/actions/update-message/update-message.mjs (1 hunks)
  • components/slack/actions/update-profile/update-profile.mjs (1 hunks)
  • components/slack/actions/upload-file/upload-file.mjs (1 hunks)
  • components/slack/actions/verify-slack-signature/verify-slack-signature.mjs (1 hunks)
  • scripts/tool-annotations/README.md (1 hunks)
  • scripts/tool-annotations/apply-annotations.js (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
scripts/tool-annotations/apply-annotations.js (1)
scripts/generate-package-report.js (1)
  • componentsDir (62-62)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: Lint Code Base
  • GitHub Check: pnpm publish
  • GitHub Check: Publish TypeScript components
  • GitHub Check: Verify TypeScript components
🔇 Additional comments (53)
components/slack/actions/create-reminder/create-reminder.mjs (2)

7-7: LGTM!

The patch version bump is appropriate for adding metadata without changing runtime behavior.


8-12: LGTM!

The annotations metadata accurately reflects the action's behavior:

  • destructiveHint: false – correct, creating a reminder doesn't delete or permanently alter existing data
  • openWorldHint: true – correct, the action calls the external Slack API
  • readOnlyHint: false – correct, creating a reminder is a write operation
components/slack/actions/list-replies/list-replies.mjs (2)

7-7: LGTM!

Appropriate patch version bump for adding metadata without changing runtime behavior.


8-12: LGTM! Annotations accurately reflect the action's behavior.

The annotations are correct:

  • destructiveHint: false - The action only retrieves conversation replies without modifying data
  • openWorldHint: true - Makes external API calls to Slack
  • readOnlyHint: true - Performs read-only operations
components/slack/actions/list-group-members/list-group-members.mjs (2)

7-7: LGTM!

Patch version bump is appropriate for adding metadata annotations without changing runtime behavior.


8-12: Approve: annotations match other Slack list- actions.*

  • destructiveHint: false
  • readOnlyHint: true
  • openWorldHint: true

Please ensure a centralized annotation schema/validator exists and is applied across all actions.

components/slack/actions/find-user-by-email/find-user-by-email.mjs (1)

7-7: LGTM! Appropriate version bump.

The patch version increment is appropriate for adding metadata without changing runtime behavior.

components/slack/actions/archive-channel/archive-channel.mjs (2)

8-8: LGTM!

Patch version bump is appropriate for a metadata-only change.


9-13: Annotations: tooling present — confirm destructiveHint semantics

  • Verified: scripts/tool-annotations/apply-annotations.js (and README) applies destructiveHint/openWorldHint/readOnlyHint from CSV and inserts the annotations; the CSV includes slack-archive-channel with destructiveHint=true, openWorldHint=true, readOnlyHint=false.
  • No formal schema or runtime semantics found; validation is limited to CSV header presence and boolean parsing in apply-annotations.js.
  • Action: confirm whether destructiveHint is intended to mean "irreversible" or simply "state-changing" (Slack channel archive is reversible; keep true if you mean "modifies state").
components/slack/actions/kick-user/kick-user.mjs (2)

8-8: LGTM! Version bump is appropriate.

The patch version bump correctly reflects the metadata addition without runtime changes.


9-13: Annotations are semantically correct for this action.

The annotation values appropriately reflect the action's behavior:

  • destructiveHint: true correctly indicates that kicking a user is a destructive operation
  • openWorldHint: true correctly indicates interaction with the Slack API
  • readOnlyHint: false correctly indicates state modification
components/slack/actions/verify-slack-signature/verify-slack-signature.mjs (2)

8-8: LGTM! Version bump is appropriate.


9-13: Verify openWorldHint: true is appropriate for local signature verification.

The annotations are mostly correct, but openWorldHint: true may need clarification:

  • destructiveHint: false and readOnlyHint: true are correct (pure verification with no mutations)
  • openWorldHint: true - This action performs local cryptographic verification without making external API calls. If openWorldHint is intended to indicate external API interaction, this should be false. However, if it indicates the action is part of a workflow involving external systems (verifying requests FROM Slack), then true may be appropriate.

Please clarify the semantics of openWorldHint to ensure consistency across all actions. If it means "makes external API calls," this should likely be false.

components/slack/actions/list-files/list-files.mjs (2)

7-7: LGTM! Version bump is appropriate.


8-12: Annotations are semantically correct.

All annotation values appropriately reflect this read-only list operation:

  • destructiveHint: false (no destructive operations)
  • openWorldHint: true (interacts with Slack API)
  • readOnlyHint: true (no state modifications)
components/slack/actions/send-message/send-message.mjs (2)

9-9: LGTM! Version bump is appropriate.


10-14: Annotations are semantically correct.

All annotation values appropriately reflect this message-sending operation:

  • destructiveHint: false (creates content, not destructive)
  • openWorldHint: true (interacts with Slack API)
  • readOnlyHint: false (modifies state by creating messages)
components/slack/actions/update-group-members/update-group-members.mjs (2)

7-7: LGTM! Version bump is appropriate.


8-12: Annotations are semantically correct.

All annotation values appropriately reflect this group membership modification operation:

  • destructiveHint: true (removing users from groups is a destructive operation)
  • openWorldHint: true (interacts with Slack API)
  • readOnlyHint: false (modifies state by changing group membership)
components/slack/actions/list-channels/list-channels.mjs (1)

7-12: LGTM! Annotations accurately reflect the action's behavior.

The annotations correctly classify this action as read-only (listing channels), non-destructive, and requiring external API access to Slack.

components/slack/actions/send-large-message/send-large-message.mjs (1)

8-13: LGTM! Annotations correctly identify this as a write operation.

The annotations appropriately classify this action as a non-destructive write operation (posting messages) that requires external API access.

components/slack/actions/reply-to-a-message/reply-to-a-message.mjs (1)

9-14: LGTM! Annotations match the action's write behavior.

The annotations correctly classify this as a non-destructive write operation that creates threaded replies.

components/slack/actions/send-message-to-channel/send-message-to-channel.mjs (1)

9-14: LGTM! Annotations appropriately reflect message-sending behavior.

The annotations correctly identify this as a non-destructive write operation for posting messages to channels.

components/slack/actions/find-message/find-message.mjs (1)

7-12: LGTM! Annotations correctly classify this as a read-only search operation.

The annotations appropriately identify this action as non-destructive, read-only, and requiring external API access for message search.

components/slack/actions/set-channel-description/set-channel-description.mjs (1)

7-12: LGTM! Metadata annotations are semantically correct.

The version bump and annotations addition are appropriate. The annotation values correctly reflect that this action modifies channel state (readOnly=false), interacts with external Slack API (openWorld=true), and is non-destructive (destructive=false).

components/slack/actions/list-users/list-users.mjs (1)

7-12: LGTM! Read-only annotations are correct.

The annotations accurately reflect the read-only nature of this action (readOnly=true), with appropriate flags for non-destructive (destructive=false) external API interaction (openWorld=true).

components/slack/actions/get-file/get-file.mjs (1)

7-12: LGTM! Annotations correctly reflect read-only operation.

The annotations are appropriate for a file retrieval action with readOnly=true, destructive=false, and openWorld=true for external API interaction.

components/slack/actions/delete-message/delete-message.mjs (1)

7-12: LGTM! Destructive operation correctly annotated.

The annotations are semantically correct for a delete operation with destructive=true, readOnly=false, and openWorld=true for external Slack API interaction.

components/slack/actions/set-channel-topic/set-channel-topic.mjs (1)

8-12: Confirm intention behind destructiveHint for channel-topic action

In components/slack/actions/set-channel-topic/set-channel-topic.mjs, destructiveHint is set to true, whereas in set-channel-description it’s false. Both actions overwrite channel metadata; please verify whether topic changes should indeed be considered destructive, or adjust to align the flags consistently.

components/slack/actions/send-block-kit-message/send-block-kit-message.mjs (1)

10-15: LGTM! Annotations are appropriate for a message-sending action.

The annotations correctly classify this action as non-destructive (doesn't delete/modify existing data), external (interacts with Slack API), and non-read-only (creates new messages). Version bump follows semantic versioning.

components/slack/actions/create-channel/create-channel.mjs (1)

7-12: LGTM! Annotations correctly classify channel creation.

The annotations appropriately mark this as a non-destructive, external, non-read-only action. Channel creation adds new resources without modifying or deleting existing ones.

components/slack/actions/send-message-advanced/send-message-advanced.mjs (1)

10-15: LGTM! Annotations consistent with other message-sending actions.

The annotations are appropriate and consistent with the send-block-kit-message action, correctly classifying this as a non-destructive message-sending operation.

components/slack/actions/update-profile/update-profile.mjs (1)

8-13: LGTM! Correctly marked as destructive.

The annotations appropriately classify this action as destructive since it modifies existing user profile data. This is a key distinction from message-sending actions (which create new data rather than modifying existing data) and demonstrates proper understanding of the destructiveHint classification.

components/slack/actions/set-status/set-status.mjs (1)

7-12: LGTM! Annotations consistent with profile-modifying actions.

The annotations correctly mark this as destructive since it modifies existing user status. This is consistent with update-profile.mjs, as both actions modify existing user state rather than creating new resources.

components/slack/actions/invite-user-to-channel/invite-user-to-channel.mjs (1)

7-12: Annotations look appropriate for this action's behavior.

The annotations correctly classify this action as non-destructive (doesn't delete data), state-modifying (adds a user to a channel), and interacting with external systems (Slack API).

components/slack/actions/update-message/update-message.mjs (1)

7-12: Annotations correctly reflect the destructive nature of message updates.

The destructiveHint: true appropriately flags that updating a message overwrites existing content, which is a destructive operation.

components/slack/actions/send-message-to-user-or-group/send-message-to-user-or-group.mjs (1)

10-15: Annotations appropriately classify this message-sending action.

The annotations correctly indicate this is a non-destructive (creates new content), state-modifying operation that interacts with external systems.

components/slack/actions/list-members-in-channel/list-members-in-channel.mjs (1)

7-12: Correct read-only classification for this list operation.

The readOnlyHint: true correctly identifies this action as performing only data retrieval without modification, distinguishing it from the other actions under review.

components/slack/actions/delete-file/delete-file.mjs (1)

7-12: Annotations appropriately flag this as a destructive operation.

The destructiveHint: true correctly identifies file deletion as a destructive action that permanently removes data.

scripts/tool-annotations/apply-annotations.js (10)

82-107: LGTM! Flexible header validation.

The header validation correctly supports multiple aliases and provides clear error messages when required columns are missing.


109-117: LGTM! Batch slicing logic is correct.

The offset/limit logic correctly handles CSV slicing and preserves the header row. The 1-based logging aligns with user expectations.


119-160: LGTM! Robust CSV loading.

The CSV loading logic properly validates the file, handles per-row errors gracefully, and provides useful warnings for invalid entries.


193-200: LGTM! Regex extraction is adequate for action files.

The key extraction and annotation detection use simple regex patterns suitable for the expected action file structure.


302-311: LGTM! Advisory git status check.

The git status check appropriately warns without blocking execution, allowing users to make informed decisions.


313-328: LGTM! Clear progress reporting.

Batch processing with progress updates provides good user feedback during long-running operations.


363-431: LGTM! Comprehensive CLI interface.

The argument parsing is thorough with validation, helpful error messages, and detailed usage documentation.


434-450: LGTM! Proper module structure.

The script correctly handles both CLI execution and module export scenarios with appropriate error handling and exit codes.


187-191: Path filter is correct—no unintended matches found. Verified only .mjs files under /actions/ (excluding /common/) are matched; no false positives.


222-245: Version field formatting assumptions hold

All version entries in components/slack/actions use the version: "x.y.z",\n pattern and there are no CRLF line endings, so the existing regex and annotation insertion logic require no changes.

scripts/tool-annotations/README.md (1)

1-31: LGTM! Clear documentation.

The README accurately documents the script's functionality with helpful examples and options. The batch processing workflow is well illustrated.

components/slack/actions/add-emoji-reaction/add-emoji-reaction.mjs (1)

7-12: LGTM! Annotations are semantically correct.

The annotation values appropriately reflect the action's behavior:

  • Not destructive (adds data, doesn't remove)
  • Requires open-world context (Slack channels, messages)
  • Not read-only (modifies message state)
components/slack/actions/upload-file/upload-file.mjs (1)

11-16: LGTM! Annotations are semantically correct.

The annotation values appropriately reflect the upload action's behavior:

  • Not destructive (creates new files)
  • Requires open-world context (Slack channels)
  • Not read-only (uploads new files)
components/slack/actions/approve-workflow/approve-workflow.mjs (1)

8-13: LGTM! Annotations are semantically correct.

The annotation values appropriately reflect the workflow approval action's behavior:

  • Not destructive (sends approval message)
  • Requires open-world context (Slack channels)
  • Not read-only (posts new messages)

Comment on lines +8 to +12
annotations: {
destructiveHint: false,
openWorldHint: true,
readOnlyHint: true,
},
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion | 🟠 Major

🧩 Analysis chain

Annotations are semantically correct for this read-only action.

The annotation values accurately reflect the behavior of this action:

  • readOnlyHint: true is correct since the action only calls lookupUserByEmail
  • destructiveHint: false is appropriate as no data is modified or deleted
  • openWorldHint: true accurately indicates the external Slack API call

Please verify that type definitions or schema validation exist for the annotations field to ensure consistency across all actions where these annotations are being added.


🏁 Script executed:

#!/bin/bash
# Description: Search for type definitions or schemas for the annotations field

# Search for TypeScript definitions or JSDoc comments defining annotations structure
rg -n -C3 'annotations.*\{' --type=ts --type=js

# Search for schema validation or documentation of annotation fields
rg -n -C3 '(destructiveHint|openWorldHint|readOnlyHint)' --type=ts --type=js --type=md

# Look for the tool-annotations script mentioned in the AI summary
fd -t f 'AnnotationApplier|tool-annotations' --exec cat {}

Length of output: 6972


Define and enforce a schema for the annotations field
No type definitions or runtime validations exist for annotations (destructiveHint, openWorldHint, readOnlyHint). Add a shared interface or JSDoc typedef and integrate build-time or runtime validation to guarantee consistency across all actions.

🤖 Prompt for AI Agents
In components/slack/actions/find-user-by-email/find-user-by-email.mjs around
lines 8 to 12, the annotations object lacks type and runtime validation; add a
shared JSDoc typedef or TypeScript interface (e.g., ActionAnnotations with
destructiveHint/openWorldHint/readOnlyHint as booleans) in a common module and
update this file to import/use that type (or add matching JSDoc @typedef) and
enforce it at runtime by validating the annotations object (e.g., a small
validator that checks required keys and boolean values or use a shared
validation utility) and throw or log a clear error when validation fails so all
actions follow the same schema.

Comment on lines +55 to +73
parseCSVLine(line) {
const values = [];
let current = '';
let inQuotes = false;

for (const char of line) {
if (char === '"') {
inQuotes = !inQuotes;
} else if (char === ',' && !inQuotes) {
values.push(current.trim());
current = '';
} else {
current += char;
}
}

values.push(current.trim());
return values;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

CSV parser doesn't handle escaped quotes.

The parseCSVLine method toggles quote state but doesn't handle escaped quotes within quoted values (e.g., "value with ""quotes""). If the CSV contains such values, parsing will fail.

Consider using a battle-tested CSV library like csv-parse for production reliability:

+const { parse } = require('csv-parse/sync');
+
 parseCSVLine(line) {
-  const values = [];
-  let current = '';
-  let inQuotes = false;
-
-  for (const char of line) {
-    if (char === '"') {
-      inQuotes = !inQuotes;
-    } else if (char === ',' && !inQuotes) {
-      values.push(current.trim());
-      current = '';
-    } else {
-      current += char;
-    }
-  }
-
-  values.push(current.trim());
-  return values;
+  const records = parse(line, { 
+    trim: true,
+    skip_empty_lines: false
+  });
+  return records[0];
 }
📝 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.

Suggested change
parseCSVLine(line) {
const values = [];
let current = '';
let inQuotes = false;
for (const char of line) {
if (char === '"') {
inQuotes = !inQuotes;
} else if (char === ',' && !inQuotes) {
values.push(current.trim());
current = '';
} else {
current += char;
}
}
values.push(current.trim());
return values;
}
const { parse } = require('csv-parse/sync');
parseCSVLine(line) {
const records = parse(line, {
trim: true,
skip_empty_lines: false
});
return records[0];
}
🤖 Prompt for AI Agents
In scripts/tool-annotations/apply-annotations.js around lines 55 to 73, the
parseCSVLine implementation toggles quote state but doesn't handle escaped
quotes ("" inside a quoted field), causing incorrect parsing for values like
"value with ""quotes"". Update the parser to detect when a quote char appears
while inQuotes and the next char is also a quote, treat that pair as an escaped
quote by appending a single quote character to the current field and advancing
the cursor past the second quote instead of toggling the inQuotes flag;
otherwise keep the existing toggling and comma-splitting logic. Alternatively,
replace this custom logic by using a robust CSV parsing library (e.g.,
csv-parse) and adjust callers accordingly; add unit tests covering quoted fields
with escaped quotes, unquoted fields, and mixed cases.

@dannyroosevelt dannyroosevelt merged commit aa16301 into master Sep 29, 2025
8 of 10 checks passed
@dannyroosevelt dannyroosevelt deleted the danny/prototyping-action-classifications branch September 29, 2025 23:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant