@linchpinagency/skills 0.1.8 → 0.1.9

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.
package/README.md CHANGED
@@ -12,7 +12,7 @@ GitHub Copilot, and other compatible coding agents.
12
12
  ![Zero dependencies](https://img.shields.io/badge/Dependencies-0-brightgreen)
13
13
 
14
14
  <!-- x-release-please-start-version -->
15
- ### Latest release: 0.1.8
15
+ ### Latest release: 0.1.9
16
16
  <!-- x-release-please-end -->
17
17
 
18
18
  | Release | Skill standard | Install |
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@linchpinagency/skills",
3
- "version": "0.1.8",
3
+ "version": "0.1.9",
4
4
  "description": "Linchpin's library of reusable AI agent skills for WordPress projects.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -102,9 +102,11 @@ need a commit or a branch behind it.
102
102
  `clickup_create_task` requires a `list_id` and `name`. Resolve the list with the cheapest
103
103
  path that works:
104
104
 
105
- 1. **Use a known default if the project has one.** If the project pins a default list
106
- (see *Reducing friction*), confirm it in one line ("Create in *Linchpin linchpin.com
107
- Development*?") rather than making the user navigate.
105
+ 1. **Read `.clickup.json` first.** If the repo root has one, it pins the Space, a default
106
+ list, and often a routing map from source directory list confirm the destination in
107
+ one line ("Create in *Mantle › Modules › Security*?") rather than making the user
108
+ navigate. A ClickUp section in the project's `CLAUDE.md`/`AGENTS.md` counts too. Schema
109
+ and lookup order: [`references/clickup-json.md`](references/clickup-json.md).
108
110
  2. **Otherwise present a picker** built from `clickup_get_workspace_hierarchy`:
109
111
  - Call it with `max_depth: 2` **scoped to the likely Space** (pass `space_ids`) so you
110
112
  return Folders + Lists for one space, not the whole workspace.
@@ -202,10 +204,13 @@ Work happens on a dedicated branch opened as a PR against the base branch (usual
202
204
 
203
205
  ## Reducing friction
204
206
 
205
- - **Pin a default list per project.** Record the project's usual Space/List (id + path) in
206
- the project's `CLAUDE.md` or a small `.clickup.json`, so creation becomes a one-line
207
- confirm instead of navigation — e.g. `<Space> <Project> › Development` with its
208
- `list_id`. The id belongs in that project's repo, not in this shared library.
207
+ - **Pin the routing per project in `.clickup.json`.** A small file at the repo root holding
208
+ the Space, a default list, and (where the board mirrors the code) a directory → list map,
209
+ so creation becomes a one-line confirm instead of navigation. Schema, worked example, and
210
+ packaging notes: [`references/clickup-json.md`](references/clickup-json.md). The ids belong
211
+ in that project's repo, not in this shared library.
212
+ - **Write the file when you had to look it up.** Resolving a list the slow way is the moment
213
+ to offer to pin it — otherwise the next agent pays the same cost.
209
214
  - **Remember the last-used list** within a session and reuse it.
210
215
  - **Infer the Space from the repo** to scope every search and hierarchy call.
211
216
  - **Batch the questions**: when you must ask, resolve task-vs-NO-TASK and (if creating) the
@@ -0,0 +1,125 @@
1
+ # `.clickup.json` — per-project ClickUp routing
2
+
3
+ A small file at a project's repo root that pins **where this project's tasks live**, so
4
+ creating one is a single confirmation instead of a workspace-hierarchy crawl across dozens of
5
+ spaces.
6
+
7
+ The **convention** is portable and lives here. The **IDs** are project-specific and live in
8
+ that project's repo — never in this library.
9
+
10
+ ## Why it exists
11
+
12
+ Without it, every "create a task for X" starts the same way: call
13
+ `clickup_get_workspace_hierarchy`, guess the Space from the repo name, page through folders,
14
+ and rediscover the same handful of list IDs that were found last week. That's slow, it burns
15
+ context, and it produces inconsistent placement when the guess is wrong.
16
+
17
+ With it, the flow is: read the file, confirm the list in one line, create.
18
+
19
+ ## Where to look
20
+
21
+ Check in this order, and stop at the first hit:
22
+
23
+ 1. `.clickup.json` at the repo root
24
+ 2. A ClickUp section in the project's `CLAUDE.md` / `AGENTS.md`
25
+ 3. Nothing pinned → fall back to the hierarchy lookup in the main skill, and **offer to write
26
+ `.clickup.json`** once the list has been resolved, so the next agent doesn't repeat the work
27
+
28
+ ## Schema
29
+
30
+ Every field is optional except `space` and `defaultList` — a two-key file is already useful.
31
+
32
+ | Key | Type | Purpose |
33
+ | --- | --- | --- |
34
+ | `space` | object | `id`, `name`, and `customIdPrefix` (e.g. `MANTLE` — the prefix on custom IDs, used to sanity-check a key before putting it in a commit scope) |
35
+ | `defaultList` | object | `id`, `name`, `path`, and a `use` string saying what belongs there. The fallback for anything that doesn't route elsewhere |
36
+ | `lists` | object | Human list name → list id. Flat map; use `›` in the name for nesting when two lists share a name |
37
+ | `folders` | object | Human folder name → folder id. Only needed when a tool call wants a folder rather than a list |
38
+ | `moduleRouting` | object | Source directory → list **name** (a key in `lists`). For repos whose board mirrors their code structure |
39
+ | `unmapped` | object | Deliberate code↔board mismatches, recorded so they read as intentional rather than as failed lookups |
40
+
41
+ Two rules that matter more than the shape:
42
+
43
+ - **IDs are the contract; names are for humans.** ClickUp list names get renamed freely and
44
+ the id survives it. Route on the id, show the name.
45
+ - **`moduleRouting` points at names, not ids** — so a renamed list is a one-line fix in
46
+ `lists` rather than a find-and-replace through the routing map.
47
+
48
+ ## Example
49
+
50
+ Trimmed from a real plugin repo whose ClickUp board has one list per code module:
51
+
52
+ ```json
53
+ {
54
+ "$comment": "ClickUp routing for this repo. IDs are workspace-stable; names are for humans.",
55
+ "space": {
56
+ "id": "90140515528",
57
+ "name": "Mantle",
58
+ "customIdPrefix": "MANTLE"
59
+ },
60
+ "defaultList": {
61
+ "id": "901401607739",
62
+ "name": "Product Roadmap",
63
+ "path": "Mantle › Product Roadmap",
64
+ "use": "Cross-cutting work, new modules, and anything that doesn't map to a single existing module."
65
+ },
66
+ "lists": {
67
+ "Product Roadmap": "901401607739",
68
+ "Housekeeping": "901414301271",
69
+ "Optimizations": "901413938412",
70
+ "Security": "901413938417",
71
+ "Declutter": "901413954051"
72
+ },
73
+ "folders": {
74
+ "Modules": "90147467026"
75
+ },
76
+ "moduleRouting": {
77
+ "$comment": "includes/Modules/<Dir> → list name. Fall back to defaultList.",
78
+ "Optimizations": "Optimizations",
79
+ "Security": "Security"
80
+ },
81
+ "unmapped": {
82
+ "modulesWithoutList": [
83
+ "Maintenance — no dedicated list; use Product Roadmap"
84
+ ],
85
+ "listsWithoutModule": [
86
+ "Declutter — intended home for admin-menu tidying; no module exists yet"
87
+ ]
88
+ }
89
+ }
90
+ ```
91
+
92
+ `$comment` keys are ignored by every JSON parser and are the only way to annotate JSON —
93
+ use them, since this file is read by people as often as by agents.
94
+
95
+ ## `unmapped` is the part people skip
96
+
97
+ A board and a codebase drift apart. A list gets created for work that was never built; a
98
+ module ships without anyone adding a list for it. An agent that finds no route for
99
+ `includes/Modules/Maintenance` can't tell "nobody added it" from "I looked in the wrong
100
+ place", so it either asks a pointless question or files the task somewhere wrong.
101
+
102
+ Recording the mismatch converts a lookup failure into a documented decision. Keep it honest
103
+ and prune it when the gap closes.
104
+
105
+ ## Packaging
106
+
107
+ Projects that build a distributable — WordPress plugins and themes especially — should
108
+ exclude the file from the build:
109
+
110
+ - `.distignore` for `wp dist-archive` / plugin zips
111
+ - `.npmignore` or a `files` allowlist for npm packages
112
+
113
+ It's dev-time metadata with no runtime meaning. It contains no secrets — workspace, folder,
114
+ and list IDs are not credentials, and the ClickUp API still requires a token — so it can be
115
+ committed to a private repo without concern. Treat it the same as any other project config
116
+ in a public repo: harmless, but pointless to publish.
117
+
118
+ ## Keeping it current
119
+
120
+ - A renamed list keeps its id — nothing to do.
121
+ - A **new** list, or one that gets retired, needs the map updated. Cheapest moment is when
122
+ you notice the drift while creating a task; fix it in the same PR.
123
+ - If a lookup by the pinned id fails, the list was deleted or moved out of the space. Re-run
124
+ the hierarchy lookup, correct the file, and say so — don't silently fall back to the
125
+ default list, or tasks quietly pile up in the wrong place.