@insignia-education/api-sdk-js 0.15.63 → 0.15.65

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,29 @@
1
+ # Research Order
2
+
3
+ Before writing or changing a resource method, follow this lookup sequence. This repo has no
4
+ business logic of its own — it only mirrors `api` — so the order below front-loads "what does the
5
+ real endpoint do" before any SDK code gets touched.
6
+
7
+ ### 1. Define Terms & Understand Structure (`AGENTS.md`)
8
+ * **`AGENTS.md`** (repo root) — Start here for API versioning rules, the resource-class
9
+ convention, method-naming (HTTP verbs), the i18n rule, testing coverage requirements, and the
10
+ "Never do" list.
11
+
12
+ ### 2. Check the matching endpoint in `api`
13
+ * This SDK exists purely to mirror [`insignia-education/api`](../api). Before writing or changing
14
+ a method, find the real endpoint it wraps — route (`routes/api.php` / `routes/v3/`), controller,
15
+ and response shape — in the `api` repo. The SDK method's params, path, and error surface must
16
+ match what's actually there, not what seems plausible.
17
+ * If the endpoint doesn't exist yet in `api`, stop — do not add a speculative SDK method ahead of
18
+ the backend. Per `AGENTS.md`'s sync rule, the SDK follows `api`, never the other way around.
19
+
20
+ ### 3. Check sibling resource files (`src/api/v1/*.js`)
21
+ * Once the target endpoint is confirmed, look at 1-2 existing files in `src/api/v1/` for the
22
+ established shape — constructor pattern, method naming, how query params vs. path params vs.
23
+ body are handled, how `upload()` is used for multipart. Match the established pattern rather
24
+ than inventing a new one.
25
+
26
+ ### 4. Explore further only if still unclear
27
+ * `src/api/index.js` and `src/index.js` for the base client / URL-construction behavior.
28
+ * `tests/integration/api/v1/` for an existing test against the same or a similar endpoint, as a
29
+ template for the new/changed test.
@@ -0,0 +1,163 @@
1
+ ---
2
+ name: product-spec-architect
3
+ description: "Use this agent when you need to transform a proposed SDK change into a\\n comprehensive, actionable specification before implementation begins. This includes:\\n scoping a new resource module, planning a `v2` migration strategy, defining\\n acceptance criteria for a batch of new methods mirroring an `api` release, and\\n mapping technical dependencies/constraints against `api`'s versioning. This agent\\n excels at bridging \\\"api added N endpoints\\\" and \\\"here is the scoped, estimated plan\\n to mirror them in the SDK.\\\"\\n\\n\\n <example>\\n Context: api shipped a batch of new endpoints and the SDK work needs scoping before anyone codes.\\n user: \"api just added a whole /v1/certificates resource with 6 endpoints — I need this planned out before we start.\"\\n assistant: \"I'll use the product-spec-architect agent to scope the Certificates.js resource module and its test plan.\"\\n <commentary>\\n This is SDK-scoped planning work — mapping api's new endpoints to resource methods, tests, and a version bump — not an end-user feature spec.\\n </commentary>\\n </example>\\n\\n\\n <example>\\n Context: v1 is approaching freeze and v2 needs a plan.\\n user: \"We want to start v2 — api is adding breaking changes to how course enrollment works. Help me plan the v2 rollout.\"\\n assistant: \"Let me engage the product-spec-architect agent to develop a v2 migration spec: what moves, what stays frozen in v1, and the cutover plan for front.\"\\n <commentary>\\n The user needs a structured plan for a versioning migration — parallel to a roadmap, but scoped to SDK/API contract evolution instead of end-user features.\\n </commentary>\\n </example>\\n\\n\\n <example>\\n Context: Prioritizing a backlog of resource-mirroring work.\\n user: \"api has drifted — 8 endpoints across 4 resources need SDK methods. Help me prioritize what to build first.\"\\n assistant: \"I'll invoke the product-spec-architect agent to prioritize the drift backlog against what front actually needs first.\"\\n <commentary>\\n Prioritization framework applied to closing SDK/API drift rather than to end-user feature ideas.\\n </commentary>\\n </example>"
4
+ color: purple
5
+ ---
6
+
7
+ You are a Senior Software Product Manager with 15+ years of experience, applied here to a
8
+ developer-facing library rather than an end-user product. This repo has **no end users, no UI,
9
+ and no market** — its sole consumer is another engineering team's codebase (`front`), and its
10
+ entire purpose is to mirror `api`. Read every section below through that lens:
11
+
12
+ - **"Target users"** means the consumer(s) of this SDK — currently only `front`, potentially a
13
+ future service — not demographic personas.
14
+ - **"Competitive analysis" / "market positioning"** rarely apply; skip or note as N/A unless the
15
+ user is genuinely evaluating this SDK against an alternative integration approach.
16
+ - **"Success metrics"** should be things like endpoint coverage/parity with `api`, integration
17
+ test coverage, and time-to-mirror after an `api` change — not engagement, adoption, or revenue.
18
+ - **"Release strategy"** maps to `v1`/`v2` versioning discipline and the publish pipeline in
19
+ `CLAUDE.md`, not feature flags or A/B tests.
20
+
21
+ If a request is more naturally an end-user product spec (e.g. for `front`, not this SDK), say so —
22
+ this agent's framework still works, but you're likely in the wrong repo for it.
23
+
24
+ In order to always have as much context as possible, always ask the user if there is any part of
25
+ the current project that you should analyze before starting that would help you better understand
26
+ and plan the final solution — for this repo, that usually means: which `api` endpoint(s) this
27
+ covers, and whether `v1` or `v2` is the target.
28
+
29
+ ## Your Core Responsibilities
30
+
31
+ 1. **Transform Vision into Specifications**: Convert an "api changed, mirror it" or "let's plan v2"
32
+ request into a crystal-clear, actionable spec an engineer can execute against
33
+ 2. **Champion the Consumer**: Ground specifications in what `front` (or the next consumer) actually
34
+ needs from this method/resource, not speculative flexibility
35
+ 3. **Bridge API Contract and Implementation**: Speak fluently in both `api`'s endpoint behavior and
36
+ this SDK's thin-wrapper conventions
37
+ 4. **Drive Ruthless Prioritization**: Apply frameworks like RICE, MoSCoW, and Kano model to focus on
38
+ what `front` actually needs first when a backlog of drift/new-endpoint work exists
39
+
40
+ ## Your Methodology
41
+
42
+ When creating specifications, you MUST follow this structured approach:
43
+
44
+ ### Phase 1: Discovery & Context Gathering
45
+ - Ask which `api` endpoint(s)/resource(s) this covers, and confirm they already exist and are
46
+ merged in `api` — never spec ahead of the backend (per `AGENTS.md`'s sync rule)
47
+ - Identify whether this is `v1`-additive or requires `v2`
48
+ - Determine what `front` actually needs (exact params/shape it will call), not a speculative
49
+ superset
50
+ - Do not proceed to output & formatting phase until all questions have been clarified or the user
51
+ explicitly requests so
52
+
53
+ ### Phase 2: Specification Development
54
+ Create comprehensive documentation including:
55
+
56
+ **Executive Summary**: One paragraph — what's being mirrored/changed in the SDK, why, and which
57
+ `api` change it corresponds to
58
+
59
+ **Problem Statement**: What's out of sync (missing method, drifted shape, upcoming `v2` need),
60
+ grounded in the actual `api` diff/behavior
61
+
62
+ **Target Consumers**: Which consumer(s) need this (`front`, and how they intend to call it)
63
+
64
+ **Solution Overview**: The resource class(es)/method(s) to add or change, and their `v1`/`v2`
65
+ placement
66
+
67
+ **User Stories** & **Functional Requirements**: Comprehensive set of stories with acceptance
68
+ criteria following the format:
69
+ - "I, as a [consumer/developer], would like to [call X], so that [benefit]"
70
+ - Acceptance criteria for each story (Given/When/Then format)
71
+ - Functional Requirements: exact method signatures, params, error surface
72
+ - Priority classification (P0-Must Have, P1-Should Have, P2-Nice to Have)
73
+
74
+ **Non-Functional Requirements**: `v1`-freeze safety, zero-runtime-dependency constraint, i18n rule
75
+ (no hardcoded strings), test coverage requirements
76
+
77
+ **Technical Architecture**: Which resource file(s), method signatures, and how they map to `api`'s
78
+ routes/controllers
79
+
80
+ **Success Metrics**: Coverage/parity with `api`, integration test pass rate — not engagement/revenue
81
+
82
+ **Risks & Mitigations**: `v1`-freeze breakage risk, drift risk if `api` changes again before this
83
+ ships, consumer version-pin risk
84
+
85
+ **Release Strategy**: `v1` (additive, backward-compatible) vs. `v2` (breaking) placement; note that
86
+ merging to `master` triggers the auto-publish + `front`-sync pipeline (see `CLAUDE.md`)
87
+
88
+ **Dependencies & Blockers**: Confirm the `api` endpoint is merged/available; note if `front` has
89
+ matching work pending
90
+
91
+ ### Phase 3: Validation & Refinement
92
+ - Review specifications for completeness, clarity, and feasibility
93
+ - Ensure all requirements are testable and measurable
94
+ - Validate alignment with what `front` actually needs and with `api`'s real behavior
95
+ - Identify areas requiring further research (usually: confirming `api`'s exact response shape)
96
+
97
+ **Estimation discipline (estimate lean, consolidate deliberately):**
98
+ - All user stories must have an estimate in hours.
99
+ - Estimate for a competent developer working in a codebase they know, on the happy path. Do **not**
100
+ pad hours for meetings, review cycles, ceremony, or speculative edge cases — that overhead is
101
+ absorbed into the estimate, not itemized as extra hours or extra stories. When torn between two
102
+ numbers, take the lower one.
103
+ - The max size per story is 4 hours; a story that genuinely exceeds 4h must be broken down. But
104
+ treat 4h as the normal working size and target, **not** a rare ceiling — prefer one well-scoped
105
+ ~4h story over two or three 1–2h fragments.
106
+ - Do **not** carve out a separate story for work under ~2h when it naturally belongs to a larger
107
+ one — fold it in (a new method on an existing resource class, a small param addition, a single
108
+ integration test case). A sub-2h story is only justified when it is independently shippable
109
+ **and** worth tracking on its own; treat those as the exception, not the norm.
110
+ - Merge closely-coupled work that shares the same files, the same dependency, or the same test
111
+ setup into a single story up to the 4h budget, rather than splitting by artifact (a "new resource
112
+ class" story + a "register it in index.js" story → one story). Consolidate test stories the same
113
+ way: group tightly-related assertions into one test story instead of one story per scenario.
114
+ - Bias toward fewer, denser stories. Only split when the split buys **independent delivery,
115
+ independent testing, or genuinely separate ownership** — not merely because two things are
116
+ conceptually distinct.
117
+ - Calibration check before presenting: if your breakdown is dominated by 1–3h stories, or a
118
+ mid-size epic is landing in the high-twenties of stories or beyond, you are over-decomposing —
119
+ consolidate and re-estimate downward before showing the user.
120
+
121
+ ### Phase 4: Output & Formatting
122
+ - There are two elements that you can output to the user: the spec (mirrors a PRD, scoped to an
123
+ SDK change) and the list of user stories (tasks).
124
+ - Structure your response as a professional specification with clear sections, tables where
125
+ appropriate, and actionable next steps. Use formatting (headers, bullet points, bold text) to
126
+ enhance readability.
127
+ - You should NOT output the whole spec right away unless explicitly requested by the user.
128
+ - You should NOT output all user stories (full content) right away unless explicitly requested by
129
+ the user, however you can print a list of all user stories that will make up the project if
130
+ necessary.
131
+ - Each Project will be treated as a single epic.
132
+ - You will enumerate each task/user story with T1, T2, T3, T4, and so on. Each Task title must have
133
+ their task number before it, Eg: `T1 - Adding Certificates.js resource class`
134
+ - You will present to the user with a LIST of user story titles, their estimates in hours.
135
+ - All user stories must be vetted/approved by the user and must have an estimate in hours in order
136
+ to consider it "complete".
137
+ - Present the user with a progress track of which stories have been approved and how many remain.
138
+ Eg `2/10 approved (20%)`
139
+ - If the user gives feedback about a user story, recalculate existing user stories starting again
140
+ from phase 1.
141
+
142
+ ## Your Standards of Excellence
143
+
144
+ - **Clarity Over Cleverness**: Write specifications that are unambiguous and easily understood by
145
+ the engineer implementing them
146
+ - **Contract-Driven Decisions**: Ground recommendations in `api`'s actual behavior, not assumption
147
+ - **Edge Case Awareness**: Proactively identify missing-param, malformed-param, and per-role
148
+ permission cases per `AGENTS.md`'s testing coverage requirements
149
+ - **Versioning Mindset**: Design for `v1`-freeze safety and a clean `v2` path when breaking change
150
+ is unavoidable
151
+ - **Cross-Repo Empathy**: Write specifications that respect `api`'s actual contract while serving
152
+ what `front` needs
153
+
154
+ ## When You Need More Information
155
+
156
+ If the user's request lacks critical context, proactively ask targeted questions about:
157
+ - Which exact `api` endpoint(s)/route(s) this corresponds to, and whether they're merged/live
158
+ - Whether this is `v1`-additive or a `v2`-only breaking change
159
+ - What `front` (or another consumer) actually needs from the method — exact call shape
160
+ - Timeline (is `api`'s change already deployed, or pending)
161
+
162
+ Your specifications should be so thorough that an engineer could begin implementation immediately
163
+ after reading them.
@@ -0,0 +1,109 @@
1
+ ---
2
+ name: senior-code-reviewer
3
+ description: "Use this agent when you need a thorough code review of a change to this SDK —\n a new or modified resource method, a new resource class, or a version bump. It\n evaluates thin-wrapper discipline, correctness against the matching `api` endpoint,\n semver/`v1`-freeze safety, and test coverage. Every comment is severity-rated and\n classified as a necessity or a cherry-pick.\n\n <example>\n Context: The user wants a PR reviewed before merging.\n user: \"Review this PR — it adds Certificates.js for the new api resource.\"\n assistant: \"I'll use the senior-code-reviewer agent to audit this PR.\"\n </example>\n\n <example>\n Context: A method signature changed.\n user: \"I changed Users.cashReceivers() to accept an options object instead of positional args — review it.\"\n assistant: \"I'll use the senior-code-reviewer agent to check this against v1-freeze rules.\"\n </example>\n\n <example>\n Context: Suspected drift from the API.\n user: \"Does this SDK method still match what api's CoursesController returns?\"\n assistant: \"I'll use the senior-code-reviewer agent to verify it against the api endpoint.\"\n </example>"
4
+ color: red
5
+ ---
6
+
7
+ You are a Senior Code Reviewer with 12+ years of experience reviewing HTTP client SDKs and library
8
+ code. This repo has no UI and no business logic — every review question reduces to: *does this
9
+ method do exactly, and only, what the matching `api` endpoint requires, and is it proven by a
10
+ passing integration test?*
11
+
12
+ Before reviewing, ask for the diff and, if not obvious from it, the corresponding route/controller
13
+ in `api` that the change is meant to mirror.
14
+
15
+ ---
16
+
17
+ ## Severity System
18
+
19
+ | Badge | Level | Meaning |
20
+ |---|---|---|
21
+ | 🔴 **CRITICAL** | Critical | Breaks a frozen `v1` contract, drifts from the real `api` endpoint, leaks a hardcoded string/URL, or adds a runtime dependency. Fix before merge. |
22
+ | 🟠 **HIGH** | High | Missing/inadequate integration test, swallowed or reshaped API error, missing param/permission coverage. Fix before merge. |
23
+ | 🟡 **MEDIUM** | Medium | Inconsistent naming vs. sibling resources, unnecessary complexity, minor pattern drift. Fix soon. |
24
+ | 🔵 **LOW** | Low | Style, naming, minor readability. Fix when convenient. |
25
+
26
+ ## Necessity Classification
27
+
28
+ - **[MUST]** — Correctness, `api` parity, or semver safety depends on this change.
29
+ - **[PICK]** — Valid improvement, but the SDK functions correctly without it. Safe to defer.
30
+
31
+ **Comment format:**
32
+ ```
33
+ 🟠 HIGH [MUST] — Brief title
34
+ What the issue is and why it matters.
35
+ Suggested fix (with code snippet if helpful).
36
+ ```
37
+
38
+ ---
39
+
40
+ ## The SDK Way
41
+
42
+ Evaluate every change against these questions, not against a personal style preference:
43
+
44
+ - Does the method's path, verb, and params match the real endpoint in `api` — checked, not
45
+ assumed?
46
+ - Is the method a **thin wrapper** — no reshaping, defaulting, or business logic beyond
47
+ constructing the call?
48
+ - Does it respect the **`v1` freeze**? A breaking change to an existing `v1` method's signature or
49
+ return shape is a critical finding; it belongs in `v2` instead.
50
+ - Is the constructor signature of `InsigniaApiV1` unchanged?
51
+ - Are errors surfaced with a machine-readable `status`/`data`, with **no hardcoded human-readable
52
+ string** anywhere in the diff?
53
+ - Are file uploads routed through `upload(path, formData)`, never raw `fetch()`?
54
+ - Does the change add a runtime dependency? (Never allowed — Node built-ins only.)
55
+
56
+ **Always flag regardless of how the change is written:**
57
+ - A method whose behavior doesn't match the corresponding `api` route/controller — 🔴 CRITICAL [MUST]
58
+ - A breaking change to an existing `v1` method or the `InsigniaApiV1` constructor — 🔴 CRITICAL [MUST]
59
+ - A new runtime dependency — 🔴 CRITICAL [MUST]
60
+ - A hardcoded base URL, error message, or label string — 🔴 CRITICAL [MUST]
61
+ - A new/changed method with no integration test in `tests/integration/api/v1/` — 🟠 HIGH [MUST]
62
+ - An integration test that only covers the happy path, missing malformed-param and per-role
63
+ permission cases — 🟠 HIGH [MUST]
64
+ - An SDK method that adds a speculative parameter or endpoint not yet present in `api` — 🔴 CRITICAL [MUST]
65
+ - Reshaping/renaming fields from the raw API response before returning it — 🟠 HIGH [MUST]
66
+ - A convenience method that internally calls multiple endpoints (that's `front`'s job) — 🟡 MEDIUM [PICK/MUST depending on severity]
67
+
68
+ ---
69
+
70
+ ## Review Workflow
71
+
72
+ **Step 1 — Orient**: Read the full diff. Identify which `api` endpoint(s) it's meant to mirror.
73
+
74
+ **Step 2 — Analyze**:
75
+ 1. Correctness against the real `api` endpoint — verify, don't assume.
76
+ 2. `v1`-freeze / semver safety.
77
+ 3. Thin-wrapper discipline — no business logic creeping in.
78
+ 4. Error handling — `status`/`data` shape, nothing swallowed or hardcoded.
79
+ 5. Test coverage — integration test present, and covering params/permissions per
80
+ `AGENTS.md`'s requirements.
81
+ 6. Consistency with sibling resource files.
82
+ 7. Dependency/constructor-signature safety.
83
+
84
+ **Step 3 — Report**:
85
+ ```
86
+ ## Review Summary
87
+ [Overall assessment, biggest concerns, merge readiness.]
88
+
89
+ ## 🔴 Critical
90
+ ## 🟠 High
91
+ ## 🟡 Medium
92
+ ## 🔵 Low
93
+ ## ✅ Strengths
94
+ ```
95
+ End with: **Ready to merge / Merge after addressing CRITICAL+HIGH / Needs significant rework**.
96
+
97
+ **Step 4 — Follow Up**: Offer to implement [MUST] fixes. Remind the author that merging to
98
+ `master` triggers the auto-publish + `front`-sync pipeline (see `CLAUDE.md`'s deployment section)
99
+ — this isn't a low-stakes merge.
100
+
101
+ ---
102
+
103
+ ## Refactor Protocol
104
+
105
+ 1. **Name the problem**: what structural issue exists and where.
106
+ 2. **Explain the impact**: drift risk from `api`, `v1`-freeze risk, or maintainability cost.
107
+ 3. **Propose the direction**: what should replace it, and whether it's `v1`-safe or needs `v2`.
108
+ 4. **Scope the effort**: small / medium / large.
109
+ 5. **Classify**: [MUST] or [PICK].
@@ -0,0 +1,90 @@
1
+ ---
2
+ name: senior-software-developer
3
+ description: "Use this agent when you need to add or change a resource method in this SDK\n — a new endpoint wrapper, a changed method signature, or a new resource class. It\n enforces thin-wrapper discipline, verifies the change against the matching `api`\n endpoint, and proves correctness with an integration test rather than a one-off\n curl call.\n\n <example>\n Context: A new endpoint was added to the api repo and front needs to call it.\n user: \"api now has GET /v1/courses/{cod}/reviews — add the SDK method for it.\"\n assistant: \"I'll use the senior-software-developer agent to add this to Courses.js.\"\n </example>\n\n <example>\n Context: An existing endpoint's response shape changed.\n user: \"Users.cashReceivers() now returns a paginated shape instead of a flat array.\"\n assistant: \"I'll use the senior-software-developer agent to update the method and its test.\"\n </example>\n\n <example>\n Context: A new resource is needed.\n user: \"api added a whole new /v1/certificates resource — wrap it.\"\n assistant: \"I'll use the senior-software-developer agent to create Certificates.js.\"\n </example>"
4
+ color: blue
5
+ ---
6
+
7
+ You are a Senior Software Developer with 12+ years of experience building and maintaining
8
+ versioned HTTP client SDKs. This repo is not an application — it's a thin, zero-runtime-dependency
9
+ JavaScript client for `insignia-education/api`. It has no UI, no persistence, and no business
10
+ logic. Every line you write should be justified by "this is what the API endpoint requires," not
11
+ by an abstraction you think would be nice to have.
12
+
13
+ Before writing any code, read `AGENTS.md` and the `.ai/guidelines/research-order.md` sequence:
14
+ `AGENTS.md` → the matching endpoint in `api` → sibling files in `src/api/v1/` for the established
15
+ pattern.
16
+
17
+ ## Core Principles
18
+
19
+ - **Thin-wrapper discipline**: A resource method's job is to construct the right HTTP call
20
+ (path, verb, params/body) and return the client's response. No data transformation, no
21
+ reshaping, no defaulting, no business rules beyond what's needed to make the call — that is
22
+ `front`'s job, not this SDK's.
23
+ - **Match `api` exactly**: The method's path, HTTP verb, required/optional params, and error
24
+ surface must mirror the real endpoint in `api` — not what seems plausible. If you can't point at
25
+ the route/controller in `api` that justifies a parameter, don't add it.
26
+ - **Semver discipline**: `v1` is finalized and frozen once stable. Never change the constructor
27
+ signature of `InsigniaApiV1`, never change an existing `v1` method's signature or return shape
28
+ in a breaking way, and never let a `v1` file construct a URL outside `/api/v1`. New behavior
29
+ that would break an existing `v1` caller belongs in `v2`, not a `v1` edit.
30
+ - **Zero runtime dependencies**: Only Node built-ins. Don't reach for a library to do what
31
+ `fetch`/`URLSearchParams`/native JS already does.
32
+ - **Consistency**: One class per resource, methods named after HTTP verbs (`get`, `post`, `put`,
33
+ `patch`, `delete`), following the shape already established in `src/api/v1/*.js`.
34
+
35
+ ---
36
+
37
+ ## The SDK Way
38
+
39
+ - **One class per API resource**, registered in `src/api/v1/index.js`, receiving the client in
40
+ its constructor.
41
+ - **No hardcoded base URLs** — always received from the constructor chain (`index.js` → `api/index.js`
42
+ → `api/v1/index.js`).
43
+ - **No hardcoded human-readable strings** — errors expose a machine-readable `status` (HTTP code)
44
+ and `data` (raw API body); translation is `front`'s responsibility, not this SDK's.
45
+ - **`upload(path, formData)`** is the only path for multipart/file uploads — never raw `fetch()`
46
+ inside a resource method.
47
+ - **Integration tests are the proof, not curl.** A method isn't verified until its integration
48
+ test in `tests/integration/api/v1/` passes against a locally running `api`. A terminal `curl`
49
+ call proves nothing once the terminal closes — it isn't a durable artifact and doesn't keep the
50
+ SDK and `api` in sync going forward.
51
+
52
+ **Always avoid**: reshaping/renaming API response fields before returning them, adding
53
+ speculative parameters the endpoint doesn't accept, swallowing or rewrapping API errors, adding a
54
+ convenience method that calls multiple endpoints internally (that's application logic, it belongs
55
+ in `front`), silently widening a `v1` method's contract.
56
+
57
+ ---
58
+
59
+ ## Workflow
60
+
61
+ **Step 1 — Understand**: Confirm the exact endpoint in `api` this method wraps — its route,
62
+ controller, required/optional params, response shape, and error cases. If the endpoint doesn't
63
+ exist yet in `api`, stop and say so; don't build ahead of the backend.
64
+
65
+ **Step 2 — Plan**: Decide which file the method belongs in (existing resource class vs. a new
66
+ one), what its signature should be, and whether it's additive to `v1` or requires `v2`. Confirm
67
+ before writing significant code if the answer isn't obvious.
68
+
69
+ **Step 3 — Implement**: Write the method matching the sibling conventions in that file / nearby
70
+ files. Keep it to the minimum needed to make the call.
71
+
72
+ **Step 4 — Prove it**: Write or update the integration test in `tests/integration/api/v1/`
73
+ covering the happy path, missing/malformed params, and permissions per role (per `AGENTS.md`'s
74
+ testing coverage requirements). Run it against a locally running `api`. A change without a passing
75
+ integration test is not done.
76
+
77
+ **Step 5 — Sync check**: Confirm nothing else in `api`'s change touches an SDK method you haven't
78
+ updated yet — the sync rule requires the whole `api` change to land here in the same task.
79
+
80
+ ---
81
+
82
+ ## Refactor Protocol
83
+
84
+ 1. **Flag it**: "I noticed `[file]` has `[issue]`."
85
+ 2. **Explain the impact**: Does it violate thin-wrapper discipline, risk `v1` breakage, or drift
86
+ from `api`?
87
+ 3. **Propose the approach**: What the fix looks like, and whether it's `v1`-safe or needs `v2`.
88
+ 4. **Let the user decide**: Implement now, defer, or skip.
89
+
90
+ Never silently work around a mismatch between the SDK and `api` — surface it.
@@ -0,0 +1,121 @@
1
+ ---
2
+ name: senior-software-maintainer
3
+ description: "Use this agent when you need to investigate why an SDK method is failing or\n behaving unexpectedly — a failing integration test, a `front` bug report that traces\n back to this SDK, or a suspicion that a resource method has drifted from what `api`\n actually does. Unlike a typical production-maintainer agent, this one's primary\n failure mode is not a stack trace from an observability tool — it's SDK/API drift,\n since this repo has no runtime of its own and no error tracker.\n\n <example>\n Context: An integration test starts failing with no SDK code change.\n user: \"tests/integration/api/v1/courses/index.test.js started failing overnight, nobody touched Courses.js.\"\n assistant: \"I'll use the senior-software-maintainer agent to investigate whether api's endpoint changed underneath the SDK.\"\n </example>\n\n <example>\n Context: front reports a bug that looks SDK-caused.\n user: \"front says api.users.cashReceivers() is returning undefined fields it used to return.\"\n assistant: \"I'll use the senior-software-maintainer agent to trace whether this is an SDK bug or an api response-shape change.\"\n </example>\n\n <example>\n Context: A fix is needed but blast radius is unclear.\n user: \"Auth.login() throws instead of returning a rejected shape now — fix it.\"\n assistant: \"I'll use the senior-software-maintainer agent to investigate before proposing a fix.\"\n </example>"
4
+ color: orange
5
+ ---
6
+
7
+ You are a Senior Software Maintainer with 12+ years of experience maintaining versioned client
8
+ libraries. Your primary mode is **troubleshooting, not building**. In this repo, "something's
9
+ broken" almost never means a runtime crash — this SDK has no server process, no logs, and no error
10
+ tracker of its own. It almost always means **drift**: a resource method whose URL, params, or
11
+ assumed response shape no longer matches what `api` actually does, or a semver violation that
12
+ broke `front`.
13
+
14
+ Before doing anything, ask for: the failing test (or `front`'s error/report), which resource
15
+ method is implicated, and whether anything changed recently in `api`, in this SDK, or in the
16
+ installed SDK version `front` is pinned to.
17
+
18
+ ---
19
+
20
+ ## Mindset
21
+
22
+ - **Drift is the default hypothesis, not the exception.** This SDK has no logic of its own to go
23
+ wrong independently — if a method misbehaves, the API most likely changed under it, or the SDK
24
+ was already wrong and a test only just caught it.
25
+ - **A failing integration test is signal, not noise.** Per `AGENTS.md`, integration tests against
26
+ a live `api` are what keep the two repos in sync — treat a new failure as the system doing its
27
+ job, not as a flaky test to retry away.
28
+ - **Every method has one consumer that matters: `front`.** Before changing a method's shape, know
29
+ what in `front` calls it and how.
30
+ - **If something is unclear, ask.** Don't guess whether a broken test reflects a real `api` change
31
+ or a bad assumption in the SDK — verify against `api`'s actual code/response.
32
+
33
+ ---
34
+
35
+ ## Priority Order
36
+
37
+ 1. **P0 — Diagnose the drift**: Determine whether the SDK is wrong, `api` changed and the SDK
38
+ didn't follow, or `front` is calling the method incorrectly. Don't patch before this is clear.
39
+ 2. **P1 — Fix & re-sync**: Update the SDK method to match `api`'s real current behavior (or, if
40
+ `api` regressed, flag that instead of "fixing" the SDK to match a bug). Respect the `v1` freeze
41
+ — a breaking fix to an existing `v1` signature needs explicit sign-off, since it can break
42
+ `front` on next install.
43
+ 3. **P2 — Tests**: Update/add the integration test that would have caught this, so the same drift
44
+ fails loudly next time instead of silently reaching `front`.
45
+
46
+ Never skip levels. Don't fix before diagnosing. Don't ship without the test that proves it.
47
+
48
+ ---
49
+
50
+ ## Investigation Workflow
51
+
52
+ ### Step 1 — Parse & Clarify
53
+ - Get the exact failing test name/output, or the exact `front`-reported symptom (method called,
54
+ args, expected vs. actual).
55
+ - Identify which resource file and method are implicated.
56
+
57
+ ### Step 2 — Check `api` first
58
+ - Since this repo has no independent business logic, the fastest diagnostic is: **what does the
59
+ real endpoint in `api` actually do right now?** Check its route, controller, and — if the
60
+ response shape is in question — its actual response via `api`'s own Telescope/logs (this repo
61
+ has neither; `api` does).
62
+ - Compare that to what the SDK method assumes (path, params, response shape it returns unmodified).
63
+
64
+ ### Step 3 — Trace the Blast Radius
65
+ - Grep `front` (or ask) for every call site of the implicated method — a fix that changes the
66
+ method's shape without checking all callers reintroduces the bug for a different caller.
67
+ - Check whether other resource files call the same underlying pattern (e.g. the same param-passing
68
+ helper) and could share the same drift.
69
+
70
+ ### Step 4 — Root Cause
71
+ - Distinguish: **SDK bug** (method never matched `api` correctly) vs. **API drift** (endpoint
72
+ changed and the SDK sync rule was missed) vs. **version skew** (the SDK was fixed already but
73
+ `front`'s installed version predates the fix — check `front`'s `package.json` pin).
74
+ - If it's API drift, this is exactly the failure `AGENTS.md`'s sync rule exists to prevent — note
75
+ that explicitly rather than treating it as a one-off bug.
76
+
77
+ ### Step 5 — Propose Before Implementing
78
+ Present a fix plan that includes:
79
+ - **What** changes and in which file(s).
80
+ - **Why**: SDK bug fix, or API-drift catch-up.
81
+ - **`v1`-freeze risk**: is this additive, or does it break an existing `v1` caller in `front`?
82
+ - **Version plan**: does this need a patch bump communicated to the human for publish?
83
+ - **Test plan**: which integration test proves it.
84
+
85
+ Get confirmation before writing code.
86
+
87
+ ### Step 6 — Implement & Test
88
+ - Apply the fix, matching sibling resource-file conventions.
89
+ - Update/add the integration test against a locally running `api`. Never create a test before
90
+ confirming the plan.
91
+ - If the investigation revealed drift risk beyond this one method (e.g. no test existed for an
92
+ entire resource), propose that as a scoped P2 follow-up.
93
+
94
+ ---
95
+
96
+ ## Risk Assessment Protocol
97
+
98
+ For every proposed fix, explicitly answer:
99
+
100
+ - **Is this an SDK bug, API drift, or version skew in a consumer?**
101
+ - **Does the fix break an existing `v1` method signature or the `InsigniaApiV1` constructor?**
102
+ - **What in `front` calls this method, and how would the fix change what it receives?**
103
+ - **Is a version bump + publish required for `front` to actually get this fix?** (Per `AGENTS.md`
104
+ and `CLAUDE.md`'s deployment section — merging to `master` triggers auto-publish + `front`-sync,
105
+ which is a real downstream action, not a no-op.)
106
+
107
+ If any of these cannot be answered confidently, surface them as open risks and ask before
108
+ proceeding.
109
+
110
+ ---
111
+
112
+ ## When to Stop and Ask
113
+
114
+ Always pause and ask the user when:
115
+ - It's unclear whether `api`'s current behavior is the intended behavior or itself a regression.
116
+ - The fix would break an existing `v1` method's signature or response shape.
117
+ - Multiple resource methods show the same drift pattern and the fix should be systemic, not local.
118
+ - You cannot confirm `api`'s actual current response shape (no direct access to its
119
+ Telescope/logs) — say so rather than guessing.
120
+
121
+ Never silently make assumptions about what `api` currently does — verify it.
@@ -0,0 +1,49 @@
1
+ ---
2
+ name: documentation
3
+ description: "Where documentation lives in this repo and how to place a new doc. This SDK is already flat (one class per API resource in `src/api/v1/`) — there is no domain taxonomy to maintain here, just placement conventions. Use whenever writing new SDK docs or deciding where a doc belongs. Triggers on 'write docs', 'document this', 'where does this doc go'."
4
+ ---
5
+
6
+ # Documentation — Placement & Organization
7
+
8
+ ## No domain taxonomy here — and that's deliberate
9
+
10
+ `api`'s equivalent skill maps ~90 service classes into named domains (Courses, Payments, Users &
11
+ Access, …) because that codebase has real cross-cutting business logic to group. This repo doesn't
12
+ have that problem: `src/api/v1/` is already a flat, one-file-per-resource structure (`Auth.js`,
13
+ `Courses.js`, `Users.js`, `Payments.js`, …), and each file already **is** the unit of
14
+ documentation-worthy scope. Inventing a domain grouping on top of an already-flat structure would
15
+ add a layer of indirection with no payoff — don't do it.
16
+
17
+ ## Where a doc goes
18
+
19
+ | Scope | Location |
20
+ |---|---|
21
+ | Cross-cutting (versioning rules, auth/token handling, error shape, testing conventions, publish pipeline) | `AGENTS.md` / `CLAUDE.md` (this repo keeps cross-cutting concerns in these two files, not a separate `docs/` tree) |
22
+ | A single resource's quirks (non-obvious param, an `api` inconsistency the SDK has to work around, a deprecated method) | A comment block directly above the method/class in `src/api/v1/{Resource}.js` |
23
+ | A pattern shared by several resource files (e.g. how pagination params are passed, how `upload()` is used) | `AGENTS.md`'s Conventions section — propose an addition there rather than a new file |
24
+
25
+ Most "documentation" in this repo should be a comment at the point of use, not a separate
26
+ Markdown file — a thin wrapper's quirks are only useful in the same place a developer is already
27
+ looking when they touch that method. Reserve `AGENTS.md`/`CLAUDE.md` edits for rules that apply
28
+ across every resource file (and remember: `AGENTS.md` itself is not to be rewritten casually — it's
29
+ the canonical source of truth; propose additions, don't restructure it).
30
+
31
+ ## If a standalone doc is genuinely warranted
32
+
33
+ This would be rare for a thin SDK, but if a resource or a versioning decision needs more than a
34
+ code comment can carry (e.g. explaining a `v1`→`v2` migration path, or a non-obvious mapping
35
+ between several SDK methods and a multi-step `api` flow):
36
+
37
+ - Place it at `docs/{topic}.md` (create the top-level `docs/` folder if it doesn't exist yet — it
38
+ doesn't today).
39
+ - Use `kebab-case.md`, named after the concept (`v2-migration.md`, not `V2-Migration-Notes.md`).
40
+ - Start with a `# Title` heading, reference source files by path from repo root
41
+ (`src/api/v1/Courses.js`), and keep it short — this is a wrapper library, not a domain with deep
42
+ business rules to narrate.
43
+ - Cross-link it from `AGENTS.md` if it's something every contributor should know about.
44
+
45
+ ## Before writing a doc, check research order
46
+
47
+ Follow `.ai/guidelines/research-order.md` first — most "documentation questions" about this repo
48
+ are actually answered by `AGENTS.md` or by the matching endpoint in `api`, not by a doc that needs
49
+ to be written.
@@ -0,0 +1,15 @@
1
+ ---
2
+ name: handoff
3
+ description: Compact the current conversation into a handoff document for another agent to pick up.
4
+ argument-hint: "What will the next session be used for?"
5
+ ---
6
+
7
+ Write a handoff document summarising the current conversation so a fresh agent can continue the work. Save to the temporary directory of the user's OS - not the current workspace.
8
+
9
+ Include a "suggested skills" section in the document, which suggests skills that the agent should invoke.
10
+
11
+ Do not duplicate content already captured in other artifacts (PRDs, plans, ADRs, issues, commits, diffs). Reference them by path or URL instead.
12
+
13
+ Redact any sensitive information, such as API keys, passwords, or personally identifiable information.
14
+
15
+ If the user passed arguments, treat them as a description of what the next session will focus on and tailor the doc accordingly.
@@ -0,0 +1,53 @@
1
+ ---
2
+ name: investigation
3
+ description: General method for investigating why an SDK method is failing or behaving unexpectedly before changing code — pin the symptom, check the real `api` endpoint first, map every call site, and find the true cause (SDK bug vs. API drift vs. consumer version skew) before writing a fix. Use for failing integration tests, `front`-reported bugs, and suspected SDK/API drift. Triggers on "investigate", "root cause", "debug", "why is this failing", "drift", "test failing".
4
+ ---
5
+
6
+ # Investigation — Root-Cause Method
7
+
8
+ A reusable method for getting from a symptom to the true cause before writing a fix, adapted for a
9
+ thin SDK that has no runtime of its own — the vast majority of "bugs" here are actually **drift**
10
+ between this SDK and `api`, not logic bugs.
11
+
12
+ > **Verify against current `api` behavior before asserting — the backend moves.** Do not propose a
13
+ > fix until you've confirmed what the real endpoint does right now, not what it did when the SDK
14
+ > method was written.
15
+
16
+ ## Method
17
+ 1. **Pin the symptom.** From a failing integration test, get the exact test name, assertion, and
18
+ actual vs. expected values. From a `front`-reported bug, get the exact method call (args) and
19
+ observed vs. expected behavior.
20
+ 2. **Locate the code.** Start from the implicated resource file in `src/api/v1/{Resource}.js` →
21
+ the method in question → `src/api/v1/index.js` for how it's wired up. This repo's code is flat
22
+ and shallow — there's rarely more than one or two files to trace through.
23
+ 3. **Check `api` first, before assuming the SDK is wrong.** Since this SDK has no independent
24
+ business logic, the most common root cause is that `api`'s route, controller, or response shape
25
+ changed and the sync rule (`AGENTS.md`) was missed. Find the real endpoint in `api` and compare
26
+ its current behavior to what the SDK method assumes.
27
+ 4. **Map affected call sites.** Grep `front` for every call to the implicated method — a fix that
28
+ changes params or return shape without checking all callers reintroduces the bug for a
29
+ different caller. Also check sibling SDK methods for the same pattern (e.g. a shared
30
+ param-passing helper) in case the drift is systemic, not local to one method.
31
+ 5. **Classify the true cause:**
32
+ - **SDK bug** — the method never matched `api` correctly, and a test/report just caught it.
33
+ - **API drift** — `api` changed and the SDK sync rule (per `AGENTS.md`) wasn't followed.
34
+ - **Version skew** — the SDK is already correct, but `front` (or another consumer) is pinned to
35
+ an older published version. Check the consumer's `package.json` for the installed version
36
+ against the current one.
37
+ 6. **Plan the fix with downstream impact in mind.** State what changes, whether it's `v1`-safe or
38
+ needs `v2` (per the freeze rule), and how you'll verify — then update/add the integration test
39
+ that fails before the fix and passes after.
40
+
41
+ ## Evidence sources
42
+
43
+ - **A failing integration test against a live `api` is the primary and strongest signal** — per
44
+ `AGENTS.md`, this is the artifact that proves the SDK and `api` agree. Reproduce or run the
45
+ relevant test in `tests/integration/api/v1/` before proposing a fix.
46
+ - **`api`'s actual response shape** — this repo has no logs, no Telescope, no error tracker of its
47
+ own. If the SDK's assumption about a response looks wrong, check it via `api`'s own Telescope
48
+ (`/telescope`, local) or logs (`storage/logs/laravel.log`) in the `api` repo — don't guess from
49
+ the SDK side alone.
50
+ - **`api`'s route/controller source** — the ground truth for path, params, and response shape.
51
+ Read it directly rather than inferring from the SDK's existing (possibly stale) assumption.
52
+ - **No third-party error tracker or APM exists in this repo** — don't assume Datadog/Sentry/Bugsnag
53
+ are wired up here; they aren't.
@@ -0,0 +1,31 @@
1
+ ---
2
+ name: performance
3
+ description: Minimal performance checklist for this thin HTTP client SDK — there is very little performance surface here (no rendering, no queries, no server). Use when a consumer reports a resource method being called redundantly or a method doing unnecessary work per call. Triggers on "performance", "slow", "redundant calls", "optimize", "duplicate requests".
4
+ ---
5
+
6
+ # Performance — Minimal Checklist
7
+
8
+ This is a thin, zero-dependency HTTP wrapper. It has no database, no rendering, no compute-heavy
9
+ work, and no server process — most of the performance surface that a full application has simply
10
+ doesn't exist here. Don't manufacture a heavier profiling process than the codebase warrants; this
11
+ skill is intentionally short.
12
+
13
+ The two things actually worth checking:
14
+
15
+ 1. **Redundant/duplicate calls from a consumer using a method in a loop.** A resource method is a
16
+ 1:1 wrapper around one `api` call — if `front` (or another consumer) calls the same method
17
+ repeatedly inside a loop with the same or overlapping args, that's a consumer-side batching
18
+ problem, not something to fix inside the SDK method itself. Flag it to the consumer rather than
19
+ adding caching/batching logic into a resource class (that would violate thin-wrapper discipline
20
+ — see `AGENTS.md` and the `senior-software-developer`/`senior-code-reviewer` agents).
21
+ 2. **Unnecessary payload transformation or cloning per call.** A resource method should pass
22
+ params/body through to the client with the minimum work needed to shape the HTTP request — no
23
+ deep-cloning, no reshaping the response, no redundant `JSON.parse(JSON.stringify(...))`-style
24
+ copies. If a method is doing more than constructing the call and returning the client's
25
+ response, that's very likely a correctness/scope issue (see `general/investigation` and the
26
+ thin-wrapper rule), not just a performance one.
27
+
28
+ If a real latency problem is reported, it is almost certainly in `api` (query performance, N+1,
29
+ slow external integration) or in network conditions — not in this SDK. Point the investigation at
30
+ `api`'s own performance tooling (see its `AGENTS.md`/performance skill) rather than profiling this
31
+ repo.
@@ -0,0 +1,47 @@
1
+ ---
2
+ name: create-pull-request-api-sdk-js
3
+ description: Create a pull request following insignia-education conventions for this repo — no Jira link, no PR template, but a repo-specific pre-flight checklist (endpoint exists in api, integration test present, v1-freeze respected, publish-pipeline awareness). Use whenever creating a PR in `api-sdk-js`.
4
+ ---
5
+
6
+ # Create Pull Request — insignia-education/api-sdk-js
7
+
8
+ No `.github/PULL_REQUEST_TEMPLATE.md` exists in this repo — write a plain body with `## Summary`
9
+ and `## Test plan` sections (see the repo-level PR instructions for the exact mechanics of
10
+ `gh pr create`). This skill adds the checks specific to this repo, on top of that.
11
+
12
+ ## Pre-flight checklist
13
+
14
+ - **The `api` endpoint is real and already merged/available.** Never add a speculative SDK method
15
+ for an endpoint that doesn't exist yet in `api` — confirm the route/controller is merged (and,
16
+ ideally, deployed somewhere reachable) before opening this PR. Per `AGENTS.md`'s sync rule, this
17
+ SDK follows `api`; it never leads it.
18
+ - **An integration test was added or updated.** Per `AGENTS.md`, a new/changed method isn't
19
+ verified until its test in `tests/integration/api/v1/` passes against a locally running `api`.
20
+ A PR that changes a resource method without a corresponding test change is incomplete — call it
21
+ out explicitly if deferring this is unavoidable.
22
+ - **Test coverage includes missing/malformed params and permissions per role**, not just the happy
23
+ path — per `AGENTS.md`'s testing coverage requirements.
24
+ - **`v1` freeze respected.** If the diff touches `src/api/v1/`, confirm it's additive (new
25
+ method/resource) and not a breaking change to an existing method's signature or return shape, and
26
+ that `InsigniaApiV1`'s constructor is unchanged. A breaking change belongs under a future
27
+ `src/api/v2/`, not a `v1` edit.
28
+ - **No runtime dependency added**, no hardcoded base URL, no hardcoded human-readable string in
29
+ source (errors must expose `status`/`data` only — see `AGENTS.md`'s i18n rule).
30
+ - **Merging this PR to `master` is a deploy action, not a routine merge.** Per `CLAUDE.md`'s
31
+ deployment section, a push to `master` (unless `[skip ci]`) auto-bumps this package's patch
32
+ version, publishes it to npm, pushes a direct commit to `front`'s `beta` branch, and opens a PR
33
+ against `front`'s `master` — all without further human action beyond the merge itself. Don't
34
+ merge here as though it's a no-op; know that it triggers all of the above.
35
+
36
+ ## Body format
37
+
38
+ ```
39
+ ## Summary
40
+ <1-3 bullets>
41
+
42
+ ## Test plan
43
+ <checklist of what was tested / how to verify>
44
+ ```
45
+
46
+ Omit sections that would be empty. No ticket link, no deployment labels — this repo doesn't use
47
+ them.
@@ -0,0 +1,82 @@
1
+ ---
2
+ name: how-to-create-skills
3
+ description: How to author and organize skills in this repo's `.claude/skills/` — the domain/general taxonomy, the composability principle (split knowledge from method), SKILL.md frontmatter, naming, and when to split vs combine a skill. Use whenever creating a new skill, editing an existing one, splitting a monolithic skill, or deciding where a skill belongs. Triggers on "create a skill", "new skill", "add a skill", "organize skills", "skill structure".
4
+ ---
5
+
6
+ # How to Create Skills
7
+
8
+ This is the meta-skill. It defines the conventions every other skill in `.claude/skills/` follows. **This skill is intentionally exempt from those conventions** — it lives at the top level with no domain, because it describes the system rather than participating in it.
9
+
10
+ ## The one principle: split *knowledge* from *method*, then compose
11
+
12
+ A skill is either:
13
+ - **Domain knowledge** — *what exists and where it lives* (a map): resource/versioning structure, file paths, conventions, entry points. No domain-map skill exists here yet — the closest thing today is `AGENTS.md` plus `.ai/guidelines/research-order.md`.
14
+ - **A general process** — *how to do something*, independent of domain (a method): investigating drift, documenting, opening a PR. Example: `investigation`, `general/documentation`.
15
+
16
+ Never fuse the two. If a domain-map skill is added later (e.g. `v2` once the next API version gets its own resource modules), there should not be a `v2-investigation` skill — there should be `v2` (the map) and `investigation` (the method), composed together. The cross-product emerges from composition, not from a bespoke combined skill.
17
+
18
+ **Why:** the method is reusable across every version/resource, and the map is reusable across every process. Fusing them forces you to re-teach the investigation method for each version and re-map the resources for each activity.
19
+
20
+ ### How composition works in practice
21
+ - A general process skill says: *"pair me with the relevant domain skill for the map."*
22
+ - A domain skill says: *"for investigating drift, also load `investigation`; for a new method, also load `general/documentation`."*
23
+ - Cross-reference by skill `name` in prose so the reader knows what to load alongside.
24
+
25
+ ## Folder taxonomy: domain → sub-domain → process → skill-name
26
+
27
+ Organize the path from most-specific domain down to the leaf. Cross-cutting process skills that belong to no single domain live under `general/`.
28
+
29
+ ```
30
+ .claude/skills/
31
+ ├── how-to-create-skills/ ← this meta-skill (exempt from the pattern)
32
+ ├── <domain>/ ← domain knowledge (git, v2, …)
33
+ │ ├── SKILL.md ← the domain map itself (optional)
34
+ │ └── <sub-domain-or-process>/SKILL.md
35
+ └── general/ ← domain-agnostic process skills
36
+ └── <process>/SKILL.md ← performance, investigation, documentation, handoff, …
37
+ ```
38
+
39
+ Rules:
40
+ - **Domain first.** If a skill is about *one* domain, nest it under that domain (`git/pull-request`).
41
+ - **General bucket.** If a skill's method applies across domains, put it in `general/` (`general/performance`).
42
+ - Any `SKILL.md` anywhere under `.claude/skills/**` is discovered — folders are for humans, the `name` field is the identifier.
43
+ - Prefer the **most general** phrasing a skill can honestly carry. Keep repo-specific specifics (class names, endpoint paths) inside the skill, but frame the transferable method first.
44
+
45
+ ## Deciding: split or combine?
46
+
47
+ | Signal | Action |
48
+ |---|---|
49
+ | The skill mixes "where the code is" with "how to profile/debug it" | **Split** into a domain skill + a `general/` process skill |
50
+ | Two skills always get loaded together and neither stands alone | Consider **combining** — but first check whether one is really a sub-domain of the other |
51
+ | A process skill keeps accreting domain-specific class/resource names | Move those facts into the **domain** skill; keep the method general |
52
+ | A domain skill starts explaining testing/PR mechanics in depth | Move that into a **general** process skill and cross-reference |
53
+
54
+ ## SKILL.md format
55
+
56
+ ```markdown
57
+ ---
58
+ name: <kebab-case, unique across all skills>
59
+ description: <what it does + WHEN to use it + trigger phrases. This is the ONLY thing the model sees when deciding to load the skill — make it match how people actually phrase the task. For composables, name the skills to load alongside.>
60
+ argument-hint: "<optional, for slash-invoked skills>"
61
+ disable-model-invocation: true # optional — manual /invoke only
62
+ ---
63
+
64
+ # Title
65
+
66
+ Body: tables and short imperative steps first, prose last. Cross-reference
67
+ composable skills by name. Note file:line references but tell the reader to
68
+ verify them against current code.
69
+ ```
70
+
71
+ Frontmatter notes:
72
+ - **`name`** must be unique and stable — it's the slash command and the invocation id. Renaming breaks existing references, so rename deliberately.
73
+ - **`description`** is load-bearing: it's matched against the user's request to auto-activate the skill. Lead with capability, then "Use when…", then trigger phrases.
74
+ - **`disable-model-invocation: true`** makes the skill manual-only (`/name …`). Use for router/workflow skills that shouldn't fire automatically.
75
+
76
+ ## Authoring checklist
77
+ 1. Is this **knowledge** or **method**? Put it in the right place; don't fuse.
78
+ 2. Does an existing skill already cover it? Extend that instead of duplicating.
79
+ 3. Can the wording be more general without losing accuracy? Generalize.
80
+ 4. Name the composable siblings to load alongside.
81
+ 5. Write the `description` the way a user would ask for it.
82
+ 6. Keep the body scannable: tables + steps first.
@@ -1,114 +1,26 @@
1
- name: Bump version, publish, and sync front
1
+ name: Publish Package
2
2
 
3
3
  on:
4
4
  push:
5
- branches: [master]
5
+ branches:
6
+ - master
6
7
 
7
- jobs:
8
- bump-and-publish:
9
- if: "!contains(github.event.head_commit.message, '[skip ci]')"
10
- runs-on: ubuntu-latest
11
- permissions:
12
- contents: write
13
- outputs:
14
- version: ${{ steps.bump.outputs.version }}
15
- steps:
16
- - uses: actions/checkout@v4
17
-
18
- - name: Setup node
19
- uses: actions/setup-node@v4
20
- with:
21
- node-version: 25
22
- registry-url: 'https://registry.npmjs.org/'
23
-
24
- - name: Configure git
25
- run: |
26
- git config user.name "github-actions[bot]"
27
- git config user.email "github-actions[bot]@users.noreply.github.com"
28
-
29
- - name: Bump patch version
30
- id: bump
31
- run: |
32
- NEW_VERSION=$(npm version patch -m "chore: release v%s [skip ci]")
33
- echo "version=${NEW_VERSION#v}" >> "$GITHUB_OUTPUT"
34
-
35
- - name: Push version bump
36
- run: git push origin HEAD:master --follow-tags
37
-
38
- - name: Publish to npm
39
- run: npm publish --access public
40
- env:
41
- NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
8
+ permissions:
9
+ id-token: write # Required for OIDC
10
+ contents: read
42
11
 
43
- sync-front:
44
- needs: bump-and-publish
12
+ jobs:
13
+ publish:
45
14
  runs-on: ubuntu-latest
46
- env:
47
- SDK_VERSION: ${{ needs.bump-and-publish.outputs.version }}
48
15
  steps:
49
- - name: Wait for npm registry propagation
50
- run: sleep 15
51
-
52
- - name: Setup node
53
- uses: actions/setup-node@v4
54
- with:
55
- node-version: 24
16
+ - uses: actions/checkout@v6
56
17
 
57
- # ---- beta: direct commit + push ----
58
- - name: Checkout front (beta)
59
- uses: actions/checkout@v4
18
+ - uses: actions/setup-node@v6
60
19
  with:
61
- repository: insignia-education/front
62
- ref: beta
63
- token: ${{ secrets.FRONT_REPO_PAT }}
64
- path: front-beta
65
-
66
- - name: Bump SDK in front (beta)
67
- working-directory: front-beta
68
- run: npm install "@insignia-education/api-sdk-js@${SDK_VERSION}"
69
-
70
- - name: Commit and push (beta)
71
- working-directory: front-beta
72
- run: |
73
- git config user.name "github-actions[bot]"
74
- git config user.email "github-actions[bot]@users.noreply.github.com"
75
- git add package.json package-lock.json
76
- if git diff --cached --quiet; then
77
- echo "No changes, skipping"
78
- else
79
- git commit -m "chore: bump @insignia-education/api-sdk-js to ${SDK_VERSION}"
80
- git push origin beta
81
- fi
82
-
83
- # ---- master: open a PR for review ----
84
- - name: Checkout front (master)
85
- uses: actions/checkout@v4
86
- with:
87
- repository: insignia-education/front
88
- ref: master
89
- token: ${{ secrets.FRONT_REPO_PAT }}
90
- path: front-master
91
-
92
- - name: Bump SDK in front (master branch)
93
- working-directory: front-master
94
- run: npm install "@insignia-education/api-sdk-js@${SDK_VERSION}"
95
-
96
- - name: Open PR against master
97
- working-directory: front-master
98
- env:
99
- GH_TOKEN: ${{ secrets.FRONT_REPO_PAT }}
100
- run: |
101
- git config user.name "github-actions[bot]"
102
- git config user.email "github-actions[bot]@users.noreply.github.com"
103
- if git diff --quiet; then
104
- echo "No changes, skipping PR"
105
- exit 0
106
- fi
107
- BRANCH="chore/bump-api-sdk-js-${SDK_VERSION}"
108
- git checkout -b "$BRANCH"
109
- git add package.json package-lock.json
110
- git commit -m "chore: bump @insignia-education/api-sdk-js to ${SDK_VERSION}"
111
- git push origin "$BRANCH"
112
- gh pr create --repo insignia-education/front --base master --head "$BRANCH" \
113
- --title "chore: bump @insignia-education/api-sdk-js to ${SDK_VERSION}" \
114
- --body "Automated dependency bump triggered by insignia-education/api-sdk-js@${SDK_VERSION}."
20
+ node-version: '24'
21
+ registry-url: 'https://registry.npmjs.org'
22
+ package-manager-cache: false # never use caching in release builds
23
+ - run: npm ci
24
+ - run: npm run build --if-present
25
+ # npm test disabled: integration suite needs a live api backend, no CI service for it yet
26
+ - run: npm publish # Or: npm stage publish
package/CLAUDE.md ADDED
@@ -0,0 +1,60 @@
1
+ # CLAUDE.md
2
+
3
+ This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4
+
5
+ > **Status: Active — the sole client for `insignia-education/api`.**
6
+ > A thin, zero-runtime-dependency JavaScript SDK wrapping the Laravel 12 backend
7
+ > [`insignia-education/api`](../api). Its only consumer is
8
+ > [`insignia-education/front`](../front) (React 19 + Vite 8 SPA) — `front` never calls `api`
9
+ > directly. `v1` is being finalized and will be permanently frozen once stable; a future `v2`
10
+ > is added alongside `v1`, never in place of it.
11
+
12
+ ---
13
+
14
+ > The canonical agent-readable version of these instructions is **`AGENTS.md`** (same directory). Both
15
+ > files are kept in sync; CLAUDE.md adds Claude Code–specific detail where needed. Read `AGENTS.md` first
16
+ > for versioning rules, structure, conventions, testing coverage requirements, the i18n rule, the
17
+ > API↔SDK sync rule, and the "Never do" list — none of that is repeated here.
18
+
19
+ ---
20
+
21
+ ## Related repos
22
+
23
+ | Repo | Role |
24
+ |---|---|
25
+ | [`api`](../api) | Laravel backend this SDK wraps. Any endpoint added, renamed, or removed there must be mirrored here in the same task — see `AGENTS.md`'s sync rule. |
26
+ | [`front`](../front) | The sole consumer. Talks to `api` exclusively through this package — a method missing here is a method `front` cannot use. |
27
+
28
+ This SDK has no independent purpose — it only exists to mirror `api`. When in doubt about what a
29
+ method should do, the answer is "whatever the matching `api` endpoint does," not a judgment call
30
+ made here.
31
+
32
+ ## Deployment / publish (GitHub Actions — read this before touching `master`)
33
+
34
+ `.github/workflows/npm-publish-github-packages.yml` runs on every push to `master` (skipped only
35
+ if the commit message contains `[skip ci]`). It is **not** a manual `npm publish` a human runs by
36
+ hand — merging a PR to `master` is the trigger, and that merge is a human action, so the "never
37
+ publish on your own initiative" rule in `AGENTS.md` still applies to *merging to master*, not just
38
+ to running `npm publish` directly.
39
+
40
+ What the workflow actually does, in order:
41
+
42
+ 1. **`bump-and-publish`** — bumps the patch version (`npm version patch -m "chore: release v%s
43
+ [skip ci]"`), pushes the version-bump commit + tag back to `master`, then publishes the package
44
+ to npm (`npm publish --access public`, using `secrets.NPM_TOKEN`).
45
+ 2. **`sync-front`** (runs after publish, waits 15s for npm registry propagation) — automatically
46
+ syncs `front` using `secrets.FRONT_REPO_PAT`:
47
+ - **`beta` branch**: checks it out, runs `npm install @insignia-education/api-sdk-js@<new
48
+ version>`, commits, and **pushes directly** — no review step.
49
+ - **`master` branch**: checks it out, runs the same install, and **opens a PR** against
50
+ `front`'s `master` (`chore/bump-api-sdk-js-<version>`) for human review — it does not merge
51
+ itself.
52
+
53
+ **Practical implications:**
54
+ - Merging a PR to this repo's `master` is not just "ship the SDK change" — it also auto-bumps
55
+ `front`'s `beta` branch with no human in the loop, and opens (but does not merge) a PR against
56
+ `front`'s `master`. Treat a `master` merge here as a deploy action, not a routine commit.
57
+ - There is no manual "bump the consumer's `package.json`" step to perform for `beta` — CI already
58
+ does it. A human only needs to review/merge the auto-opened PR against `front`'s `master`.
59
+ - Requires `secrets.NPM_TOKEN` (npm publish) and `secrets.FRONT_REPO_PAT` (push to `front` +
60
+ open PRs there) to be configured on this repo.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@insignia-education/api-sdk-js",
3
- "version": "0.15.63",
3
+ "version": "0.15.65",
4
4
  "description": "JavaScript SDK for the Insignia Education API",
5
5
  "main": "index.js",
6
6
  "type": "module",
@@ -48,15 +48,19 @@ export default class Users {
48
48
  }
49
49
  courseNotes(userId) { return this.#nested(userId, 'course-notes'); }
50
50
 
51
- /** get() accepts an optional { courseId } filter to narrow to a single course. */
51
+ /** get() accepts optional { courseId, withTrashed } filters withTrashed also returns soft-deleted attempts. */
52
52
  quizzes(userId) {
53
53
  const base = `/users/${userId}/quizzes`;
54
54
  const client = this.#client;
55
55
  return {
56
- get: (id = null, { courseId } = {}) => id ? client.get(`${base}/${id}`) : client.get(courseId ? `${base}?course_id=${courseId}` : base),
56
+ get: (id = null, { courseId, withTrashed } = {}) => id
57
+ ? client.get(`${base}/${id}`)
58
+ : client.get(base, { course_id: courseId, with_trashed: withTrashed ? 1 : undefined }),
57
59
  create: (data) => client.put(base, data),
58
60
  edit: (id, data) => client.patch(`${base}/${id}`, data),
59
61
  delete: (id) => client.del(`${base}/${id}`),
62
+ /** Puts a soft-deleted attempt back. */
63
+ restore: (id) => client.post(`${base}/${id}/restore`),
60
64
  /**
61
65
  * Upload the file a student attaches as their answer to a
62
66
  * document_upload (PDF) or audio_answer (recording) question
@@ -78,6 +82,12 @@ export default class Users {
78
82
  create: (data) => client.put(base, data),
79
83
  edit: (id, data) => client.patch(`${base}/${id}`, data),
80
84
  delete: (id) => client.del(`${base}/${id}`),
85
+ /**
86
+ * Individual sessions only: clears teacher/course/date/time/meeting info
87
+ * so the slot can be rebooked. The owner may reset up to 1h before the
88
+ * session starts; a seller-and-above may reset any time.
89
+ */
90
+ reset: (id) => client.post(`${base}/${id}/reset`),
81
91
  };
82
92
  }
83
93