|
| 1 | +--- |
| 2 | +name: init-api-mapping |
| 3 | +description: Create an initial `api_mapping.toml` for a new IOTA Trust Framework product, then delegate to the `update-api-mapping` skill to populate it with all currently public Move/Rust/WASM entities. |
| 4 | +--- |
| 5 | + |
| 6 | +# Bootstrap a product's `api_mapping.toml` |
| 7 | + |
| 8 | +## Purpose |
| 9 | + |
| 10 | +A new IOTA Trust Framework product (or a product whose Move/Rust/WASM code |
| 11 | +already exists but has never had an API mapping committed) needs a starting |
| 12 | +`api_mapping.toml` placed in the Move package root. This skill scaffolds that |
| 13 | +file with the standard header and conventions, then hands off to the |
| 14 | +`update-api-mapping` skill to fill in every section by diffing against the |
| 15 | +empty tree — i.e. treating *every* current public Move/Rust/WASM entity as |
| 16 | +"newly added". |
| 17 | + |
| 18 | +The actual extraction, naming, and reconciliation logic lives in |
| 19 | +`update-api-mapping`. This skill exists only to: |
| 20 | + |
| 21 | +1. Establish the file at the right path with the right header. |
| 22 | +2. Invoke `update-api-mapping` with the right inputs so the bootstrap pass |
| 23 | + reconciles "nothing" against "everything currently in `HEAD`". |
| 24 | +3. Hand a populated, verified TOML back to the user. |
| 25 | + |
| 26 | +## When to invoke this skill |
| 27 | + |
| 28 | +- The user says "create an api_mapping for `<product>`", "bootstrap the api |
| 29 | + mapping", "we need an `api_mapping.toml` for the new `<product>` crate", |
| 30 | + or similar. |
| 31 | +- A product directory has Move/Rust/WASM code but no `api_mapping.toml` |
| 32 | + alongside the Move package. |
| 33 | +- The user explicitly invokes `/init-api-mapping`. |
| 34 | + |
| 35 | +Do **not** invoke this skill when an `api_mapping.toml` already exists at |
| 36 | +the target location — use `update-api-mapping` instead. If one exists and |
| 37 | +the user really wants to recreate it, confirm first that they want the |
| 38 | +existing file overwritten before proceeding. |
| 39 | + |
| 40 | +## Required inputs |
| 41 | + |
| 42 | +The caller (user or invoking agent) **must** provide all of the following. |
| 43 | +If any are missing, try to guess them from the user's current working |
| 44 | +directory or from the product name they mentioned, and present the guesses |
| 45 | +back for validation. Do not pick defaults silently. |
| 46 | + |
| 47 | +1. **`rust-crate-path`** — path to the `src` folder of the product's Rust |
| 48 | + implementation (e.g. `audit-trail-rs/src`, `notarization-rs/src`). |
| 49 | +2. **`wasm-bindings-path`** — path to the `src` folder of the product's |
| 50 | + WASM bindings (typically `bindings/wasm/<product-name>_wasm/src`). |
| 51 | +3. **`move-sc-path`** — path to the `sources` folder of the product's Move |
| 52 | + smart contracts (e.g. `audit-trail-move/sources`). |
| 53 | + |
| 54 | +Try to guess the correct values for the `rust-crate-path`, `wasm-bindings-path` |
| 55 | +and `move-sc-path` depending on the folder the user currently works in or if the |
| 56 | +user mentions the product name. Present the input argument values to the user for |
| 57 | +validation. |
| 58 | + |
| 59 | +### Derived values |
| 60 | + |
| 61 | +- **`api-mapping-path`** — `<move-sc-path>/../api_mapping.toml`. This is |
| 62 | + where the new file will be created. |
| 63 | +- **`product`** — the product identifier, derived from the basename of |
| 64 | + the Move package directory (parent of `move-sc-path`) with any trailing |
| 65 | + `-move` stripped and `-` replaced by `_`. Examples: |
| 66 | + - `audit-trail-move/sources` → `audit_trail` |
| 67 | + - `notarization-move/sources` → `notarization` |
| 68 | +- **`product-display`** — a human-readable form for the file's title |
| 69 | + comment (e.g. `Audit Trail`, `Notarization`). Derive by title-casing |
| 70 | + the package basename with `-move` stripped and `-` → space; confirm |
| 71 | + with the user if uncertain. |
| 72 | + |
| 73 | +## Workflow |
| 74 | + |
| 75 | +1. **Validate inputs.** Confirm: |
| 76 | + - All three paths exist. |
| 77 | + - `<move-sc-path>` actually contains `*.move` files. |
| 78 | + - `<api-mapping-path>` does **not** already exist. If it does, stop |
| 79 | + and tell the user to use `update-api-mapping` instead (or ask |
| 80 | + whether they want to overwrite — never overwrite silently). |
| 81 | + |
| 82 | +2. **Identify the Move package's "main" file.** List `*.move` files in |
| 83 | + `<move-sc-path>` and identify the one whose basename matches the |
| 84 | + product identifier (with any underscore/dash normalisation needed). |
| 85 | + That file's entities will go under the `<product>.main.*` keys; all |
| 86 | + others use their bare filename. If no file matches the product name, |
| 87 | + ask the user which file should be considered "main" (or whether the |
| 88 | + convention should be relaxed for this product). |
| 89 | + |
| 90 | +3. **Create the scaffold TOML.** Write `<api-mapping-path>` with this |
| 91 | + exact header and one banner per Move source file (in source order), |
| 92 | + leaving each module body empty for the next step to populate: |
| 93 | + |
| 94 | + ```toml |
| 95 | + # <product-display> API Mapping |
| 96 | + # |
| 97 | + # Maps each public Move function or struct in the `<move-sc-path>/` |
| 98 | + # modules to the related Rust entities in `<rust-crate-path>/` and |
| 99 | + # WASM/TS entities in `<wasm-bindings-path>/`. |
| 100 | + # |
| 101 | + # TOML section keys are formed as `<product>.<module>.<entity>`: |
| 102 | + # - `<product>` — the product identifier, derived from the basename |
| 103 | + # of the Move package directory with any trailing `-move` stripped |
| 104 | + # and `-` replaced by `_`. For this file: `<product>`. |
| 105 | + # - `<module>` — `main` for the Move source file whose basename |
| 106 | + # matches the product name (`<product>.move` → `main`); for any |
| 107 | + # other Move source file, the bare filename without extension. |
| 108 | + # - `<entity>` — the function name or struct/enum/const name in |
| 109 | + # that module. |
| 110 | + # |
| 111 | + # `rust` and `wasm` arrays list the Rust- resp. WASM-level functions, |
| 112 | + # methods, and types that wrap, build, or otherwise correspond to the |
| 113 | + # Move entity. Entry conventions: |
| 114 | + # - `Type::method` — an inherent method on `Type` |
| 115 | + # - `Type::Variant` — an enum variant |
| 116 | + # - `Type` — a plain type/struct/enum |
| 117 | + # - `Type.field` — a struct field |
| 118 | + # - `module::function` — a free function |
| 119 | + # |
| 120 | + # An entry of `[]` means there is intentionally no counterpart on |
| 121 | + # that side. |
| 122 | + # |
| 123 | + # This mapping is intended for automatic comparison of function and |
| 124 | + # struct documentation across the three implementation layers, and is |
| 125 | + # maintained via the `update-api-mapping` and `sync-product-docs` |
| 126 | + # skills under `.claude/skills/`. |
| 127 | + |
| 128 | + # ============================================================================= |
| 129 | + # Module: <product>::main (<move-sc-path>/<product>.move) |
| 130 | + # ============================================================================= |
| 131 | + |
| 132 | + # ============================================================================= |
| 133 | + # Module: <product>::<other_module> (<move-sc-path>/<other_module>.move) |
| 134 | + # ============================================================================= |
| 135 | + ``` |
| 136 | + |
| 137 | + Substitute the placeholders (`<product>`, `<product-display>`, |
| 138 | + `<move-sc-path>`, `<rust-crate-path>`, `<wasm-bindings-path>`) with |
| 139 | + the actual values. Emit one banner per `.move` file, in the order |
| 140 | + they appear in `<move-sc-path>` (alphabetical, with the `main` file |
| 141 | + first). |
| 142 | + |
| 143 | +4. **Bootstrap the contents via `update-api-mapping`.** Invoke the |
| 144 | + `update-api-mapping` skill with: |
| 145 | + |
| 146 | + - `rust-crate-path`, `wasm-bindings-path`, `move-sc-path` — the same |
| 147 | + values supplied to this skill. |
| 148 | + - **base revision** = the git empty-tree SHA |
| 149 | + `4b825dc642cb6eb9a060e54bf8d69288fbee4904`. Diffing against this |
| 150 | + SHA causes every public Move/Rust/WASM entity in the working tree |
| 151 | + to be reported as "added", which is exactly what bootstrapping |
| 152 | + needs. |
| 153 | + |
| 154 | + `update-api-mapping` will then: |
| 155 | + |
| 156 | + - Detect every `public fun`, `public struct`, `public enum` in the |
| 157 | + Move sources and propose a section per entity. |
| 158 | + - Match Rust/WASM symbols using its standard naming heuristics. |
| 159 | + - Write all sections to the freshly scaffolded TOML. |
| 160 | + |
| 161 | + Follow `update-api-mapping`'s normal confirmation flow. Because this |
| 162 | + is a bootstrap, expect a large change set — group the proposal by |
| 163 | + Move module so the user can review one file at a time. |
| 164 | + |
| 165 | +5. **Verify the result.** After `update-api-mapping` finishes: |
| 166 | + |
| 167 | + - Re-read `<api-mapping-path>` and confirm it parses. |
| 168 | + - Confirm every Move public entity in `<move-sc-path>` has a |
| 169 | + corresponding TOML section. If any are missing, list them and ask |
| 170 | + the user whether to add them with `[]` arrays or pick up after |
| 171 | + manual investigation. |
| 172 | + - Confirm every banner has at least one section under it (or note |
| 173 | + that the module is intentionally empty). |
| 174 | + - Report a summary: number of sections created, number with |
| 175 | + non-empty `rust`/`wasm` arrays, number left as `[]` for the user |
| 176 | + to fill in, and any items that needed user input during the |
| 177 | + bootstrap. |
| 178 | + |
| 179 | +## Operating rules |
| 180 | + |
| 181 | +- **Don't duplicate `update-api-mapping`'s logic.** This skill scaffolds |
| 182 | + and delegates; it must not extract symbols, propose Rust/WASM matches, |
| 183 | + or edit individual sections itself. If `update-api-mapping`'s behavior |
| 184 | + needs to change, change *that* skill, not this one. |
| 185 | +- **One product per invocation.** Bootstrap one mapping at a time so |
| 186 | + the bootstrap diff is reviewable. |
| 187 | +- **Never overwrite an existing TOML silently.** Stop and ask if |
| 188 | + `<api-mapping-path>` already exists. |
| 189 | +- **Don't invent Move source files.** Only create banners for `*.move` |
| 190 | + files actually present in `<move-sc-path>`. |
| 191 | +- **Preserve the empty-tree contract.** The hand-off to |
| 192 | + `update-api-mapping` always uses the empty-tree SHA as the base. |
| 193 | + Don't substitute `origin/main` or similar — those would compare |
| 194 | + against an unrelated history and miss entities. |
| 195 | + |
| 196 | +## Example invocation |
| 197 | + |
| 198 | +User: |
| 199 | + |
| 200 | +> `/init-api-mapping` |
| 201 | +> `rust-crate-path=identity-rs/src` |
| 202 | +> `wasm-bindings-path=bindings/wasm/identity_wasm/src` |
| 203 | +> `move-sc-path=identity-move/sources` |
| 204 | +
|
| 205 | +Expected behavior: |
| 206 | + |
| 207 | +1. Confirm none of the three paths is missing and that |
| 208 | + `identity-move/api_mapping.toml` does not yet exist. |
| 209 | +2. Inspect `identity-move/sources/` — find e.g. `identity.move`, |
| 210 | + `credentials.move`, `revocation.move`. Identify `identity.move` as |
| 211 | + the "main" file (matches product name `identity`). |
| 212 | +3. Write the scaffold TOML at `identity-move/api_mapping.toml` with |
| 213 | + header and three module banners (`identity::main`, |
| 214 | + `identity::credentials`, `identity::revocation`). |
| 215 | +4. Invoke `update-api-mapping` with base |
| 216 | + `4b825dc642cb6eb9a060e54bf8d69288fbee4904`. It detects every |
| 217 | + `public fun`/`public struct`/`public enum` in those three Move |
| 218 | + files, proposes Rust and WASM counterparts via its naming |
| 219 | + heuristics, and (after user confirmation) fills the file in. |
| 220 | +5. Re-read the resulting TOML, summarise: e.g. "47 sections created; |
| 221 | + 42 have non-empty `rust` arrays; 5 left as `[]` for review: |
| 222 | + `identity.main.rotate_keys`, …". |
0 commit comments