fix: Add local settings for permissions, breakdown claude.md for#13
fix: Add local settings for permissions, breakdown claude.md for#13CameronCarlin wants to merge 2 commits intomainfrom
Conversation
customers not using harness.
There was a problem hiding this comment.
3 issues found across 5 files
Prompt for AI agents (all issues)
Check if these issues are valid — if so, understand the root cause of each and fix them.
<file name=".claude/settings.local.json">
<violation number="1" location=".claude/settings.local.json:4">
P2: Avoid committing a user-specific absolute path in local settings. It makes the permissions config non-portable for other developers and leaks a personal username. Keep this file untracked or use a repository-relative/environment-specific path instead.</violation>
</file>
<file name=".claude/skills/falcon-connector-build.md">
<violation number="1" location=".claude/skills/falcon-connector-build.md:161">
P2: The YAML example under `actions` uses duplicate `$ref` keys, which will overwrite earlier entries. Use a list so all action partials are included.</violation>
</file>
<file name="CLAUDE.md">
<violation number="1" location="CLAUDE.md:128">
P2: The example YAML uses duplicate `$ref` keys under `actions`, which is invalid YAML and would drop earlier refs. Use a list so multiple partials can be referenced correctly.</violation>
</file>
Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.
There was a problem hiding this comment.
Pull request overview
This pull request restructures the CLAUDE.md documentation file by extracting large sections into separate skill files and adds local settings for file system permissions. The main CLAUDE.md file is reduced from ~1990 lines to ~426 lines by creating three new specialized skill files for different aspects of Falcon connector development.
Changes:
- Restructured CLAUDE.md into a high-level overview with references to detailed skill files
- Created three new skill files: falcon-connector-build.md (447 lines), falcon-connector-testing.md (375 lines), and falcon-auth-setup.md (338 lines)
- Added .claude/settings.local.json with file system read permissions for a specific user's Projects directory
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
| CLAUDE.md | Condensed from comprehensive documentation (~1990 lines) to a concise overview and quick reference guide (~426 lines) with pointers to skill files |
| .claude/skills/falcon-connector-build.md | New skill file containing the complete 11-step workflow for building Falcon connectors with research, validation, and testing phases |
| .claude/skills/falcon-connector-testing.md | New skill file documenting comprehensive testing workflow including action tracking, multi-auth testing, and 100% coverage verification |
| .claude/skills/falcon-auth-setup.md | New skill file covering authentication setup patterns for OAuth 2.0, API keys, and client credentials flows |
| .claude/settings.local.json | New local configuration file with file system read permissions for a specific user's directory (should not be committed) |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
|
||
| **Request**: | ||
| ```yaml | ||
| stepFunction: | ||
| functionName: request | ||
| parameters: | ||
| url: '/users' | ||
| url: /users | ||
| method: post | ||
| args: | ||
| - name: accept | ||
| value: application/json | ||
| in: headers | ||
| # Required body parameters (JEXL or JSONPath) | ||
| - name: email | ||
| value: $.inputs.email | ||
| in: body | ||
| - name: name | ||
| value: $.inputs.name | ||
| in: body | ||
| # Optional parameters need condition | ||
| - name: phone | ||
| value: $.inputs.phone | ||
| in: body | ||
| condition: '{{present(inputs.phone)}}' | ||
| response: | ||
| collection: true | ||
| indexField: id | ||
| dataKey: user | ||
| customErrors: # Optional remapping of provider error responses | ||
| - receivedStatus: 404 | ||
| targetStatus: 400 | ||
| message: 'Custom error message' | ||
| condition: "{{headers['connection'] == 'keep-alive'}}" | ||
| ``` |
There was a problem hiding this comment.
Documentation for customErrors in request step functions has been removed. This feature allows remapping of provider error responses (e.g., changing a 404 to a 400 with a custom message), which is a useful capability for improving error handling in connectors. Consider adding at least a brief reference to this feature in the documentation.
| **SOAP Request**: | ||
| ```yaml | ||
| stepFunction: | ||
| functionName: group_data | ||
| parameters: | ||
| stepsDataToGroup: | ||
| - get_all_employees | ||
| - get_more_employees_data | ||
| isSingleRecord: false | ||
| ``` | ||
|
|
||
| ### Map | ||
|
|
||
| Using the `fieldConfigs` , performs a mapping of the `dataSource` | ||
|
|
||
| NOTE: This step is not required when building a non-unified actions | ||
|
|
||
| ```yaml | ||
| - stepId: map_employee_data | ||
| description: Map employee data | ||
| stepFunction: | ||
| functionName: map_fields | ||
| version: "2" | ||
| parameters: | ||
| dataSource: $.steps.group_employee_data.output.data | ||
| ``` | ||
|
|
||
| ### Typecast | ||
|
|
||
| Applies the types as defined in `fieldConfigs` | ||
|
|
||
| NOTE: This step is not required when building a non-unified actions | ||
|
|
||
| ```yaml | ||
| - stepId: typecast_employee_data | ||
| description: Typecast employee data | ||
| stepFunction: | ||
| functionName: typecast | ||
| version: "2" | ||
| parameters: | ||
| dataSource: $.steps.map_employee_data.output.data | ||
| ``` | ||
|
|
||
| ## Custom Step Functions | ||
|
|
||
| _Add guide on creating custom step functions_ | ||
|
|
||
| # Dynamic Values | ||
|
|
||
| Falcon connectors support multiple expression formats for dynamic values. | ||
|
|
||
| **JSONPath is the preferred expression format** and should be used by default unless you are constructing a string or performing conditional logic. | ||
|
|
||
| ## Expression Formats | ||
|
|
||
| ### 1. JSONPath (`$.path.to.field`) - PREFERRED | ||
|
|
||
| **This is the recommended format for most use cases.** JSONPath provides a consistent, powerful way to access data throughout your connector. | ||
|
|
||
| ```yaml | ||
| # Access credentials | ||
| token: $.credentials.apiKey | ||
| username: $.credentials.email | ||
|
|
||
| # Access inputs | ||
| value: $.inputs.userId | ||
|
|
||
| # Access step output | ||
| dataSource: $.steps.fetch_users.output.data | ||
|
|
||
| # Access array elements | ||
| expression: $.users[0].id | ||
| ``` | ||
|
|
||
| **When to use JSONPath:** | ||
|
|
||
| - When the ENTIRE value is a direct reference (no string construction needed) | ||
| - Accessing credentials: `token: $.credentials.apiKey` | ||
| - Accessing inputs: `userId: $.inputs.userId` | ||
| - Accessing step output: `dataSource: $.steps.fetch_users.output.data` | ||
| - Reading response fields: `nextCursor: $.response.pagination.cursor` | ||
|
|
||
| ### 2. String Interpolation (`${...}`) | ||
|
|
||
| Use **whenever you need to embed dynamic values within a string** (i.e., string construction): | ||
|
|
||
| ```yaml | ||
| # Single dynamic value in URL path | ||
| url: /users/${inputs.id} | ||
| url: /calls/${inputs.callId}/transcript | ||
|
|
||
| # Multiple dynamic values in URL | ||
| url: /users/${inputs.id}/posts/${inputs.postId} | ||
|
|
||
| # URLs with dynamic domains | ||
| baseUrl: https://${credentials.domain}.api.com | ||
|
|
||
| # Environment variables | ||
| redirect_uri: ${apiHostUri}/callback | ||
| ``` | ||
|
|
||
| **When to use String Interpolation:** | ||
|
|
||
| - **ANY time you're building a string with embedded dynamic values** | ||
| - URLs with path parameters: `/resource/${inputs.id}` | ||
| - URLs with multiple segments: `/users/${inputs.userId}/posts/${inputs.postId}` | ||
| - Domain or subdomain construction: `https://${credentials.subdomain}.api.com` | ||
| - Any string concatenation scenario | ||
|
|
||
| ### 3. JEXL Expressions (`'{{...}}'`) | ||
|
|
||
| Use only when you need conditional logic, transformations, or complex expressions. Must be wrapped in single quotes: | ||
|
|
||
| ```yaml | ||
| # Conditionals | ||
| condition: '{{present(inputs.includeInactive)}}' | ||
| condition: '{{inputs.includeInactive == true}}' | ||
| matchExpression: '{{$.accountType == "admin"}}' | ||
|
|
||
| # Transformations | ||
| value: '{{inputs.name.toUpperCase()}}' | ||
|
|
||
| # Complex logic | ||
| value: '{{$.status == "active" ? "enabled" : "disabled"}}' | ||
|
|
||
| # Ternary operations | ||
| value: '{{$.count > 0 ? $.count : "none"}}' | ||
| ``` | ||
|
|
||
| **When to use JEXL:** | ||
|
|
||
| - Conditional logic in `condition` fields | ||
| - Enum matching with `matchExpression` | ||
| - String transformations (uppercase, lowercase, etc.) | ||
| - Mathematical operations | ||
| - Ternary operators | ||
|
|
||
| For more details on JEXL expressions, see the [expressions package documentation](https://github.com/StackOneHQ/connect/tree/main/packages/expressions). | ||
|
|
||
| ## Common Use Cases | ||
|
|
||
| **Credential Templating (use JSONPath):** | ||
|
|
||
| ```yaml | ||
| token: $.credentials.apiKey | ||
| username: $.credentials.email | ||
| password: $.credentials.password | ||
| functionName: soap_request | ||
| parameters: | ||
| url: /EmployeeService | ||
| method: post | ||
| soapOperation: GetEmployee | ||
| soapAction: http://example.com/soap/GetEmployee | ||
| namespaces: | ||
| - namespaceIdentifier: emp | ||
| namespace: http://example.com/employees | ||
| args: | ||
| - name: EmployeeId | ||
| value: ${inputs.employee_id} | ||
| in: body | ||
| ``` |
There was a problem hiding this comment.
The SOAP Request example in the Quick Reference section is missing important parameters that were present in the original documentation. The original included critical details such as useSoapContext, detailed documentation about XML attributes (@_xsi:type), credential block handling, and comprehensive input examples. This abbreviated version may not provide enough guidance for developers implementing SOAP-based connectors.
Consider either expanding this section to include the key details or adding a reference to where more comprehensive SOAP documentation can be found (if it exists elsewhere in the skill files).
| ```tsx | ||
| stackone validate [pathToYaml] // Single run validation of the file | ||
| ``` | ||
| **Testing Formula**: `Success = (operations × auth_types) tests completed at 100%` |
There was a problem hiding this comment.
The documentation for fieldConfigs (field configuration mappings) has been completely removed in this restructuring and does not appear in any of the skill files. This is important information about mapping provider response fields to StackOne unified response, including enumMapper patterns and expression usage.
While the PR description suggests this is for "customers not using harness," fieldConfigs appears to be a core concept that should be documented somewhere, even if only briefly or with a note about when it's needed. Consider either:
- Adding a brief section about fieldConfigs to one of the skill files
- Adding a note in CLAUDE.md explaining when/where fieldConfigs documentation can be found
- Clarifying if this feature is being deprecated
| **Testing Formula**: `Success = (operations × auth_types) tests completed at 100%` | |
| **Testing Formula**: `Success = (operations × auth_types) tests completed at 100%` | |
| ## Field configuration mappings (`fieldConfigs`) | |
| - `fieldConfigs` define how provider response fields map into StackOne's unified schema (including enum mapping and expression-based transforms). | |
| - This skill focuses on customers not using harness, so it does not usually generate or overhaul `fieldConfigs` on its own. | |
| - When working in a repository where `fieldConfigs` are present or required, respect existing `fieldConfigs` definitions and follow the established patterns in that connector for enum mapping and expression syntax. | |
| - The `fieldConfigs` feature is not deprecated; detailed patterns and reference documentation live alongside the connector and harness documentation rather than in this CLAUDE skill file. |
| ### GraphQL Best Practices | ||
|
|
||
| **Input Structure** (nested variables object): | ||
| ```yaml | ||
| inputs: | ||
| - name: variables | ||
| description: Variables for the query | ||
| type: object | ||
| in: body | ||
| required: false | ||
| properties: | ||
| - name: first | ||
| description: The number of items to forward paginate | ||
| type: number | ||
| required: false | ||
| - name: filter | ||
| description: Filter object | ||
| type: object | ||
| required: false | ||
| ``` | ||
|
|
||
| **Benefits:** | ||
|
|
||
| - Matches GraphQL variable structure | ||
| - Groups related parameters together | ||
| - Makes optional parameters clear | ||
| - Consistent across all actions | ||
|
|
||
| ## Request Configuration | ||
|
|
||
| ### Standard GraphQL Request Setup | ||
|
|
||
| All GraphQL requests follow this pattern: | ||
|
|
||
| ```yaml | ||
| steps: | ||
| - stepId: fetch_resource | ||
| description: Query resource from GraphQL API | ||
| stepFunction: | ||
| functionName: request | ||
| parameters: | ||
| url: "/graphql" | ||
| method: post | ||
| args: | ||
| - name: Content-Type | ||
| value: application/json | ||
| in: headers | ||
| - name: query | ||
| value: "query($first: Int, $filter: FilterType) { resources(first: $first, filter: $filter) { nodes { id name } } }" | ||
| in: body | ||
| - name: variables | ||
| in: body | ||
| condition: "{{present(inputs.variables)}}" | ||
| value: | ||
| { | ||
| first: $.inputs.variables.first, | ||
| filter: $.inputs.variables.filter, | ||
| } | ||
| ``` | ||
|
|
||
| **Key points:** | ||
|
|
||
| - **Query**: GraphQL query/mutation string in `query` arg | ||
| - **Variables**: GraphQL variables object in `variables` arg | ||
|
|
||
| ## Nested Objects in Queries | ||
|
|
||
| **⚠️ IMPORTANT: When querying nested objects, ONLY return the `id` field if a separate action exists to fetch the full object.** | ||
|
|
||
| This rule applies to both GraphQL and REST APIs: | ||
|
|
||
| **Rationale:** | ||
|
|
||
| - If a separate `get_*` action exists for a nested resource, users can fetch full details when needed | ||
| - Returning only `id` reduces response payload size and improves performance | ||
| - Prevents redundant data fetching when only the relationship is needed | ||
| - Keeps queries focused and maintainable | ||
|
|
||
| **Example - Correct:** | ||
|
|
||
| ```yaml | ||
| # If get_user action exists, only return id in nested user objects | ||
| value: "query($id: String!) { issue(id: $id) { id title assignee { id } creator { id } team { id } } }" | ||
| ``` | ||
|
|
||
| **Example - Incorrect:** | ||
|
|
||
| **Request Configuration**: | ||
| ```yaml | ||
| # Don't return full nested objects if separate actions exist | ||
| value: "query($id: String!) { issue(id: $id) { id title assignee { id name email } creator { id name email } team { id name } } }" | ||
| args: | ||
| - name: query | ||
| value: "query($first: Int) { users(first: $first) { nodes { id name } } }" | ||
| in: body | ||
| - name: variables | ||
| value: { first: $.inputs.variables.first } | ||
| in: body | ||
| ``` | ||
|
|
||
| **Exception:** | ||
| If no separate action exists to fetch the nested resource, you may include additional fields. However, prefer creating a separate action for the resource if it's commonly accessed. | ||
|
|
||
| ## Variables Value Format | ||
|
|
||
| ### Direct JSONPath References (Preferred) | ||
| **Nested Objects**: | ||
| - ⚠️ ONLY return `id` field if separate action exists to fetch full object | ||
| - Reduces payload size and improves performance |
There was a problem hiding this comment.
The GraphQL Best Practices section has been significantly condensed compared to the original documentation. Important information that was removed includes:
- Detailed explanation of variables value format (Direct JSONPath references vs String interpolation)
- Query string format examples for different action types (list/query, get, mutation)
- Important warnings about avoiding JSON.stringify()
- Mutation input object patterns
- Comprehensive examples from the Linear connector
This condensed version may not provide sufficient guidance for developers working with GraphQL-based APIs. Consider either expanding this section or explicitly referencing where the full GraphQL documentation can be found.
| - You follow strict workflows to ensure quality, completeness, and security | ||
|
|
||
| ## Project knowledge | ||
| ## Project Knowledge |
There was a problem hiding this comment.
The PR description mentions "customers not using harness" but there is no mention of Harness in either the original or modified documentation. This suggests a discrepancy between the PR description and the actual changes made. Consider updating the PR description to accurately reflect what changes were made, or if Harness-related changes were intended, they appear to be missing from this PR.
| ```tsx | ||
| stackone validate [pathToYaml] // Single run validation of the file | ||
| ``` | ||
| **Testing Formula**: `Success = (operations × auth_types) tests completed at 100%` |
There was a problem hiding this comment.
Documentation for the group_data step function has been removed and does not appear in any of the skill files. This step function is used to combine data from multiple steps, which is a useful operation in connector configurations. Consider adding this back either as a reference in CLAUDE.md or in one of the skill files, or clarifying if this feature is being deprecated.
customers not using harness.
Summary by cubic
Breaks CLAUDE.md into focused skills for auth, build, and testing. Removes the local permissions settings file to avoid committing machine-specific paths.
New Features
Migration
Written for commit 06990ef. Summary will update on new commits.