Skip to content

fix: Add local settings for permissions, breakdown claude.md for#13

Open
CameronCarlin wants to merge 2 commits intomainfrom
condensing
Open

fix: Add local settings for permissions, breakdown claude.md for#13
CameronCarlin wants to merge 2 commits intomainfrom
condensing

Conversation

@CameronCarlin
Copy link
Contributor

@CameronCarlin CameronCarlin commented Feb 12, 2026

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

    • Added skills: falcon-auth-setup.md, falcon-connector-build.md, falcon-connector-testing.md.
    • Trimmed CLAUDE.md and linked to the new skills.
  • Migration

    • If you need local read permissions, create .claude/settings.local.json locally with your workspace path (do not commit).
    • Using Harness: no action needed.

Written for commit 06990ef. Summary will update on new commits.

Copilot AI review requested due to automatic review settings February 12, 2026 17:21
Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

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

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.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

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.

Comment on lines +197 to 213

**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'}}"
```
Copy link

Copilot AI Feb 12, 2026

Choose a reason for hiding this comment

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

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.

Copilot uses AI. Check for mistakes.
Comment on lines +230 to 246
**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
```
Copy link

Copilot AI Feb 12, 2026

Choose a reason for hiding this comment

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

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).

Copilot uses AI. Check for mistakes.
```tsx
stackone validate [pathToYaml] // Single run validation of the file
```
**Testing Formula**: `Success = (operations × auth_types) tests completed at 100%`
Copy link

Copilot AI Feb 12, 2026

Choose a reason for hiding this comment

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

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:

  1. Adding a brief section about fieldConfigs to one of the skill files
  2. Adding a note in CLAUDE.md explaining when/where fieldConfigs documentation can be found
  3. Clarifying if this feature is being deprecated
Suggested change
**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.

Copilot uses AI. Check for mistakes.
Comment on lines +281 to +309
### 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
Copy link

Copilot AI Feb 12, 2026

Choose a reason for hiding this comment

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

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.

Copilot uses AI. Check for mistakes.
- You follow strict workflows to ensure quality, completeness, and security

## Project knowledge
## Project Knowledge
Copy link

Copilot AI Feb 12, 2026

Choose a reason for hiding this comment

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

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.

Copilot uses AI. Check for mistakes.
```tsx
stackone validate [pathToYaml] // Single run validation of the file
```
**Testing Formula**: `Success = (operations × auth_types) tests completed at 100%`
Copy link

Copilot AI Feb 12, 2026

Choose a reason for hiding this comment

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

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.

Copilot uses AI. Check for mistakes.
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