@use-the-fork/spindle 0.0.2 → 0.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.
Files changed (34) hide show
  1. package/build/Assets/Blueprints/Catalog.js +12 -7
  2. package/build/Assets/Blueprints/skills/author-agent/SKILL.md +9 -8
  3. package/build/Assets/Blueprints/skills/author-instruction/SKILL.md +9 -8
  4. package/build/Assets/Blueprints/skills/author-skill/SKILL.md +9 -8
  5. package/build/Assets/Blueprints/skills/grill/SKILL.md +3 -3
  6. package/build/Assets/Blueprints/skills/int-subagent-driven-dev/SKILL.md +6 -6
  7. package/build/Assets/Blueprints/skills/int-subagent-driven-dev/references/corrective-rounds.md +1 -1
  8. package/build/Assets/Blueprints/skills/int-subagent-driven-dev/references/example-workflow.md +4 -4
  9. package/build/Assets/Blueprints/skills/int-subagent-driven-dev/references/full-spec.md +12 -12
  10. package/build/Assets/Blueprints/skills/int-testing-agent-guidance/SKILL.md +2 -2
  11. package/build/Assets/Blueprints/skills/int-writing-skills/SKILL.md +2 -2
  12. package/build/Assets/Blueprints/skills/int-writing-skills/references/testing-skills.md +2 -2
  13. package/build/Assets/Blueprints/skills/ref-php-laravel-saloon-api-integrations/SKILL.md +38 -0
  14. package/build/Assets/Blueprints/skills/ref-php-laravel-saloon-api-integrations/references/concurrency-and-pools.md +73 -0
  15. package/build/Assets/Blueprints/skills/ref-php-laravel-saloon-api-integrations/references/connectors.md +99 -0
  16. package/build/Assets/Blueprints/skills/ref-php-laravel-saloon-api-integrations/references/data-transfer-objects.md +104 -0
  17. package/build/Assets/Blueprints/skills/ref-php-laravel-saloon-api-integrations/references/handling-failures.md +95 -0
  18. package/build/Assets/Blueprints/skills/ref-php-laravel-saloon-api-integrations/references/requests.md +111 -0
  19. package/build/Assets/Blueprints/skills/ref-php-laravel-saloon-api-integrations/references/responses.md +56 -0
  20. package/build/Assets/Blueprints/skills/ref-php-laravel-saloon-api-integrations/references/sending-requests.md +42 -0
  21. package/build/Assets/Blueprints/skills/ref-php-laravel-saloon-api-integrations/references/testing.md +119 -0
  22. package/build/Assets/Blueprints/skills/{author-design → sdd-author-design}/SKILL.md +12 -4
  23. package/build/Assets/Blueprints/skills/{grill-design → sdd-grill-design}/SKILL.md +1 -1
  24. package/build/Assets/Blueprints/skills/{implement-spec → sdd-implement-spec}/SKILL.md +3 -3
  25. package/build/Assets/Blueprints/skills/{to-spec → sdd-to-spec}/SKILL.md +3 -3
  26. package/build/Assets/Blueprints/skills/{to-tickets → sdd-to-tickets}/SKILL.md +3 -3
  27. package/build/Assets/Blueprints/skills/{setup-project → spindle-project-setup}/SKILL.md +4 -4
  28. package/build/Assets/Blueprints/skills/{update-tooling → spindle-tooling-update}/SKILL.md +5 -5
  29. package/build/Assets/Templates/project/copilot-instructions.md +3 -9
  30. package/build/Assets/Templates/project/ticket-tracker.md +5 -5
  31. package/build/BlueprintManagement/Commands/Prompts.js +1 -1
  32. package/build/TemplateRendering/Computed/ComputedVariableProviders.js +2 -0
  33. package/build/TemplateRendering/Computed/Providers/AuthoringFlowchartProvider.js +26 -0
  34. package/package.json +1 -1
@@ -62,14 +62,14 @@ export const blueprintCatalog = {
62
62
  skills: {
63
63
  "asd-ste100": { path: "asd-ste100/", status: "active", stacks: [] },
64
64
  "author-agent": { path: "author-agent/", status: "active", stacks: [] },
65
- "author-design": { path: "author-design/", status: "active", stacks: [] },
65
+ "sdd-author-design": { path: "sdd-author-design/", status: "active", stacks: [] },
66
66
  "author-instruction": { path: "author-instruction/", status: "active", stacks: [] },
67
67
  "author-skill": { path: "author-skill/", status: "active", stacks: [] },
68
68
  grill: { path: "grill/", status: "active", stacks: [] },
69
- "grill-design": { path: "grill-design/", status: "active", stacks: [] },
69
+ "sdd-grill-design": { path: "sdd-grill-design/", status: "active", stacks: [] },
70
70
  "grill-with-docs": { path: "grill-with-docs/", status: "active", stacks: [] },
71
71
  implement: { path: "implement/", status: "active", stacks: [] },
72
- "implement-spec": { path: "implement-spec/", status: "active", stacks: [] },
72
+ "sdd-implement-spec": { path: "sdd-implement-spec/", status: "active", stacks: [] },
73
73
  "improve-codebase-architecture": {
74
74
  path: "improve-codebase-architecture/",
75
75
  status: "active",
@@ -102,9 +102,14 @@ export const blueprintCatalog = {
102
102
  "int-writing-instruction": { path: "int-writing-instruction/", status: "active", stacks: [] },
103
103
  "int-writing-skills": { path: "int-writing-skills/", status: "active", stacks: [] },
104
104
  retrospective: { path: "retrospective/", status: "active", stacks: [] },
105
- "setup-project": { path: "setup-project/", status: "active", stacks: [] },
106
- "to-spec": { path: "to-spec/", status: "active", stacks: [] },
107
- "to-tickets": { path: "to-tickets/", status: "active", stacks: [] },
108
- "update-tooling": { path: "update-tooling/", status: "active", stacks: [] },
105
+ "ref-php-laravel-saloon-api-integrations": {
106
+ path: "ref-php-laravel-saloon-api-integrations/",
107
+ status: "active",
108
+ stacks: ["php-laravel"],
109
+ },
110
+ "sdd-to-spec": { path: "sdd-to-spec/", status: "active", stacks: [] },
111
+ "sdd-to-tickets": { path: "sdd-to-tickets/", status: "active", stacks: [] },
112
+ "spindle-project-setup": { path: "spindle-project-setup/", status: "active", stacks: [] },
113
+ "spindle-tooling-update": { path: "spindle-tooling-update/", status: "active", stacks: [] },
109
114
  },
110
115
  };
@@ -1,26 +1,27 @@
1
1
  ---
2
2
  name: author-agent
3
3
  description: Create or revise a workspace custom agent from requirements.
4
- argument-hint: "[--test] <agent idea or requirements>"
4
+ argument-hint: "<agent idea or requirements>"
5
5
  disable-model-invocation: true
6
6
  user-invocable: true
7
7
  metadata:
8
8
  spindle:
9
- version: 1.0.0
9
+ version: 1.0.2
10
10
  ---
11
11
 
12
12
  Create or update a project agent in `.github/agents/<agent-name>.agent.md` based on the user's requirements.
13
13
 
14
- ## Required skills
14
+ ## Authoring flow
15
15
 
16
- Before drafting or editing, read:
16
+ {{ computed.authoring_flowchart }}
17
+
18
+ Before grilling, read and consider only the `int-writing-for-agents` and `asd-ste100` skills. Do not follow their workflows or load skills they reference yet.
19
+
20
+ After the user confirms shared understanding, load and follow:
17
21
 
18
22
  - **REQUIRED:** `int-writing-agents`
19
- - **REQUIRED:** `int-writing-for-agents`
20
23
  - **REQUIRED:** `int-testing-agent-guidance`
21
24
 
22
- These skills define the complete authoring workflow. Every agent change requires the baseline and focused validation specified by `int-testing-agent-guidance`; `--test` does not disable or replace them.
23
-
24
- When `--test` is present, also run the expanded testing workflow in `int-testing-agent-guidance`.
25
+ Apply the clarity rules from the `asd-ste100` skill. Include a before/after table only when the user requests one. Run the core and expanded testing workflows in `int-testing-agent-guidance` for every authoring request.
25
26
 
26
27
  Do not modify unrelated files. Report the skill changed and validation performed, including any blockers or unverified requirements.
@@ -1,27 +1,28 @@
1
1
  ---
2
2
  name: author-instruction
3
3
  description: Create or revise workspace-scoped Copilot instruction files from the user's requirements
4
- argument-hint: "[--test] <instruction requirements>"
4
+ argument-hint: "<instruction requirements>"
5
5
  disable-model-invocation: true
6
6
  user-invocable: true
7
7
  metadata:
8
8
  spindle:
9
- version: 1.0.0
9
+ version: 1.0.2
10
10
  ---
11
11
 
12
12
  Create or update a project instruction in `.github/instructions/**/*.instructions.md` based on the user's requirements.
13
13
 
14
- ## Required skills
14
+ ## Authoring flow
15
15
 
16
- Before drafting or editing, read:
16
+ {{ computed.authoring_flowchart }}
17
+
18
+ Before grilling, read and consider only the `int-writing-for-agents` and `asd-ste100` skills. Do not follow their workflows or load skills they reference yet.
19
+
20
+ After the user confirms shared understanding, load and follow:
17
21
 
18
22
  - **REQUIRED:** `int-writing-instruction`
19
- - **REQUIRED:** `int-writing-for-agents`
20
23
  - **REQUIRED:** `int-testing-agent-guidance`
21
24
 
22
- These skills define the complete authoring workflow. Every instruction change requires the baseline and focused validation specified by `int-testing-agent-guidance`; `--test` does not disable or replace them.
23
-
24
- When `--test` is present, also run the expanded testing workflow in `int-testing-agent-guidance`.
25
+ Apply the clarity rules from the `asd-ste100` skill. Include a before/after table only when the user requests one. Run the core and expanded testing workflows in `int-testing-agent-guidance` for every authoring request.
25
26
 
26
27
  Verify any `applyTo` glob against concrete in-scope files and near misses; every intended file must match, and out-of-scope files must not.
27
28
 
@@ -1,26 +1,27 @@
1
1
  ---
2
2
  name: author-skill
3
3
  description: Create or update a project skill from the user's requirements
4
- argument-hint: "[--test] <skill idea or requirements>"
4
+ argument-hint: "<skill idea or requirements>"
5
5
  disable-model-invocation: true
6
6
  user-invocable: true
7
7
  metadata:
8
8
  spindle:
9
- version: 1.0.0
9
+ version: 1.0.2
10
10
  ---
11
11
 
12
12
  Create or update a project skill in `.github/skills/<skill-name>/SKILL.md` based on the user's requirements.
13
13
 
14
- ## Required skills
14
+ ## Authoring flow
15
15
 
16
- Before drafting or editing, read:
16
+ {{ computed.authoring_flowchart }}
17
+
18
+ Before grilling, read and consider only the `int-writing-for-agents` and `asd-ste100` skills. Do not follow their workflows or load skills they reference yet.
19
+
20
+ After the user confirms shared understanding, load and follow:
17
21
 
18
22
  - **REQUIRED:** `int-writing-skills`
19
- - **REQUIRED:** `int-writing-for-agents`
20
23
  - **REQUIRED:** `int-testing-agent-guidance`
21
24
 
22
- These skills define the complete authoring workflow. Every skill change requires the baseline and focused validation specified by `int-testing-agent-guidance`; `--test` does not disable or replace them.
23
-
24
- When `--test` is present, also run the expanded testing workflow in `int-testing-agent-guidance`.
25
+ Apply the clarity rules from the `asd-ste100` skill. Include a before/after table only when the user requests one. Run the core and expanded testing workflows in `int-testing-agent-guidance` for every authoring request.
25
26
 
26
27
  Do not modify unrelated files. Report the skill changed and validation performed, including any blockers or unverified requirements.
@@ -4,7 +4,7 @@ description: "Grill the user relentlessly about a plan, decision, or idea. Use w
4
4
  user-invocable: false
5
5
  metadata:
6
6
  spindle:
7
- version: 1.0.2
7
+ version: 1.0.3
8
8
  ---
9
9
 
10
10
  Stress-test the user's proposal until its decisions are explicit and you share an understanding. Treat dependent decisions as a **design tree**.
@@ -16,13 +16,13 @@ Stress-test the user's proposal until its decisions are explicit and you share a
16
16
  3. Apply the answer and continue the queue, revising or skipping questions whose premises changed. Newly unlocked decisions wait for the next round.
17
17
  4. When the queue is exhausted, recompute the frontier and start the next round.
18
18
 
19
- Label each question visibly as **Round <R>, Question <Q> of <TOTAL> - <title>**, in chat or the tool's user-visible title. Start both counters at 1; increment the question number for each question asked and reset it to 1 when the round advances. The first question announces the new round without exposing the remaining queue.
19
+ Label each question visibly as **Round <R>, Question <Q> - <title>**, in chat or the tool's user-visible title. Start both counters at 1; increment the question number for each question asked and reset it to 1 when the round advances. The first question announces the new round without exposing the remaining queue.
20
20
 
21
21
  Include the context needed to decide and a recommended answer. Phrase confirmations so "yes" accepts the recommendation; for choices, identify the recommended option.
22
22
 
23
23
  Example opening:
24
24
 
25
- > **Round 1, Question 1 of 5 - Output format**
25
+ > **Round 1, Question 1 - Output format**
26
26
  >
27
27
  > CSV meets the agreed export requirements. I recommend CSV. Shall we use it?
28
28
 
@@ -41,17 +41,17 @@ flowchart TD
41
41
 
42
42
  ## Ticket workflow
43
43
 
44
- 1. Read the feature spec, tickets, applicable instructions, glossary, and ADRs. Inspect `spindle sdd status --spec <path>` and `spindle sdd ready --spec <path>` to understand blockers, dependencies, and available work.
45
- 2. Create a ticket for independently actionable work with `spindle sdd ticket create`. Fill its `[REQUIREMENTS]` and `[ACCEPTANCE CRITERIA]` placeholders. Use `spindle sdd ticket update` for tracker status, explicit blockers, and dependencies; the supported lifecycle is `open`, `in-progress`, and `closed`. Readiness is derived from status, blockers, and dependencies rather than stored as a separate triage state.
46
- 3. Claim a ready ticket with `spindle sdd claim`. Dispatch implementation with `spindle sdd implement`; pass the worker the exact assignment and report destination. Submit its report with `spindle sdd submit --role implementation`.
44
+ 1. Read the feature spec, tickets, applicable instructions, glossary, and ADRs. Inspect `{{ computed.spindle_package_manager }} spindle sdd status --spec <path>` and `{{ computed.spindle_package_manager }} spindle sdd ready --spec <path>` to understand blockers, dependencies, and available work.
45
+ 2. Create a ticket for independently actionable work with `{{ computed.spindle_package_manager }} spindle sdd ticket create`. Fill its `[REQUIREMENTS]` and `[ACCEPTANCE CRITERIA]` placeholders. Use `{{ computed.spindle_package_manager }} spindle sdd ticket update` for tracker status, explicit blockers, and dependencies; the supported lifecycle is `open`, `in-progress`, and `closed`. Readiness is derived from status, blockers, and dependencies rather than stored as a separate triage state.
46
+ 3. Claim a ready ticket with `{{ computed.spindle_package_manager }} spindle sdd claim`. Dispatch implementation with `{{ computed.spindle_package_manager }} spindle sdd implement`; pass the worker the exact assignment and report destination. Submit its report with `{{ computed.spindle_package_manager }} spindle sdd submit --role implementation`.
47
47
  4. Run relevant tests and checks and record their actual outcomes against the current snapshot. TDD is not required, but verification is.
48
- 5. Address implementation and verification gaps, then close the ticket with `spindle sdd ticket update --status closed` once its acceptance criteria are met. Do not use per-ticket accept or integrate steps.
48
+ 5. Address implementation and verification gaps, then close the ticket with `{{ computed.spindle_package_manager }} spindle sdd ticket update --status closed` once its acceptance criteria are met. Do not use per-ticket accept or integrate steps.
49
49
 
50
- If work is interrupted, inspect `spindle sdd status` and use `spindle sdd resume` to restore the recorded assignment. Preserve existing reports, findings, and evidence. Do not invent missing results or reset progress.
50
+ If work is interrupted, inspect `{{ computed.spindle_package_manager }} spindle sdd status` and use `{{ computed.spindle_package_manager }} spindle sdd resume` to restore the recorded assignment. Preserve existing reports, findings, and evidence. Do not invent missing results or reset progress.
51
51
 
52
52
  ## Feature review and completion
53
53
 
54
- After every ticket is closed, establish current feature-level checks and request the comprehensive review with `spindle sdd review --scope delivery --inventory <json-array>`. The `sdd-reviewer` is the default reviewer. Add specialists only for justified objectives with `spindle sdd review require --scope delivery --type <agent-name>`; eligible names must be marked `canReview: true` in the Blueprint Catalog, and actual agent access must be confirmed before dispatch.
54
+ After every ticket is closed, establish current feature-level checks and request the comprehensive review with `{{ computed.spindle_package_manager }} spindle sdd review --scope delivery --inventory <json-array>`. The `sdd-reviewer` is the default reviewer. Add specialists only for justified objectives with `{{ computed.spindle_package_manager }} spindle sdd review require --scope delivery --type <agent-name>`; eligible names must be marked `canReview: true` in the Blueprint Catalog, and actual agent access must be confirmed before dispatch.
55
55
 
56
56
  Submit every assigned review report against its exact assignment. Register findings from their report and snapshot. A blocking finding can name `--related-ticket`; once the complete review batch is submitted, that ticket is reopened so work can resume. Resolve blocking findings through ticket work and repeat any invalidated checks and reviews.
57
57
 
@@ -38,7 +38,7 @@ adjudication rather than another automatic dispatch.
38
38
 
39
39
  ## C. Record objective and dispatch correction
40
40
 
41
- Use `spindle sdd correct --scope delivery` to record and dispatch the feature-level
41
+ Use `{{ computed.spindle_package_manager }} spindle sdd correct --scope delivery` to record and dispatch the feature-level
42
42
  correction. Preserve prior attempts, reports, and report destinations.
43
43
  Serialize implementation edits and keep the assignment limited to the
44
44
  recorded objective.
@@ -5,16 +5,16 @@ Markdown holds requirements and acceptance criteria; `sdd.json` holds tracker
5
5
  status and dependencies.
6
6
 
7
7
  1. Create a feature workspace and split independent work into tickets:
8
- `spindle sdd create`, then `spindle sdd ticket create` for each ticket.
8
+ `{{ computed.spindle_package_manager }} spindle sdd create`, then `{{ computed.spindle_package_manager }} spindle sdd ticket create` for each ticket.
9
9
  2. Record the dependency with
10
- `spindle sdd ticket update --ticket T-0002 --blocked-by T-0001`. Check `spindle sdd ready`:
10
+ `{{ computed.spindle_package_manager }} spindle sdd ticket update --ticket T-0002 --blocked-by T-0001`. Check `{{ computed.spindle_package_manager }} spindle sdd ready`:
11
11
  the prerequisite is ready and the dependent ticket is not.
12
12
  3. Claim and implement `T-0001`, submit its report, run and record relevant
13
- checks, then close it with `spindle sdd ticket update --status closed`.
13
+ checks, then close it with `{{ computed.spindle_package_manager }} spindle sdd ticket update --status closed`.
14
14
  4. `T-0002` becomes ready because its dependency is closed. Implement and
15
15
  verify it in the same way, then close it.
16
16
  5. Record current feature-level required checks and request the comprehensive
17
- review with `spindle sdd review --scope delivery`. Add only justified specialists.
17
+ review with `{{ computed.spindle_package_manager }} spindle sdd review --scope delivery`. Add only justified specialists.
18
18
  6. Submit every assigned report. Register findings from their report and
19
19
  snapshot. A blocking finding can reopen its related ticket; complete the
20
20
  correction, close the ticket again, and refresh stale checks and review.
@@ -7,16 +7,16 @@ checks, review assignments, findings, and corrections.
7
7
 
8
8
  ## Checks and review
9
9
 
10
- Inspect `spindle sdd status --spec <spec>` and `spindle sdd next --spec <spec>`. Establish
11
- required final checks with `spindle sdd checks require --scope delivery`, run them, and
10
+ Inspect `{{ computed.spindle_package_manager }} spindle sdd status --spec <spec>` and `{{ computed.spindle_package_manager }} spindle sdd next --spec <spec>`. Establish
11
+ required final checks with `{{ computed.spindle_package_manager }} spindle sdd checks require --scope delivery`, run them, and
12
12
  record actual results against the returned snapshot. Then dispatch the
13
13
  comprehensive review with
14
- `spindle sdd review --scope delivery --inventory <json-array>`. Its inventory must
14
+ `{{ computed.spindle_package_manager }} spindle sdd review --scope delivery --inventory <json-array>`. Its inventory must
15
15
  cover the feature's current Git-derived changes.
16
16
 
17
17
  The `sdd-reviewer` is the default comprehensive reviewer. Before dispatch,
18
18
  record any justified specialist with
19
- `spindle sdd review require --scope delivery --type <agent-name> --details <objective>`.
19
+ `{{ computed.spindle_package_manager }} spindle sdd review require --scope delivery --type <agent-name> --details <objective>`.
20
20
  Only catalog agents with `canReview: true` are eligible. Confirm that the
21
21
  controller can actually dispatch each selected agent; catalog eligibility does
22
22
  not guarantee harness access.
@@ -28,24 +28,24 @@ failed, unavailable, stale, or mismatched review blocks completion.
28
28
  ## Findings and correction
29
29
 
30
30
  Register findings from their assigned reports and snapshots with
31
- `spindle sdd finding create --scope delivery`. Delivery findings have feature-scoped
31
+ `{{ computed.spindle_package_manager }} spindle sdd finding create --scope delivery`. Delivery findings have feature-scoped
32
32
  IDs, provenance, ruling history, and status. Use `--related-ticket <id>` for a
33
33
  finding that should return work to a specific ticket. A blocking linked finding
34
34
  reopens its ticket after the complete review batch is submitted; dependent
35
35
  tickets remain blocked until that ticket is closed again.
36
36
 
37
- Use `spindle sdd finding update --scope delivery` for explicit rulings. Deferring a
37
+ Use `{{ computed.spindle_package_manager }} spindle sdd finding update --scope delivery` for explicit rulings. Deferring a
38
38
  blocker requires rationale, a follow-up reference, and an approved delivery
39
39
  requirements decision. Record that decision with
40
- `spindle sdd requirements decide --scope delivery` only after a requirements change
40
+ `{{ computed.spindle_package_manager }} spindle sdd requirements decide --scope delivery` only after a requirements change
41
41
  and completed prior review. Approval invalidates earlier aggregate assignments.
42
42
 
43
43
  For actionable feature findings, follow [feature correction](./corrective-rounds.md)
44
- and use `spindle sdd correct --scope delivery` to record
44
+ and use `{{ computed.spindle_package_manager }} spindle sdd correct --scope delivery` to record
45
45
  each independent correction attempt. Record passing checks against the changed
46
46
  feature snapshot and submit the implementation report before requesting a new
47
47
  feature review. Pause unproductive work, recurring failures, or requirements
48
- disagreement for adjudication. Resume with `spindle sdd resume --scope delivery`;
48
+ disagreement for adjudication. Resume with `{{ computed.spindle_package_manager }} spindle sdd resume --scope delivery`;
49
49
  preserve existing assignments, attempts, evidence, and adjudication.
50
50
 
51
51
  ## Finish
@@ -59,14 +59,14 @@ the original comparison baseline is identified. Do not silently use the
59
59
  current `HEAD` after implementation; that could omit completed feature work
60
60
  from review.
61
61
 
62
- Finish with `spindle sdd finish --spec <spec> --author <author>`. Completion requires
62
+ Finish with `{{ computed.spindle_package_manager }} spindle sdd finish --spec <spec> --author <author>`. Completion requires
63
63
  at least one ticket, every ticket closed, current passing required feature
64
64
  checks and reviews, and no unresolved delivery blockers. The retrospective
65
65
  policy is stored at feature creation: when required, attach a Markdown report
66
66
  with `--report`; otherwise it is optional. Any report must remain inside that
67
67
  feature's `reports/` directory.
68
68
 
69
- Use `spindle sdd status`, `spindle sdd next`, and
70
- `spindle sdd resume --scope delivery` to inspect blockers and
69
+ Use `{{ computed.spindle_package_manager }} spindle sdd status`, `{{ computed.spindle_package_manager }} spindle sdd next`, and
70
+ `{{ computed.spindle_package_manager }} spindle sdd resume --scope delivery` to inspect blockers and
71
71
  restore interrupted feature-level work. These commands do not close tickets or
72
72
  publish changes.
@@ -2,7 +2,7 @@
2
2
  name: int-testing-agent-guidance
3
3
  metadata:
4
4
  spindle:
5
- version: 1.0.0
5
+ version: 1.0.1
6
6
  description: "{{ computed.internal_skill_description }}"
7
7
  user-invocable: false
8
8
  ---
@@ -32,7 +32,7 @@ Use this workflow for behavior-shaping changes to skills, agents, prompts, instr
32
32
 
33
33
  ## Expanded testing
34
34
 
35
- Use expanded testing when the user requests it or the skill is invoked with `--test`. This adds independent samples; it does not replace the core baseline and retest.
35
+ Always run expanded testing for authoring tasks. It adds independent samples and does not replace the core baseline and retest.
36
36
 
37
37
  1. Freeze scenario prompts and observable pass criteria before dispatch. Cover each meaningful branch. For discipline-enforcing guidance, use at least three scenarios, each combining at least three pressures such as deadline, authority, sunk cost, or exhaustion.
38
38
  2. Run five independent read-only agents against the baseline. For a new document, provide no proposed guidance; for an edit, provide the current version. Each agent runs every scenario once and reports its concrete choices and rationalizations verbatim.
@@ -4,7 +4,7 @@ description: "{{ computed.internal_skill_description }}"
4
4
  user-invocable: false
5
5
  metadata:
6
6
  spindle:
7
- version: 1.3.0
7
+ version: 1.3.1
8
8
  ---
9
9
 
10
10
  # Writing Skills
@@ -118,7 +118,7 @@ Compare observed behavior with the unchanged criterion. An unresolved failure se
118
118
 
119
119
  ### G. Refactor and deliver
120
120
 
121
- Prune duplication, stale material, and speculative rules. Retest after wording changes. Verify frontmatter, relative links, resource packaging, and any required version bump. Run expanded testing only when requested, including `--test`.
121
+ Prune duplication, stale material, and speculative rules. Retest after wording changes. Verify frontmatter, relative links, resource packaging, and any required version bump. Always run expanded testing with `int-testing-agent-guidance`.
122
122
 
123
123
  **Complete when:** final validation passes or limitations are explicit, and the change is ready for authorized delivery. Commit, push, or open a PR only when requested.
124
124
 
@@ -36,7 +36,7 @@ For discipline-enforcing guidance, consult [Persuasion principles](./persuasion-
36
36
 
37
37
  Rerun the same prompt and criterion with the full revised guidance in a fresh context. Check actual choices, resource loads, and artifacts. Correct remaining failures narrowly, then rerun after each wording change.
38
38
 
39
- Run expanded testing only when explicitly requested or when `--test` is present, using `int-testing-agent-guidance`. It adds coverage rather than replacing the focused baseline and retest.
39
+ Always run expanded testing with `int-testing-agent-guidance`. It adds coverage rather than replacing the focused baseline and retest.
40
40
 
41
41
  | Testing pitfall | Required evidence |
42
42
  | --------------------------------------- | --------------------------------------------------------------- |
@@ -45,4 +45,4 @@ Run expanded testing only when explicitly requested or when `--test` is present,
45
45
  | "There is no time" | Recorded validation or an explicit blocker, not claimed success |
46
46
  | "The output is close enough" | The unchanged observable criterion passes |
47
47
 
48
- **Complete when:** the final focused scenario passes without unresolved failures, requested expanded testing is complete, or remaining failures and validation limits are explicitly reported.
48
+ **Complete when:** the final focused scenario passes without unresolved failures, expanded testing is complete, or remaining failures and validation limits are explicitly reported.
@@ -0,0 +1,38 @@
1
+ ---
2
+ name: ref-php-laravel-saloon-api-integrations
3
+ description: "Use when building or testing Laravel API integrations with Saloon: connectors, requests, responses, failures, mocks, pools, or DTOs."
4
+ metadata:
5
+ spindle:
6
+ version: 1.0.0
7
+ ---
8
+
9
+ # Working with Saloon
10
+
11
+ This skill covers the latest Saloon release and its Laravel plugin.
12
+
13
+ ## Integration boundaries
14
+
15
+ A connector owns the base URL, shared authentication, default headers, and client configuration.
16
+ A request owns its method, endpoint, and request-specific query, headers, and body.
17
+ The connector sends the request.
18
+
19
+ ## Topic lookup
20
+
21
+ Before writing code, read each reference whose condition matches the task.
22
+ For combined tasks, read all matching references.
23
+
24
+ | When working on | Read |
25
+ | ----------------------------------------------------------------------------------- | ------------------------------------------------------------ |
26
+ | Base URL, shared authentication, default headers, timeouts, or client configuration | [Connectors](references/connectors.md) |
27
+ | HTTP method, endpoint, inputs, query parameters, headers, or JSON body | [Requests](references/requests.md) |
28
+ | `send()` or `sendAsync()`, including promise handling | [Sending requests](references/sending-requests.md) |
29
+ | Status, headers, body parsing, response helpers, or custom response classes | [Responses](references/responses.md) |
30
+ | HTTP or connection failures, throwing, or custom failure detection and exceptions | [Handling failures](references/handling-failures.md) |
31
+ | Tests, request assertions, mocks, or recorded fixtures | [Testing](references/testing.md) |
32
+ | Concurrent batches, rate limits, keyed results, or pool handlers | [Concurrency and pools](references/concurrency-and-pools.md) |
33
+ | Typed response mapping or DTO-driven request bodies | [Data transfer objects](references/data-transfer-objects.md) |
34
+
35
+ ## Sources
36
+
37
+ Use the [official documentation](https://docs.saloon.dev/) for API details beyond these references.
38
+ Use the [latest release](https://github.com/saloonphp/saloon/releases/latest) for current changes.
@@ -0,0 +1,73 @@
1
+ # Concurrency & Pools
2
+
3
+ A pool sends independent requests concurrently through one connector.
4
+ Use pools for batches such as fetching records by ID.
5
+ Concurrency requires `GuzzleSender` (the default) or `HttpSender`.
6
+
7
+ ## Basic pool
8
+
9
+ ```php
10
+ use Saloon\Exceptions\Request\FatalRequestException;
11
+ use Saloon\Exceptions\Request\RequestException;
12
+ use Saloon\Http\Response;
13
+
14
+ $products = [];
15
+ $failures = [];
16
+
17
+ $pool = $connector->pool(
18
+ requests: function () use ($ids): Generator {
19
+ foreach ($ids as $id) {
20
+ yield $id => new GetProductRequest($id);
21
+ }
22
+ },
23
+ concurrency: 10,
24
+ responseHandler: function (Response $response, int|string $key) use (&$products) {
25
+ $products[$key] = $response->dtoOrFail();
26
+ },
27
+ exceptionHandler: function (FatalRequestException|RequestException $exception, int|string $key) use (&$failures) {
28
+ $failures[$key] = $exception instanceof RequestException
29
+ ? $exception->getResponse()->status()
30
+ : $exception->getMessage();
31
+ },
32
+ );
33
+
34
+ $pool->send()->wait();
35
+ ```
36
+
37
+ `send()` returns a promise; call `wait()` before reading the results.
38
+
39
+ ## Requests
40
+
41
+ Provide any of the following as the first argument or with `setRequests()`:
42
+
43
+ - An array of `Request` or `PendingRequest` objects.
44
+ - A generator, to keep memory low for large batches.
45
+ - A closure or invokable class returning an array or generator, to run setup just before sending.
46
+
47
+ Keys from arrays or generators reach both handlers, so key by ID to match results. Responses complete in any order; never rely on input order.
48
+
49
+ ## Concurrency
50
+
51
+ The default is 5 requests in flight.
52
+ Use the `concurrency` argument or `$pool->setConcurrency(10)` to change it. Both also accept a callable.
53
+ Choose a value that respects the API's rate limits. A pool does not throttle requests over time.
54
+
55
+ ## Handlers
56
+
57
+ - `responseHandler` / `withResponseHandler()`: receives each **successful** `Response`.
58
+ - `exceptionHandler` / `withExceptionHandler()`: receives `RequestException` for 4xx/5xx responses and `FatalRequestException` for connection failures. HTTP failures always arrive here, even without `throw()` or `AlwaysThrowOnErrors`.
59
+
60
+ Each pool holds one handler of each kind.
61
+ For failure classification and custom exceptions, read [Handling failures](handling-failures.md).
62
+
63
+ ## Testing pools
64
+
65
+ Use `MockClient` with pools. Mocked HTTP failures reach the exception handler.
66
+ For offline setup and request assertions, read [Testing](testing.md).
67
+
68
+ ```php
69
+ $connector->withMockClient(new MockClient([
70
+ MockResponse::make(['id' => 1, 'name' => 'Widget', 'price_cents' => 999], 200),
71
+ MockResponse::make(['message' => 'Not found'], 404),
72
+ ]));
73
+ ```
@@ -0,0 +1,99 @@
1
+ # Connectors
2
+
3
+ A connector represents one external API. Create one connector per integration under `app/Http/Integrations/<Api>/`.
4
+
5
+ ## Minimal connector
6
+
7
+ Extend `Saloon\Http\Connector` and implement `resolveBaseUrl()`.
8
+
9
+ ```php
10
+ use Saloon\Http\Connector;
11
+
12
+ class InventoryConnector extends Connector
13
+ {
14
+ public function resolveBaseUrl(): string
15
+ {
16
+ return 'https://inventory.example.com/api/v1';
17
+ }
18
+ }
19
+ ```
20
+
21
+ With the Laravel plugin installed, `php artisan saloon:connector` scaffolds one.
22
+
23
+ ## Constructor arguments and authentication
24
+
25
+ Pass instance-specific values through the constructor. Put shared bearer authentication in `defaultAuth()`.
26
+
27
+ ```php
28
+ use Saloon\Contracts\Authenticator;
29
+ use Saloon\Http\Auth\TokenAuthenticator;
30
+ use Saloon\Http\Connector;
31
+
32
+ class InventoryConnector extends Connector
33
+ {
34
+ public function __construct(
35
+ protected readonly string $baseUrl,
36
+ protected readonly string $token,
37
+ ) {}
38
+
39
+ public function resolveBaseUrl(): string
40
+ {
41
+ return $this->baseUrl;
42
+ }
43
+
44
+ protected function defaultAuth(): ?Authenticator
45
+ {
46
+ return new TokenAuthenticator($this->token);
47
+ }
48
+ }
49
+
50
+ $connector = new InventoryConnector(config('services.inventory.url'), config('services.inventory.token'));
51
+ ```
52
+
53
+ `TokenAuthenticator` sends `Authorization: Bearer <token>`.
54
+ Load credentials from configuration or secrets. Never hard-code production credentials.
55
+
56
+ ## Default headers
57
+
58
+ Override `defaultHeaders()` for headers every request needs. Request headers are merged on top.
59
+
60
+ ```php
61
+ protected function defaultHeaders(): array
62
+ {
63
+ return [
64
+ 'Accept' => 'application/json',
65
+ 'Content-Type' => 'application/json',
66
+ ];
67
+ }
68
+ ```
69
+
70
+ Change headers on an instance with `$connector->headers()->add('X-Tenant', 'acme');`.
71
+
72
+ ## Timeouts
73
+
74
+ Defaults are a 10-second connection timeout and a 30-second request timeout.
75
+ Use `HasTimeout` on a connector for shared timeouts, or on a request for endpoint-specific timeouts.
76
+
77
+ ```php
78
+ use Saloon\Traits\Plugins\HasTimeout;
79
+
80
+ class InventoryConnector extends Connector
81
+ {
82
+ use HasTimeout;
83
+
84
+ protected int $connectTimeout = 60;
85
+
86
+ protected int $requestTimeout = 120;
87
+ }
88
+ ```
89
+
90
+ ## HTTP client config
91
+
92
+ The default sender is Guzzle. Pass Guzzle request options through `defaultConfig()` or `$connector->config()->add(...)`.
93
+
94
+ ```php
95
+ public function defaultConfig(): array
96
+ {
97
+ return ['verify' => true];
98
+ }
99
+ ```