Skip to content

Commit 300b9f2

Browse files
chore: Update skills with the new skill-creator version (#561)
1 parent 3cf954a commit 300b9f2

12 files changed

Lines changed: 166 additions & 37 deletions

File tree

.claude/hooks/pre-commit.sh

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,12 @@ if ! echo "$INPUT" | grep -q 'git commit'; then
1212
exit 0
1313
fi
1414

15+
# Skip lint in CI environments where pnpm may not be installed (e.g., claude-code-action).
16+
if ! command -v pnpm &>/dev/null; then
17+
echo "pnpm not found — skipping lint (CI environment)"
18+
exit 0
19+
fi
20+
1521
echo "--- pnpm lint ---"
1622
if ! pnpm lint; then
1723
echo "Lint failed. Fix errors before committing." >&2

.github/prompts/sync-agent-skill.md

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ When updating the skill:
1515
- Do NOT create or modify any files outside `agent-skills/workleap-squide/`.
1616
- Do NOT use TodoWrite, TaskCreate, or any task tracking tools.
1717
- Never update a versioned skill. You can identify a versioned skill with its folder name pattern, e.g. `workleap-squide-v*`.
18-
- Never change skill content unless you can point to a specific line in `./docs` that contradicts the current skill text. If you cannot identify the exact discrepancy, do not touch the content.
18+
- Never change skill content unless you can point to a specific line in `./docs` that either contradicts the current skill text or documents an API/pattern the skill is missing. If you cannot identify the exact discrepancy or omission, do not touch the content.
1919
- The SKILL.md body must stay under ~250 lines. New API content goes in the appropriate `references/` file, not in the body. Only add to the body if the content is a critical multi-file pattern that agents need in nearly every conversation.
2020

2121
## Excluded docs
@@ -165,4 +165,30 @@ The following issues could not be resolved after 3 retries:
165165
<List the failed coverage questions and/or accuracy discrepancies>"
166166
```
167167

168-
Then STOP. You are done.
168+
## If you cannot complete the workflow
169+
170+
If anything prevents you from completing the steps above — hook failures, permission errors, tool errors, validation loops that exhaust retries, or any other unrecoverable problem — do NOT stop silently. Create a GitHub issue so the team knows the sync failed and what was lost:
171+
172+
```bash
173+
gh issue create \
174+
--title "Sync agent skill: workflow failed to complete" \
175+
--label "bug" \
176+
--body "## Problem
177+
178+
The sync-agent-skill workflow could not complete successfully.
179+
180+
## What failed
181+
182+
<Describe the step that failed and the exact error message>
183+
184+
## Work completed before failure
185+
186+
<List any skill files you modified and a brief summary of each change, or 'None' if failure occurred before any changes>
187+
188+
## Next steps
189+
190+
1. Check the workflow run logs for details
191+
2. Fix the blocker and re-run the workflow, or apply the changes manually"
192+
```
193+
194+
Then STOP.

.github/prompts/update-agent-docs.md

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -159,4 +159,30 @@ The PR body must follow this structure:
159159

160160
If there are no staged changes after `git add`, output "No agent-docs update needed." and STOP.
161161

162-
Then STOP. You are done.
162+
## If you cannot complete the workflow
163+
164+
If anything prevents you from completing the steps above — hook failures, permission errors, tool errors, validation loops, or any other unrecoverable problem — do NOT stop silently. Create a GitHub issue so the team knows the update failed and what was lost:
165+
166+
```bash
167+
gh issue create \
168+
--title "Update agent docs: workflow failed to complete" \
169+
--label "bug" \
170+
--body "## Problem
171+
172+
The update-agent-docs workflow could not complete successfully.
173+
174+
## What failed
175+
176+
<Describe the step that failed and the exact error message>
177+
178+
## Work completed before failure
179+
180+
<List any files you modified and a brief summary of each change, or 'None' if failure occurred before any changes>
181+
182+
## Next steps
183+
184+
1. Check the workflow run logs for details
185+
2. Fix the blocker and re-run the workflow, or apply the changes manually"
186+
```
187+
188+
Then STOP.

.github/workflows/sync-agent-skill.yml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,21 @@ jobs:
5656
- name: Checkout
5757
uses: actions/checkout@v4
5858

59+
- name: Install pnpm
60+
uses: pnpm/action-setup@v4
61+
62+
- name: Install Node.js
63+
uses: actions/setup-node@v6
64+
with:
65+
node-version: ">=24.0.0"
66+
check-latest: true
67+
cache: 'pnpm'
68+
69+
- name: Install dependencies
70+
run: pnpm install
71+
5972
- name: Sync agent skill with docs
73+
id: claude
6074
uses: anthropics/claude-code-action@v1
6175
with:
6276
prompt: |

.github/workflows/update-agent-docs.yml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,13 +80,21 @@ jobs:
8080
# Need 2 commits so the agent can diff against HEAD~1.
8181
fetch-depth: 2
8282

83+
- name: Install pnpm
84+
uses: pnpm/action-setup@v4
85+
8386
- name: Install Node.js
8487
uses: actions/setup-node@v6
8588
with:
8689
node-version: ">=24.0.0"
8790
check-latest: true
91+
cache: 'pnpm'
92+
93+
- name: Install dependencies
94+
run: pnpm install
8895

8996
- name: Update agent documentation
97+
id: claude
9098
uses: anthropics/claude-code-action@v1
9199
with:
92100
prompt: |

agent-skills/workleap-squide/SKILL.md

Lines changed: 17 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ description: |
1111
(7) Squide hooks for event bus, environment variables, feature flags, logging, or bootstrapping state
1212
(8) Error boundaries or modular architecture in Squide applications
1313
metadata:
14-
version: 1.5
14+
version: 1.6
1515
---
1616

1717
# Squide Framework
@@ -20,23 +20,12 @@ Squide is a React modular application shell. Use only documented APIs.
2020

2121
## Core Concepts
2222

23-
### Runtime
24-
The `FireflyRuntime` instance is the backbone of a Squide application. Never instantiate directly - use `initializeFirefly()`.
23+
- **Runtime**: The `FireflyRuntime` instance is the backbone of a Squide application. Never instantiate directly — use `initializeFirefly()`, which wires up plugins, logging, and the module lifecycle.
24+
- **Modular Registration**: Modules register routes, navigation items, and MSW handlers via a registration function, assembled by the host at bootstrapping.
25+
- **Public vs Protected Routes**: Routes default to `protected` (rendered under `ProtectedRoutes`). Use `registerPublicRoute()` for public routes. Protected routes fetch both public and protected global data.
26+
- **Deferred Registrations**: Navigation items dependent on remote data or feature flags use two-phase registration — return a function from the registration to defer items to a second phase.
2527

26-
### Modular Registration
27-
Modules register routes, navigation items, and MSW handlers via a registration function. Each module contributes its own configuration, assembled by the host at bootstrapping.
28-
29-
### Public vs Protected Routes
30-
- Routes default to `protected` (rendered under `ProtectedRoutes` placeholder)
31-
- Use `registerPublicRoute()` for public routes (rendered under `PublicRoutes` placeholder)
32-
- Public routes only fetch public global data; protected routes fetch both public and protected data
33-
34-
### Deferred Registrations
35-
Navigation items dependent on remote data or feature flags use two-phase registration:
36-
1. First phase: Register static routes and navigation items
37-
2. Second phase: Return a function from registration to defer navigation items
38-
39-
## Quick Reference
28+
## Key Patterns
4029

4130
### Host Application Setup
4231

@@ -80,15 +69,15 @@ function BootstrappingRoute() {
8069
export function App() {
8170
return (
8271
<AppRouter>
83-
{({ rootRoute, registeredRoutes, routerProviderProps }) => (
72+
{({ rootRoute, registeredRoutes, routerProps, routerProviderProps }) => (
8473
<RouterProvider
8574
router={createBrowserRouter([{
8675
element: rootRoute,
8776
children: [{
8877
element: <BootstrappingRoute />,
8978
children: registeredRoutes
9079
}]
91-
}])}
80+
}], routerProps)}
9281
{...routerProviderProps}
9382
/>
9483
)}
@@ -108,6 +97,7 @@ export const registerHost: ModuleRegisterFunction<FireflyRuntime> = runtime => {
10897
children: [PublicRoutes, ProtectedRoutes]
10998
}, { hoist: true });
11099

100+
// HomePage and NotFoundPage are local page components
111101
runtime.registerRoute({ index: true, element: <HomePage /> });
112102
runtime.registerPublicRoute({ path: "*", element: <NotFoundPage /> });
113103
};
@@ -158,6 +148,7 @@ export function RootLayout() {
158148
// Protected data
159149
import { useProtectedDataQueries, useIsBootstrapping, AppRouter } from "@squide/firefly";
160150

151+
// ApiError and isApiError are app-specific; define them to match your API's error shape
161152
function BootstrappingRoute() {
162153
const [session] = useProtectedDataQueries([{
163154
queryKey: ["/api/session"],
@@ -208,11 +199,14 @@ export const register: ModuleRegisterFunction<FireflyRuntime, unknown, DeferredR
208199
```
209200

210201
```tsx
211-
// Execute deferred registrations in BootstrappingRoute
202+
// Execute deferred registrations in BootstrappingRoute.
203+
// Wrap in useMemo — without it, a new object reference each render re-triggers all deferred registrations.
212204
const data = useMemo(() => ({ userData }), [userData]);
213205
useDeferredRegistrations(data);
214206
```
215207

208+
**See also:** For error boundaries, testing patterns, and advanced navigation (multi-level, dynamic segments, active state), see `references/patterns.md`. For MSW setup, LaunchDarkly, Honeycomb, i18next, and Storybook integrations, see `references/integrations.md`. For plugin authoring and the full runtime API, see `references/runtime-api.md`.
209+
216210
## Reference Guide
217211

218212
For detailed API documentation beyond the patterns above, consult the reference files:
@@ -223,11 +217,11 @@ For detailed API documentation beyond the patterns above, consult the reference
223217
- **`references/patterns.md`** — Local module setup, error boundaries, MSW request handlers, and other common patterns
224218
- **`references/integrations.md`** — LaunchDarkly (plugin, utilities, testing clients), Honeycomb, i18next, and Storybook integration details
225219

226-
## Skill Maintenance Notes
220+
## Common Pitfalls
227221

228-
Before updating this skill, read [ODR-0008](../../agent-docs/odr/0008-skill-body-reference-split.md) which explains the body/reference split. The SKILL.md body must stay under ~250 lines. New API content goes in the appropriate `references/` file — only add to the body if it is a critical multi-file pattern needed in nearly every conversation.
222+
> **Skill maintainers:** Before updating this skill, read [ODR-0008](../../agent-docs/odr/0008-skill-body-reference-split.md). The body must stay under ~250 lines; new API content goes in the appropriate `references/` file.
229223
230-
When updating this skill from the official documentation, verify these common pitfalls:
224+
When working with Squide APIs, watch for these common mistakes:
231225

232226
1. **`useRenderedNavigationItems` function signatures**: Must always be `(item, key, index, level)` and `(elements, key, index, level)`. These do NOT accept custom context parameters. If external values are needed (route params, location, etc.), use closures or React hooks - never suggest adding parameters to these functions.
233227

agent-skills/workleap-squide/references/components.md

Lines changed: 43 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,14 @@
11
# Squide Components Reference
22

3+
## Table of Contents
4+
- [AppRouter](#approuter)
5+
- [FireflyProvider](#fireflyprovider)
6+
- [PublicRoutes](#publicroutes)
7+
- [ProtectedRoutes](#protectedroutes)
8+
- [I18nextNavigationItemLabel](#i18nextnavigationitemlabel-from-squidei18next)
9+
- [Storybook Components](#storybook-components-from-squidefirefly-rsbuild-storybook)
10+
- [Helper Functions](#helper-functions)
11+
312
## AppRouter
413

514
The main router component that sets up Squide's primitives with React Router.
@@ -16,9 +25,10 @@ The main router component that sets up Squide's primitives with React Router.
1625

1726
```ts
1827
{
19-
rootRoute: ReactElement; // Root route element (must wrap registeredRoutes)
20-
registeredRoutes: Route[]; // All registered routes
21-
routerProviderProps: object; // Props for RouterProvider
28+
rootRoute: ReactElement; // Root route element (must wrap registeredRoutes)
29+
registeredRoutes: Route[]; // All registered routes
30+
routerProps: DOMRouterOpts; // Options for createBrowserRouter (e.g., dataStrategy for MSW)
31+
routerProviderProps: object; // Props for RouterProvider
2232
}
2333
```
2434

@@ -32,12 +42,12 @@ import { RouterProvider } from "react-router/dom";
3242
export function App() {
3343
return (
3444
<AppRouter>
35-
{({ rootRoute, registeredRoutes, routerProviderProps }) => (
45+
{({ rootRoute, registeredRoutes, routerProps, routerProviderProps }) => (
3646
<RouterProvider
3747
router={createBrowserRouter([{
3848
element: rootRoute,
3949
children: registeredRoutes
40-
}])}
50+
}], routerProps)}
4151
{...routerProviderProps}
4252
/>
4353
)}
@@ -59,15 +69,15 @@ function BootstrappingRoute() {
5969
export function App() {
6070
return (
6171
<AppRouter>
62-
{({ rootRoute, registeredRoutes, routerProviderProps }) => (
72+
{({ rootRoute, registeredRoutes, routerProps, routerProviderProps }) => (
6373
<RouterProvider
6474
router={createBrowserRouter([{
6575
element: rootRoute,
6676
children: [{
6777
element: <BootstrappingRoute />,
6878
children: registeredRoutes
6979
}]
70-
}])}
80+
}], routerProps)}
7181
{...routerProviderProps}
7282
/>
7383
)}
@@ -96,15 +106,15 @@ function BootstrappingRoute() {
96106
export function App() {
97107
return (
98108
<AppRouter waitForProtectedData>
99-
{({ rootRoute, registeredRoutes, routerProviderProps }) => (
109+
{({ rootRoute, registeredRoutes, routerProps, routerProviderProps }) => (
100110
<RouterProvider
101111
router={createBrowserRouter([{
102112
element: rootRoute,
103113
children: [{
104114
element: <BootstrappingRoute />,
105115
children: registeredRoutes
106116
}]
107-
}])}
117+
}], routerProps)}
108118
{...routerProviderProps}
109119
/>
110120
)}
@@ -354,3 +364,27 @@ const runtime = await initializeFireflyForStorybook({
354364
useMsw: true // Default is true
355365
});
356366
```
367+
368+
### mergeDeferredRegistrations
369+
370+
Merge multiple deferred registration functions into a single function. Useful when a module's registration function is split across multiple files or needs to combine results from several setup steps.
371+
372+
```tsx
373+
import { mergeDeferredRegistrations } from "@squide/firefly";
374+
375+
export const register: ModuleRegisterFunction<FireflyRuntime> = runtime => {
376+
runtime.registerRoute({ path: "/page-a", element: <PageA /> });
377+
runtime.registerRoute({ path: "/page-b", element: <PageB /> });
378+
379+
// Merge multiple deferred registration functions into one
380+
return mergeDeferredRegistrations([
381+
registerPageANavigation(runtime),
382+
registerPageBNavigation(runtime)
383+
]);
384+
};
385+
```
386+
387+
**Parameters:**
388+
- `candidates`: Array of deferred registration functions (or `void`). Non-function entries are filtered out.
389+
390+
**Returns:** A single merged `DeferredRegistrationFunction`, or `undefined` if no valid functions were provided.

agent-skills/workleap-squide/references/hooks-api.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,16 @@
11
# Squide Hooks API Reference
22

3+
## Table of Contents
4+
- [Routing Hooks](#routing-hooks) — useNavigationItems, useRenderedNavigationItems, useRoutes, useIsBootstrapping, useIsRouteProtected, useRouteMatch
5+
- [Data Fetching Hooks](#data-fetching-hooks) — usePublicDataQueries, useProtectedDataQueries, usePublicDataHandler, useProtectedDataHandler
6+
- [Registration Hooks](#registration-hooks) — useDeferredRegistrations
7+
- [Messaging Hooks](#messaging-hooks) — useEventBusListener, useEventBusDispatcher
8+
- [Environment & Configuration Hooks](#environment--configuration-hooks) — useEnvironmentVariable, useEnvironmentVariables, useFeatureFlag, useFeatureFlags, useLaunchDarklyClient
9+
- [Logging Hooks](#logging-hooks) — useLogger
10+
- [Runtime Hooks](#runtime-hooks) — useRuntime, useRuntimeMode
11+
- [Plugin Hooks](#plugin-hooks) — usePlugin
12+
- [i18next Hooks](#i18next-hooks-from-squidei18next) — useI18nextInstance, useCurrentLanguage, useChangeLanguage
13+
314
## Routing Hooks
415

516
### useNavigationItems(options?)

agent-skills/workleap-squide/references/integrations.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,8 @@ export const requestHandlers: HttpHandler[] = [
118118
];
119119
```
120120

121+
> For more module registration patterns including higher-order registration and deferred registration with MSW, see `references/patterns.md`.
122+
121123
## LaunchDarkly
122124

123125
### Initialize Client
@@ -447,6 +449,8 @@ runtime.registerNavigationItem({
447449

448450
## Storybook
449451

452+
> For component API signatures (`FireflyDecorator`, `withFireflyDecorator`, `withFeatureFlagsOverrideDecorator`, `initializeFireflyForStorybook`), see `references/components.md`.
453+
450454
### Setup Decorator
451455

452456
```tsx

0 commit comments

Comments
 (0)