@bffless/claude-skills 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,22 @@
1
+ {
2
+ "name": "bffless",
3
+ "owner": {
4
+ "name": "BFFless"
5
+ },
6
+ "metadata": {
7
+ "description": "BFFless platform skills for Claude Code",
8
+ "version": "1.0.0"
9
+ },
10
+ "plugins": [
11
+ {
12
+ "name": "bffless",
13
+ "source": {
14
+ "source": "npm",
15
+ "package": "@bffless/claude-skills",
16
+ "version": "^1.0.0"
17
+ },
18
+ "description": "BFFless platform skills — deployments, pipelines, proxy rules, chat, traffic splitting, and more",
19
+ "category": "platform"
20
+ }
21
+ ]
22
+ }
@@ -0,0 +1,13 @@
1
+ {
2
+ "name": "bffless",
3
+ "version": "1.0.0",
4
+ "description": "BFFless platform skills for Claude Code — deployments, pipelines, proxy rules, chat, traffic splitting, and more",
5
+ "author": {
6
+ "name": "BFFless"
7
+ },
8
+ "homepage": "https://docs.bffless.app",
9
+ "repository": "https://github.com/bffless/claude-skills",
10
+ "license": "MIT",
11
+ "keywords": ["bffless", "static-hosting", "deployments", "pipelines", "chat"],
12
+ "skills": ["./skills/"]
13
+ }
package/README.md ADDED
@@ -0,0 +1,94 @@
1
+ # @bffless/claude-skills
2
+
3
+ Claude Code plugin with platform skills for [BFFless](https://bffless.app) — a self-hosted static asset hosting platform with AI-powered pipelines.
4
+
5
+ These skills give Claude Code domain knowledge about BFFless features so it can help you build, deploy, and configure your projects.
6
+
7
+ ## Skills Included
8
+
9
+ | Skill | Description |
10
+ | --------------------- | -------------------------------------------------------- |
11
+ | **authorization** | Global and project roles, API keys, permission model |
12
+ | **bffless** | Platform overview, key concepts, and feature summary |
13
+ | **chat** | AI chat widget/full-page, skills, streaming, persistence |
14
+ | **pipelines** | Backend automation with handler chains and DB Records |
15
+ | **proxy-rules** | Forward requests to backend APIs, eliminate CORS |
16
+ | **repository** | Deployments, aliases, content browser, rollback |
17
+ | **share-links** | Token-based sharing for private deployments |
18
+ | **traffic-splitting** | A/B testing, canary deployments, weighted routing |
19
+ | **upload-artifact** | GitHub Action for uploading builds to BFFless |
20
+
21
+ ## Install
22
+
23
+ ### Via Claude Code Plugin Marketplace
24
+
25
+ ```bash
26
+ # Add the marketplace
27
+ /plugin marketplace add bffless/claude-skills
28
+
29
+ # Install the plugin
30
+ /plugin install bffless
31
+ ```
32
+
33
+ ### Via CLI
34
+
35
+ ```bash
36
+ claude plugin install bffless --scope user
37
+ ```
38
+
39
+ ### Local Development
40
+
41
+ If you're contributing or want to use a local copy:
42
+
43
+ ```bash
44
+ git clone https://github.com/bffless/claude-skills.git
45
+ claude --plugin-dir ./claude-skills
46
+ ```
47
+
48
+ ## Usage
49
+
50
+ Once installed, Claude Code automatically uses these skills when you ask about BFFless features. For example:
51
+
52
+ - "Set up a proxy rule to forward /api requests to my backend"
53
+ - "Add AI chat to my site with streaming"
54
+ - "Configure traffic splitting for a canary deployment"
55
+ - "Set up the upload-artifact GitHub Action for my repo"
56
+
57
+ Skills are invoked by name with the `bffless` namespace:
58
+
59
+ ```
60
+ /bffless:chat
61
+ /bffless:proxy-rules
62
+ /bffless:pipelines
63
+ ```
64
+
65
+ ## BFFless Pipeline Skills vs Claude Code Skills
66
+
67
+ This package contains **Claude Code plugin skills** — they teach Claude about the BFFless platform so it can assist you as a developer.
68
+
69
+ These are different from **BFFless pipeline skills**, which are markdown files you create in your own project's `.bffless/skills/` directory. Pipeline skills are deployed with your site and loaded by the AI chat handler at runtime to give your chatbot domain-specific knowledge.
70
+
71
+ | | Claude Code Skills (this package) | Pipeline Skills (your project) |
72
+ | ------------ | --------------------------------------- | --------------------------------------- |
73
+ | **Purpose** | Help Claude help _you_ build on BFFless | Give _your chatbot_ domain knowledge |
74
+ | **Location** | Installed as Claude Code plugin | `.bffless/skills/` in your project repo |
75
+ | **Used by** | Claude Code (your dev tool) | BFFless AI chat handler (your users) |
76
+ | **Deployed** | npm install | `bffless/upload-artifact` GitHub Action |
77
+
78
+ ## Documentation
79
+
80
+ - [BFFless Docs](https://docs.bffless.app)
81
+ - [Getting Started](https://docs.bffless.app/getting-started/quickstart)
82
+ - [Chat Feature](https://docs.bffless.app/features/chat/)
83
+ - [Pipelines](https://docs.bffless.app/features/pipelines/)
84
+
85
+ ## Contributing
86
+
87
+ 1. Fork this repo
88
+ 2. Add or update skills in `skills/<skill-name>/SKILL.md`
89
+ 3. Each skill needs YAML frontmatter with `name` and `description`
90
+ 4. Open a PR — CI validates all skills automatically
91
+
92
+ ## License
93
+
94
+ MIT
package/package.json ADDED
@@ -0,0 +1,23 @@
1
+ {
2
+ "name": "@bffless/claude-skills",
3
+ "version": "1.1.0",
4
+ "description": "Claude Code plugin with BFFless platform skills",
5
+ "keywords": [
6
+ "claude-code-plugin",
7
+ "bffless",
8
+ "skills",
9
+ "ai",
10
+ "static-hosting"
11
+ ],
12
+ "author": "BFFless",
13
+ "license": "MIT",
14
+ "homepage": "https://docs.bffless.app",
15
+ "repository": {
16
+ "type": "git",
17
+ "url": "https://github.com/bffless/claude-skills"
18
+ },
19
+ "files": [
20
+ ".claude-plugin/",
21
+ "skills/"
22
+ ]
23
+ }
@@ -0,0 +1,59 @@
1
+ ---
2
+ name: authorization
3
+ description: Two-level permission system with global and project roles
4
+ ---
5
+
6
+ # Authorization
7
+
8
+ **Docs**: https://docs.bffless.app/features/authorization/
9
+
10
+ BFFless uses a two-level permission system: global roles for workspace-wide access and project roles for fine-grained control.
11
+
12
+ ## Global Roles
13
+
14
+ | Role | Capabilities |
15
+ |------|-------------|
16
+ | **Admin** | Full workspace access, manage users, billing, settings |
17
+ | **User** | Create projects, manage own content |
18
+ | **Member** | View-only access, participate in assigned projects |
19
+
20
+ ## Project Roles
21
+
22
+ | Role | Capabilities |
23
+ |------|-------------|
24
+ | **Owner** | Full control, delete project, transfer ownership |
25
+ | **Admin** | Manage settings, users, deployments |
26
+ | **Contributor** | Deploy, create aliases, modify content |
27
+ | **Viewer** | Read-only access to project and deployments |
28
+
29
+ ## Permission Sources
30
+
31
+ Users can receive project access from multiple sources:
32
+
33
+ 1. **Direct assignment**: Explicitly added to project
34
+ 2. **Group membership**: Inherited from user group
35
+ 3. **Effective role**: Highest permission wins when multiple sources exist
36
+
37
+ ## API Keys
38
+
39
+ Two types of API keys for automation:
40
+
41
+ - **Global keys**: Workspace-wide access, use the creator's permissions
42
+ - **Project keys**: Scoped to single project, specify exact role
43
+
44
+ Best practice: Use project-scoped keys with minimum required permissions.
45
+
46
+ ## Common Patterns
47
+
48
+ **External contractors**: Add as Member globally, Contributor on specific projects
49
+
50
+ **CI/CD pipelines**: Create project API key with Contributor role
51
+
52
+ **Client preview access**: Use share links instead of user accounts
53
+
54
+ ## Troubleshooting
55
+
56
+ **"Permission denied" errors?**
57
+ - Check effective role (may be inherited from group)
58
+ - Verify API key scope matches the project
59
+ - Global Members need explicit project assignment
@@ -0,0 +1,158 @@
1
+ ---
2
+ name: bffless
3
+ description: Knowledge about BFFless platform, features, and setup
4
+ ---
5
+
6
+ # BFFless Platform Guide
7
+
8
+ BFFless is a self-hosted static asset hosting platform designed for modern frontend deployments. It provides a Backend-for-Frontend (BFF) layer without requiring you to write backend code.
9
+
10
+ ## What is BFFless?
11
+
12
+ BFFless is a platform that:
13
+
14
+ - **Hosts static assets** from your CI/CD pipeline (React, Vue, Angular, etc.)
15
+ - **Provides AI-powered pipelines** for backend automation without writing code
16
+ - **Manages deployments** with aliases like `production`, `staging`, `preview`
17
+ - **Handles custom domains** with automatic SSL via Let's Encrypt
18
+ - **Enables traffic splitting** for A/B testing and canary deployments
19
+ - **Offers proxy rules** to forward requests to backend APIs
20
+
21
+ ### Key Concepts
22
+
23
+ | Concept | Description |
24
+ | -------------- | --------------------------------------------------------------- |
25
+ | **Deployment** | A snapshot of your build artifacts at a specific commit SHA |
26
+ | **Alias** | A named pointer to a deployment (e.g., `production` → `abc123`) |
27
+ | **Proxy Rule** | Routes requests to external APIs or AI pipelines |
28
+ | **Pipeline** | Chain of handlers that process requests (AI, transform, proxy) |
29
+ | **Skill** | Markdown files that give AI agents specialized knowledge |
30
+
31
+ ## Setting Up Proxy Rules
32
+
33
+ Proxy rules let you route requests through BFFless to backend APIs or AI pipelines.
34
+
35
+ ### Creating a Proxy Rule
36
+
37
+ 1. Go to **Project Settings** → **Proxy Rules**
38
+ 2. Click **Add Rule**
39
+ 3. Configure the rule:
40
+
41
+ ```
42
+ Path Pattern: /api/*
43
+ Target URL: https://your-backend.com
44
+ Strip Prefix: true (removes /api from forwarded requests)
45
+ ```
46
+
47
+ ### Rule Types
48
+
49
+ | Type | Use Case |
50
+ | -------------------- | ---------------------------------------- |
51
+ | **External Proxy** | Forward to external APIs (REST, GraphQL) |
52
+ | **Pipeline** | Process with AI handlers |
53
+ | **Internal Rewrite** | Serve different static files |
54
+
55
+ ### Common Patterns
56
+
57
+ **API Gateway:**
58
+
59
+ ```
60
+ /api/* → https://api.example.com/*
61
+ ```
62
+
63
+ **AI Chat Endpoint:**
64
+
65
+ ```
66
+ /api/chat → Pipeline with AI handler
67
+ ```
68
+
69
+ **Microservices:**
70
+
71
+ ```
72
+ /api/users/* → https://users-service.internal
73
+ /api/orders/* → https://orders-service.internal
74
+ ```
75
+
76
+ ## Traffic Splitting
77
+
78
+ Traffic splitting distributes requests across multiple deployment aliases for A/B testing or gradual rollouts.
79
+
80
+ ### How It Works
81
+
82
+ 1. Configure weights per alias (e.g., 90% production, 10% canary)
83
+ 2. First-time visitors get randomly assigned based on weights
84
+ 3. A cookie (`__bffless_variant`) maintains sticky sessions
85
+ 4. Users see consistent experience on return visits
86
+
87
+ ### Setting Up Traffic Splitting
88
+
89
+ 1. Go to **Domains** → Select your domain
90
+ 2. Click **Traffic Splitting**
91
+ 3. Add aliases with weights:
92
+
93
+ | Alias | Weight |
94
+ | ---------- | ------ |
95
+ | production | 90% |
96
+ | canary | 10% |
97
+
98
+ 4. Save changes
99
+
100
+ ### Use Cases
101
+
102
+ - **A/B Testing**: Compare two versions of your app
103
+ - **Canary Deployments**: Gradually roll out new features
104
+ - **Blue/Green**: Instant switch between deployments
105
+ - **Feature Flags**: Route specific traffic to experimental builds
106
+
107
+ ### Best Practices
108
+
109
+ - Start with small percentages for new deployments (5-10%)
110
+ - Monitor error rates before increasing traffic
111
+ - Use the `X-Variant` header to track which variant served the request
112
+ - Cookie duration is configurable (default: 24 hours)
113
+
114
+ ## Pipelines and AI Handlers
115
+
116
+ Pipelines let you create backend logic without writing code.
117
+
118
+ ### Pipeline Structure
119
+
120
+ A pipeline is a chain of steps:
121
+
122
+ ```
123
+ Request → Step 1 → Step 2 → Step 3 → Response
124
+ ```
125
+
126
+ ### AI Handler
127
+
128
+ The AI handler uses LLMs to process requests:
129
+
130
+ - Configure system prompts
131
+ - Set model and temperature
132
+ - Enable skills for specialized knowledge
133
+ - Stream responses for chat interfaces
134
+
135
+ ### Example: Chat API
136
+
137
+ 1. Create a pipeline with an AI handler
138
+ 2. Configure:
139
+ - Model: `gpt-4` or `claude-3`
140
+ - System Prompt: Your assistant instructions
141
+ - Skills: Enable relevant skills
142
+ 3. Create a proxy rule pointing to the pipeline
143
+ 4. Your frontend calls `/api/chat` and gets AI responses
144
+
145
+ ## GitHub Action Integration
146
+
147
+ Upload builds automatically from CI/CD:
148
+
149
+ ```yaml
150
+ - uses: bffless/upload-artifact@v1
151
+ with:
152
+ path: dist
153
+ api-url: ${{ vars.BFFLESS_URL }}
154
+ api-key: ${{ secrets.BFFLESS_KEY }}
155
+ alias: production
156
+ ```
157
+
158
+ This uploads your build and updates the `production` alias to point to it.
@@ -0,0 +1,196 @@
1
+ ---
2
+ name: chat
3
+ description: Adding AI chat to a site with full page or popup widget layouts, skills, streaming, and message persistence
4
+ ---
5
+
6
+ # Chat
7
+
8
+ **Docs**: https://docs.bffless.app/features/chat/
9
+
10
+ Add an AI-powered chat experience to any site — no backend code required. Choose between a full page chat interface or a popup widget, give your chatbot domain knowledge with skills, and let BFFless handle streaming, persistence, and deployment.
11
+
12
+ ## Overview
13
+
14
+ BFFless Chat provides:
15
+
16
+ - **No backend code** — configure everything through the admin UI
17
+ - **Streaming responses** — real-time token-by-token output via Server-Sent Events
18
+ - **Skills** — domain-specific knowledge from markdown files deployed with your site
19
+ - **Message persistence** — conversations and messages saved automatically to DB Records
20
+ - **A/B testable** — combine with traffic splitting to test different skills or prompts
21
+ - **Two layouts** — full page chat or floating popup widget
22
+
23
+ ## Quick Start
24
+
25
+ ### 1. Generate a Chat Schema
26
+
27
+ 1. Go to **Pipelines → DB Records**
28
+ 2. Click **Generate Schema**
29
+ 3. Select **Chat Schema**
30
+ 4. Enter a name (e.g., `support`)
31
+ 5. Choose a scope:
32
+ - **User-scoped** — conversations tied to authenticated users
33
+ - **Guest-scoped** — conversations accessible without authentication
34
+ 6. Click **Generate**
35
+
36
+ This creates:
37
+ - A `{name}_conversations` DB Record for conversation metadata
38
+ - A `{name}_messages` DB Record for individual messages
39
+ - A pipeline with a `POST /api/chat` endpoint pre-configured with the AI handler
40
+
41
+ ### 2. Configure an AI Provider
42
+
43
+ 1. Navigate to **Settings → AI**
44
+ 2. Select a provider (OpenAI, Anthropic, or Google AI)
45
+ 3. Enter your API key
46
+ 4. Choose a default model
47
+ 5. Click **Test Connection** to verify
48
+ 6. Save
49
+
50
+ ### 3. Connect Your Frontend
51
+
52
+ Use the AI SDK's `useChat` hook:
53
+
54
+ ```tsx
55
+ import { useChat } from '@ai-sdk/react';
56
+
57
+ function Chat() {
58
+ const { messages, input, handleInputChange, handleSubmit, status } = useChat({
59
+ api: '/api/chat',
60
+ });
61
+
62
+ return (
63
+ <div>
64
+ {messages.map((m) => (
65
+ <div key={m.id}>
66
+ <strong>{m.role}:</strong> {m.parts.map(p => p.text).join('')}
67
+ </div>
68
+ ))}
69
+ <form onSubmit={handleSubmit}>
70
+ <input value={input} onChange={handleInputChange} placeholder="Type a message..." />
71
+ <button type="submit" disabled={status === 'streaming'}>Send</button>
72
+ </form>
73
+ </div>
74
+ );
75
+ }
76
+ ```
77
+
78
+ ### 4. Deploy
79
+
80
+ Push your code to GitHub and deploy with the `bffless/upload-artifact` GitHub Action. Your chat endpoint is live as soon as the deployment completes.
81
+
82
+ ## Chat Layouts
83
+
84
+ ### Full Page Chat
85
+
86
+ A standalone chat page that takes over the full viewport. Includes suggested prompts, real-time streaming with markdown rendering, and a clean conversational UI.
87
+
88
+ Best for: dedicated support pages, knowledge base assistants, internal tools.
89
+
90
+ ### Popup Widget
91
+
92
+ A floating chat bubble that opens a slide-up chat panel. Users can start a new conversation or close the widget without losing context. The widget stays accessible on any page.
93
+
94
+ Best for: landing pages, documentation sites, e-commerce — anywhere you want chat available without dedicating a full page.
95
+
96
+ ## Skills
97
+
98
+ Skills are markdown files that give your chatbot domain-specific knowledge. Deploy them alongside your site and the AI loads relevant skills on-demand during conversations.
99
+
100
+ Skills are **versioned with each deployment** — when an alias points to a commit, the skills for that commit are used. This makes them git-managed, rollback-safe, and A/B testable with traffic splitting.
101
+
102
+ ### Creating a Skill
103
+
104
+ Add a `SKILL.md` file to `.bffless/skills/<skill-name>/`:
105
+
106
+ ```markdown
107
+ ---
108
+ name: pricing-faq
109
+ description: Answer questions about pricing, plans, and billing
110
+ ---
111
+
112
+ # Pricing FAQ
113
+
114
+ (Your knowledge content here in markdown)
115
+ ```
116
+
117
+ ### Deploying Skills
118
+
119
+ Upload skills alongside your build artifacts:
120
+
121
+ ```yaml
122
+ - name: Deploy build
123
+ uses: bffless/upload-artifact@v1
124
+ with:
125
+ source: dist
126
+
127
+ - name: Deploy skills
128
+ uses: bffless/upload-artifact@v1
129
+ with:
130
+ source: .bffless
131
+ ```
132
+
133
+ ### Configuring Skills in Pipelines
134
+
135
+ Set the skills mode in the AI handler configuration:
136
+
137
+ | Mode | Description |
138
+ |------|-------------|
139
+ | **None** | Disable all skills (default) |
140
+ | **All** | Enable all uploaded skills |
141
+ | **Selected** | Enable only specific skills by name |
142
+
143
+ ## Message Persistence
144
+
145
+ When enabled, conversations and messages are automatically saved to DB Records. The handler manages:
146
+
147
+ - **Conversations**: chat_id, message_count, total_tokens, model
148
+ - **Messages**: conversation_id, role, content, tokens_used
149
+
150
+ Message persistence is optional — for simple use cases, skip it entirely and chat works without any database configuration.
151
+
152
+ ## Configuration
153
+
154
+ Key settings for the AI chat handler:
155
+
156
+ | Setting | Description | Options / Default |
157
+ |---------|-------------|-------------------|
158
+ | **Mode** | Chat or Completion | `chat`, `completion` |
159
+ | **Provider** | AI provider | `openai`, `anthropic`, `google` |
160
+ | **Model** | Specific model | Provider-dependent |
161
+ | **System Prompt** | Instructions for the AI | Free-text |
162
+ | **Response Format** | Stream or JSON | `stream`, `message` |
163
+ | **Skills Mode** | Which skills to enable | `none`, `all`, `selected` |
164
+ | **Temperature** | Response creativity | `0` – `2` (default: `0.7`) |
165
+ | **Max Tokens** | Maximum output length | `256` – `100000` (default: `4096`) |
166
+ | **Max History** | Messages in context | `0` – `200` (default: `50`) |
167
+
168
+ ## Supported Providers
169
+
170
+ | Provider | Models | Default |
171
+ |----------|--------|---------|
172
+ | OpenAI | gpt-4o, gpt-4-turbo, gpt-4, gpt-4o-mini, gpt-3.5-turbo | gpt-4o |
173
+ | Anthropic | claude-opus-4-6, claude-sonnet-4-6, claude-haiku-4-5 | claude-sonnet-4-6 |
174
+ | Google AI | gemini-1.5-pro, gemini-1.5-flash, gemini-1.5-flash-8b | gemini-1.5-pro |
175
+
176
+ ## Demo
177
+
178
+ - Full page chat: https://chat.docs.bffless.app/
179
+ - Popup widget: https://chat.docs.bffless.app/popup/
180
+ - Source code: https://github.com/bffless/demo-chat
181
+
182
+ ## Troubleshooting
183
+
184
+ **Chat responses not streaming?**
185
+ - Verify response format is set to **Stream (SSE)**
186
+ - Ensure the AI handler is the **last step** in your pipeline
187
+ - Check frontend is using `useChat` from `@ai-sdk/react`
188
+
189
+ **Skills not loading?**
190
+ - Verify `.bffless/skills/` exists in your deployment
191
+ - Ensure skills mode is set to **All** or **Selected** (not None)
192
+ - Check each skill has valid `SKILL.md` with YAML frontmatter (name and description)
193
+
194
+ **Messages not persisting?**
195
+ - Ensure **Message Persistence** is enabled in the AI handler config
196
+ - Verify both Conversations Schema and Messages Schema are selected
@@ -0,0 +1,81 @@
1
+ ---
2
+ name: pipelines
3
+ description: Backend automation without code using handler chains
4
+ ---
5
+
6
+ # Pipelines
7
+
8
+ **Docs**: https://docs.bffless.app/features/pipelines/
9
+
10
+ Pipelines provide backend functionality for static sites without writing server code. Chain handlers together to process forms, store data, send emails, and more.
11
+
12
+ ## Handler Types
13
+
14
+ | Handler | Purpose |
15
+ |---------|---------|
16
+ | **Form** | Parse form submissions (multipart, JSON, URL-encoded) |
17
+ | **Data CRUD** | Create, read, update, delete DB Records |
18
+ | **Email** | Send emails via configured provider |
19
+ | **Response** | Return custom JSON or redirect |
20
+ | **Function** | Custom JavaScript for complex logic |
21
+ | **Aggregate** | Combine data from multiple sources |
22
+
23
+ ## DB Records
24
+
25
+ Schema-based data storage built into BFFless:
26
+
27
+ 1. Define schema in project settings (fields, types, validation)
28
+ 2. Use Data CRUD handler to interact with records
29
+ 3. Query with filters, sorting, pagination
30
+
31
+ ## Expression Syntax
32
+
33
+ Access data throughout the pipeline using expressions:
34
+
35
+ - `input.*` - Parsed request body
36
+ - `query.*` - URL query parameters
37
+ - `params.*` - URL path parameters
38
+ - `headers.*` - Request headers
39
+ - `steps.<name>.*` - Output from previous handler
40
+ - `user.*` - Authenticated user info (if applicable)
41
+
42
+ Example: `${input.email}` or `${steps.createUser.id}`
43
+
44
+ ## Common Workflows
45
+
46
+ **Contact form:**
47
+ 1. Form handler → parse submission
48
+ 2. Data CRUD → store in "submissions" schema
49
+ 3. Email → notify admin
50
+ 4. Response → thank you message
51
+
52
+ **Waitlist signup:**
53
+ 1. Form handler → parse email
54
+ 2. Data CRUD → check if exists, then create
55
+ 3. Email → send confirmation to user
56
+ 4. Response → success or "already registered"
57
+
58
+ **Webhook receiver:**
59
+ 1. Form handler → parse JSON payload
60
+ 2. Function → validate signature, transform data
61
+ 3. Data CRUD → store event
62
+ 4. Response → 200 OK
63
+
64
+ ## Configuration Tips
65
+
66
+ 1. Name handlers descriptively for readable expressions
67
+ 2. Use Response handler last to control what client sees
68
+ 3. Test with simple inputs before adding validation
69
+ 4. Check pipeline logs for debugging failed executions
70
+
71
+ ## Troubleshooting
72
+
73
+ **Pipeline not triggering?**
74
+ - Verify endpoint path matches request URL
75
+ - Check HTTP method (GET, POST, etc.) is correct
76
+ - Ensure pipeline is enabled and deployed
77
+
78
+ **Expression returning undefined?**
79
+ - Check handler name matches exactly (case-sensitive)
80
+ - Verify previous handler completed successfully
81
+ - Use pipeline logs to see actual values at each step
@@ -0,0 +1,83 @@
1
+ ---
2
+ name: proxy-rules
3
+ description: Forward requests to backend APIs without CORS
4
+ ---
5
+
6
+ # Proxy Rules
7
+
8
+ **Docs**: https://docs.bffless.app/features/proxy-rules/
9
+
10
+ Proxy rules forward requests from your static site to backend APIs, eliminating CORS issues and hiding API endpoints from clients.
11
+
12
+ ## Configuration Levels
13
+
14
+ **Project defaults**: Apply to all aliases unless overridden
15
+
16
+ **Alias overrides**: Specific aliases can have different proxy configurations
17
+
18
+ ## Rule Structure
19
+
20
+ Each rule specifies:
21
+ - **Path pattern**: Which requests to intercept
22
+ - **Target**: Backend URL to forward to
23
+ - **Strip prefix**: Whether to remove the matched prefix
24
+
25
+ ## Pattern Types
26
+
27
+ **Prefix match** (most common):
28
+ ```
29
+ /api/* → https://api.example.com
30
+ ```
31
+ Request to `/api/users` forwards to `https://api.example.com/users`
32
+
33
+ **Exact match**:
34
+ ```
35
+ /health → https://backend.example.com/status
36
+ ```
37
+ Only exact path matches, no wildcards
38
+
39
+ **Suffix match**:
40
+ ```
41
+ *.json → https://data.example.com
42
+ ```
43
+ Matches any path ending in `.json`
44
+
45
+ ## Strip Prefix Behavior
46
+
47
+ With strip prefix ON (default):
48
+ ```
49
+ /api/* → https://backend.com
50
+ /api/users → https://backend.com/users
51
+ ```
52
+
53
+ With strip prefix OFF:
54
+ ```
55
+ /api/* → https://backend.com
56
+ /api/users → https://backend.com/api/users
57
+ ```
58
+
59
+ ## Common Patterns
60
+
61
+ **API proxy**: `/api/*` → your backend server
62
+
63
+ **Third-party API**: `/stripe/*` → `https://api.stripe.com` (hides API from client)
64
+
65
+ **Microservices**: Different prefixes route to different services
66
+
67
+ ## Security Notes
68
+
69
+ - All proxy targets must use HTTPS
70
+ - BFFless validates targets to prevent SSRF attacks
71
+ - Headers like `Host` are rewritten to match target
72
+ - Client IP forwarded via `X-Forwarded-For`
73
+
74
+ ## Troubleshooting
75
+
76
+ **Requests not proxying?**
77
+ - Check path pattern matches request URL exactly
78
+ - Verify alias isn't overriding project defaults
79
+ - Confirm target URL is HTTPS and reachable
80
+
81
+ **Getting CORS errors still?**
82
+ - Ensure the proxy rule is active on the alias being accessed
83
+ - Check browser DevTools for actual request URL (may not be hitting proxy)
@@ -0,0 +1,64 @@
1
+ ---
2
+ name: repository
3
+ description: Browse deployments, manage aliases, view branches
4
+ ---
5
+
6
+ # Repository
7
+
8
+ **Docs**: https://docs.bffless.app/features/repository-overview/
9
+
10
+ The Repository is your central hub for browsing deployments, managing aliases, and navigating your project's content.
11
+
12
+ ## Content Browser
13
+
14
+ The browser has four panels:
15
+
16
+ 1. **Files Panel**: Navigate directory structure, search files
17
+ 2. **Preview Panel**: Live preview of selected file
18
+ 3. **History Panel**: Deployment timeline, compare versions
19
+ 4. **References Panel**: See which aliases point to this deployment
20
+
21
+ ## Deployments
22
+
23
+ Each deployment is an immutable snapshot of your build output. Deployments are identified by:
24
+
25
+ - **Deployment ID**: Unique hash
26
+ - **Git info**: Branch, commit SHA, commit message (if available)
27
+ - **Timestamp**: When deployed
28
+ - **Size**: Total file size
29
+
30
+ ## Aliases
31
+
32
+ Aliases are named pointers to deployments. Two types:
33
+
34
+ **Manual aliases**: You control which deployment they point to
35
+ - `production`, `staging`, `v1.2.0`
36
+ - Update manually or via API
37
+
38
+ **Auto-preview aliases**: Automatically created for branches/PRs
39
+ - `preview-feature-branch`, `pr-123`
40
+ - Updated on each push, deleted when branch is deleted
41
+
42
+ ## Common Workflows
43
+
44
+ **Deploy new version:**
45
+ 1. Upload via CLI/API/GitHub Action
46
+ 2. New deployment appears in Repository
47
+ 3. Update alias to point to new deployment
48
+
49
+ **Rollback:**
50
+ 1. Find previous deployment in History
51
+ 2. Update production alias to point to it
52
+ 3. Instant rollback, no rebuild needed
53
+
54
+ **Preview PRs:**
55
+ 1. Configure auto-preview in project settings
56
+ 2. Each PR gets unique preview URL
57
+ 3. Preview updates on each push
58
+
59
+ ## Navigation Tips
60
+
61
+ - Use keyboard shortcuts: `j/k` to navigate files, `Enter` to preview
62
+ - Search supports glob patterns: `*.html`, `components/**`
63
+ - Click deployment hash to copy full URL
64
+ - Right-click alias for quick actions menu
@@ -0,0 +1,53 @@
1
+ ---
2
+ name: share-links
3
+ description: Token-based sharing for private deployments
4
+ ---
5
+
6
+ # Share Links
7
+
8
+ **Docs**: https://docs.bffless.app/features/share-links/
9
+
10
+ Share links allow sharing private deployments without requiring authentication. Each link contains a unique token that grants temporary access.
11
+
12
+ ## Creating Share Links
13
+
14
+ 1. Navigate to your deployment in the Repository
15
+ 2. Click the **Share** button in the toolbar
16
+ 3. Configure options:
17
+ - **Expiration**: Set duration or leave unlimited
18
+ - **Usage limit**: Max number of visits (optional)
19
+ - **Label**: Descriptive name for tracking
20
+ 4. Copy the generated URL
21
+
22
+ ## Link Management
23
+
24
+ - **View usage**: See visit count and last accessed time
25
+ - **Disable**: Temporarily suspend access without deleting
26
+ - **Regenerate**: Create new token, invalidating the old URL
27
+ - **Delete**: Permanently remove access
28
+
29
+ ## Use Cases
30
+
31
+ - **Portfolio sharing**: Send private work to potential clients
32
+ - **Client reviews**: Share staging sites for feedback
33
+ - **Beta testing**: Distribute preview builds to testers
34
+ - **Time-limited access**: Demos that expire after a meeting
35
+
36
+ ## Best Practices
37
+
38
+ 1. Use descriptive labels to track who has which link
39
+ 2. Set expiration dates for sensitive content
40
+ 3. Combine with traffic splitting to show different content per link
41
+ 4. Regenerate tokens if a link is compromised
42
+ 5. Monitor usage to detect unexpected access patterns
43
+
44
+ ## Troubleshooting
45
+
46
+ **Link not working?**
47
+ - Check if the link is disabled or expired
48
+ - Verify usage limit hasn't been reached
49
+ - Ensure the deployment still exists
50
+
51
+ **Need to revoke access?**
52
+ - Disable the link immediately, or delete it entirely
53
+ - Regenerate creates a new URL while keeping tracking history
@@ -0,0 +1,63 @@
1
+ ---
2
+ name: traffic-splitting
3
+ description: Distribute traffic across aliases with weights and rules
4
+ ---
5
+
6
+ # Traffic Splitting
7
+
8
+ **Docs**: https://docs.bffless.app/features/traffic-splitting/
9
+
10
+ Traffic splitting distributes requests across multiple deployment aliases. Use it for A/B testing, canary deployments, and personalized experiences.
11
+
12
+ ## Configuration
13
+
14
+ ### Weights
15
+
16
+ Assign percentage weights to aliases. Weights must sum to 100.
17
+
18
+ ```
19
+ production: 90%
20
+ canary: 10%
21
+ ```
22
+
23
+ ### Sticky Sessions
24
+
25
+ When enabled, visitors consistently see the same variant. Controlled via cookie. Disable for true random distribution per request.
26
+
27
+ ### Traffic Rules
28
+
29
+ Rules override weights based on conditions. Evaluated in order, first match wins.
30
+
31
+ **Rule conditions:**
32
+ - **Headers**: Match request headers (e.g., `X-Beta-User: true`)
33
+ - **Query params**: Match URL parameters (e.g., `?variant=new`)
34
+ - **Cookies**: Match cookie values
35
+ - **Share link**: Route specific share links to specific aliases
36
+
37
+ ## Use Cases
38
+
39
+ **A/B Testing**: Split traffic 50/50 between variants, measure conversion
40
+
41
+ **Canary Deployment**: Send 5% to new version, monitor for errors, gradually increase
42
+
43
+ **Beta Features**: Route users with beta header to feature branch
44
+
45
+ **Personalized Demos**: Use share links to show customized content per client
46
+
47
+ ## Configuration Tips
48
+
49
+ 1. Start canary deployments at 5-10%, increase gradually
50
+ 2. Enable sticky sessions for consistent user experience
51
+ 3. Use rules for deterministic routing (internal testing, specific clients)
52
+ 4. Combine with share links for per-recipient personalization
53
+
54
+ ## Troubleshooting
55
+
56
+ **Unexpected routing?**
57
+ - Rules are evaluated before weights; check rule order
58
+ - Clear cookies if sticky session is routing to old variant
59
+ - Verify alias names match exactly (case-sensitive)
60
+
61
+ **Traffic percentages seem off?**
62
+ - Small sample sizes show high variance; need 100+ requests for accuracy
63
+ - Sticky sessions can skew percentages if users have different visit frequencies
@@ -0,0 +1,195 @@
1
+ ---
2
+ name: upload-artifact
3
+ description: GitHub Action for uploading build artifacts to BFFless
4
+ ---
5
+
6
+ # BFFless Upload Artifact Action
7
+
8
+ The `bffless/upload-artifact` GitHub Action uploads build artifacts from your CI/CD pipeline to a BFFless instance. It's available on the [GitHub Marketplace](https://github.com/bffless/upload-artifact).
9
+
10
+ For full documentation, see the [README on GitHub](https://github.com/bffless/upload-artifact).
11
+
12
+ ## Quick Start
13
+
14
+ Only 3 inputs are required:
15
+
16
+ ```yaml
17
+ - uses: bffless/upload-artifact@v1
18
+ with:
19
+ path: dist
20
+ api-url: ${{ vars.ASSET_HOST_URL }}
21
+ api-key: ${{ secrets.ASSET_HOST_KEY }}
22
+ ```
23
+
24
+ ## Common Workflows
25
+
26
+ ### PR Preview with Comment
27
+
28
+ ```yaml
29
+ jobs:
30
+ build:
31
+ runs-on: ubuntu-latest
32
+ permissions:
33
+ contents: read
34
+ pull-requests: write # Required for PR comments
35
+ steps:
36
+ - uses: actions/checkout@v4
37
+ with:
38
+ fetch-depth: 0 # Required for commit timestamp
39
+
40
+ - name: Build
41
+ run: npm run build
42
+
43
+ - uses: bffless/upload-artifact@v1
44
+ with:
45
+ path: dist
46
+ api-url: ${{ vars.ASSET_HOST_URL }}
47
+ api-key: ${{ secrets.ASSET_HOST_KEY }}
48
+ alias: preview
49
+ description: 'PR #${{ github.event.pull_request.number }} preview'
50
+ pr-comment: true
51
+ github-token: ${{ secrets.GITHUB_TOKEN }}
52
+ ```
53
+
54
+ ### Production Deploy
55
+
56
+ ```yaml
57
+ - uses: bffless/upload-artifact@v1
58
+ id: deploy
59
+ with:
60
+ path: dist
61
+ api-url: ${{ vars.ASSET_HOST_URL }}
62
+ api-key: ${{ secrets.ASSET_HOST_KEY }}
63
+ alias: production
64
+ tags: ${{ needs.release.outputs.version }}
65
+ description: 'Release ${{ needs.release.outputs.version }}'
66
+
67
+ - run: echo "Deployed to ${{ steps.deploy.outputs.sha-url }}"
68
+ ```
69
+
70
+ ### Multiple Artifacts (Same Workflow)
71
+
72
+ You can upload multiple artifacts in the same workflow:
73
+
74
+ ```yaml
75
+ - name: Upload frontend
76
+ uses: bffless/upload-artifact@v1
77
+ with:
78
+ path: apps/frontend/dist
79
+ api-url: ${{ vars.ASSET_HOST_URL }}
80
+ api-key: ${{ secrets.ASSET_HOST_KEY }}
81
+ alias: production
82
+ base-path: /dist
83
+
84
+ - name: Upload skills
85
+ uses: bffless/upload-artifact@v1
86
+ with:
87
+ path: .bffless
88
+ api-url: ${{ vars.ASSET_HOST_URL }}
89
+ api-key: ${{ secrets.ASSET_HOST_KEY }}
90
+ alias: production
91
+ ```
92
+
93
+ ## All Inputs
94
+
95
+ | Input | Required | Default | Description |
96
+ |-------|----------|---------|-------------|
97
+ | `path` | **yes** | -- | Build directory to upload |
98
+ | `api-url` | **yes** | -- | BFFless platform URL |
99
+ | `api-key` | **yes** | -- | API key for authentication |
100
+ | `repository` | no | `github.repository` | Repository in `owner/repo` format |
101
+ | `commit-sha` | no | auto | Git commit SHA |
102
+ | `branch` | no | auto | Branch name |
103
+ | `is-public` | no | `'true'` | Public visibility |
104
+ | `alias` | no | -- | Deployment alias (e.g., `production`) |
105
+ | `base-path` | no | `/<path>` | Path prefix in zip |
106
+ | `committed-at` | no | auto | ISO 8601 commit timestamp |
107
+ | `description` | no | -- | Human-readable description |
108
+ | `proxy-rule-set-name` | no | -- | Proxy rule set name |
109
+ | `proxy-rule-set-id` | no | -- | Proxy rule set ID |
110
+ | `tags` | no | -- | Comma-separated tags |
111
+ | `summary` | no | `'true'` | Write GitHub Step Summary |
112
+ | `summary-title` | no | `'Deployment Summary'` | Summary heading |
113
+ | `working-directory` | no | `'.'` | Working directory |
114
+ | `pr-comment` | no | `'false'` | Post comment on PR |
115
+ | `comment-header` | no | `'🚀 BFFLESS Deployment'` | PR comment header |
116
+ | `github-token` | no | `GITHUB_TOKEN` | Token for PR comments |
117
+
118
+ ## Outputs
119
+
120
+ | Output | Description |
121
+ |--------|-------------|
122
+ | `deployment-url` | Primary URL (SHA-based) |
123
+ | `sha-url` | Immutable SHA-based URL |
124
+ | `alias-url` | Alias-based URL |
125
+ | `preview-url` | Preview URL (if basePath provided) |
126
+ | `branch-url` | Branch-based URL |
127
+ | `deployment-id` | API deployment ID |
128
+ | `file-count` | Number of files uploaded |
129
+ | `total-size` | Total bytes |
130
+ | `response` | Raw JSON response |
131
+
132
+ ## How It Works
133
+
134
+ 1. **Validates** the build directory exists
135
+ 2. **Zips** the directory preserving structure
136
+ 3. **Uploads** via multipart POST to `/api/deployments/zip`
137
+ 4. **Sets outputs** from API response
138
+ 5. **Writes Step Summary** with deployment table
139
+ 6. **Posts PR comment** (if enabled)
140
+ 7. **Cleans up** temporary files
141
+
142
+ ## Auto-Detection
143
+
144
+ The action automatically detects:
145
+
146
+ - **Repository**: from `github.repository`
147
+ - **Commit SHA**: PR head SHA or push SHA
148
+ - **Branch**: PR head ref or push ref
149
+ - **Committed At**: via `git log` (requires `fetch-depth: 0`)
150
+ - **Base Path**: derived from `path` input as `/<path>`
151
+
152
+ ## PR Comments
153
+
154
+ When `pr-comment: true`, the action posts a formatted comment:
155
+
156
+ > ## 🚀 BFFLESS Deployment
157
+ >
158
+ > **Alias:** `preview`
159
+ >
160
+ > | Property | Value |
161
+ > | ----------- | ---------------------------------- |
162
+ > | **Preview** | [example.com](https://example.com) |
163
+ > | **Commit** | `abc1234` |
164
+ > | **Files** | 42 |
165
+ > | **Size** | 1.2 MB |
166
+
167
+ Comments are automatically updated on subsequent pushes (no duplicates).
168
+
169
+ ## Troubleshooting
170
+
171
+ ### Missing commit timestamp
172
+
173
+ ```yaml
174
+ - uses: actions/checkout@v4
175
+ with:
176
+ fetch-depth: 0 # Full history needed for git log
177
+ ```
178
+
179
+ ### PR comment permission denied
180
+
181
+ ```yaml
182
+ permissions:
183
+ pull-requests: write # Required for comments
184
+ ```
185
+
186
+ ### Custom base path
187
+
188
+ If your app expects to be served from a subdirectory:
189
+
190
+ ```yaml
191
+ - uses: bffless/upload-artifact@v1
192
+ with:
193
+ path: build
194
+ base-path: /docs/build # Served at /docs/build/*
195
+ ```