@alessandroraffa/tangyr 0.21.5 → 1.0.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.
- package/README.md +97 -18
- package/dist/index.js +10210 -8268
- package/mappings/README.md +21 -0
- package/mappings/loss-severity.yaml +18 -1
- package/mappings/permission-modes.yaml +7 -0
- package/mappings/platform-paths.yaml +12 -0
- package/mappings/rule-modes.yaml +13 -0
- package/mappings/tool-names.yaml +12 -0
- package/package.json +1 -1
package/mappings/README.md
CHANGED
|
@@ -44,3 +44,24 @@ Each entry in `models` requires:
|
|
|
44
44
|
**Fail-closed validation**: a `custom_provider` declaration that omits `context_limit` or `output_limit` on any model entry, or that declares an empty `models` array, causes `loadMappings` to throw immediately with a descriptive error message beginning `custom-provider-limits-missing:`.
|
|
45
45
|
|
|
46
46
|
**`wire_api` semantics**: `"responses"` enables Codex `[model_providers.<id>]` TOML emission and selects `@ai-sdk/openai` as the npm package for OpenCode. When `wire_api` is absent or non-`"responses"`, Codex records a `provider-wire-protocol` loss and OpenCode uses `@ai-sdk/openai-compatible`.
|
|
47
|
+
|
|
48
|
+
## hook-events.yaml — the six-target hook contract
|
|
49
|
+
|
|
50
|
+
`hook-events.yaml` is the declarative hook contract: for each of the six targets it declares a **delivery mode** and one entry per source event. It is the file the hook compilers quote when a hook does not reach a target intact.
|
|
51
|
+
|
|
52
|
+
`source_events` is the set the canonical kit registers, plus `SessionStart`: `SessionStart`, `UserPromptSubmit`, `PreToolUse`, `PostToolUse`, `PostToolUseFailure`, `PreCompact`, `SubagentStart`, `SubagentStop`, `Stop`.
|
|
53
|
+
|
|
54
|
+
| Target | `delivery` | What the target receives |
|
|
55
|
+
| ------------- | ------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
56
|
+
| `claude-code` | `native-merge` | Every source event under its own name, merged into the target's settings file. |
|
|
57
|
+
| `copilot` | `mapped` | Every source event has a camelCase equivalent (`sessionStart`, `userPromptSubmitted`, `preToolUse`, `postToolUse`, `postToolUseFailure`, `preCompact`, `subagentStart`, `subagentStop`, `agentStop`). Copilot accepts Claude Code's nested `matcher`/`hooks` shape verbatim. Measured 2026-09-07 against Copilot CLI 1.0.83, whose `schemas/api.schema.json` (`HookType`) enumerates the events. |
|
|
58
|
+
| `codex` | `partial` | Five events map by name. `PostToolUseFailure` is a measured `drop` — Codex fires `PostToolUse` on a failed command instead — and `PreCompact`, `SubagentStart`, `SubagentStop` are `probe`: registered in the 2026-09-04 run but never exercised, so inconclusive rather than negative. `supported_platforms` records macOS/Linux only. |
|
|
59
|
+
| `cursor` | `native-versioned-object` | Every source event maps to a camelCase step in `hooks.json`; a step holds an **array** of commands, all of which run, so nothing is collapsed. Measured 2026-09-06 against cursor-agent 2026.09.02-c22c1a3. |
|
|
60
|
+
| `opencode` | `plugin-only` | Nothing. OpenCode exposes hooks only as plugin code, so every event is a `drop` with a `hook-as-plugin` loss and a warning. |
|
|
61
|
+
| `cline` | `plugin-only` | Nothing. Hooks exist only as `@cline/sdk` `AgentPlugin` code installed with `cline plugin install`, which does not apply to the extension target; every event drops the same way. |
|
|
62
|
+
|
|
63
|
+
A per-event entry is either a bare target name (claude-code's shorthand) or an object with `status` (`mapped` \| `drop` \| `probe`), an optional `target_event`, and — for `drop` and `probe` — a `severity` and a written `reason`. The `probe` status is deliberately distinct from `drop`: it records an unsettled measurement together with the experiment that would settle it.
|
|
64
|
+
|
|
65
|
+
**An unmapped event is reported, never silently dropped.** An event a kit registers that this file says nothing about is synthesized by the compilers as a fourth status, `unmapped` (see `HookEventRule` in `src/mappings/loader.ts`), and reported naming this file — so "we decided not to carry this" and "nobody has considered this event" stop producing the same output. Keeping the kit's registered events and this file in step is the purpose of that report.
|
|
66
|
+
|
|
67
|
+
**Scope limit.** This file maps event _names_ only. Translating the tool names inside a hook's `matcher` to a target's own vocabulary is done in code — `CURSOR_TOOL_NAMES` and `COPILOT_TOOL_NAMES` in `src/compiler/hooks.ts` — because those are measured target literals (`Bash` → `Shell`, `Bash` → `bash`), not the capability classes `tool-names.yaml` deals in. A matcher left untranslated produces the worst failure mode in this area: a valid, accepted hook file whose hooks never run.
|
|
@@ -1,6 +1,23 @@
|
|
|
1
1
|
version: 1
|
|
2
2
|
status: active
|
|
3
|
-
active_targets:
|
|
3
|
+
active_targets:
|
|
4
|
+
- claude-code
|
|
5
|
+
- copilot
|
|
6
|
+
- codex
|
|
7
|
+
- opencode
|
|
8
|
+
- cursor
|
|
9
|
+
- cline
|
|
10
|
+
|
|
11
|
+
notes:
|
|
12
|
+
- Widened from three targets to six on 2026-09-07. The entry-type vocabulary below is
|
|
13
|
+
emitted for every target, not only the original three - `hook-as-plugin` is recorded
|
|
14
|
+
exclusively for opencode and cline (adapters/opencode.ts, adapters/cline.ts),
|
|
15
|
+
`persona-not-representable` exclusively for cline, and `permission-coarsening` for
|
|
16
|
+
opencode and cursor (compiler/agents.ts). A three-target list described a file that was
|
|
17
|
+
already governing six.
|
|
18
|
+
- Severity is resolved per entry type, not per target - `resolveLossSeverity`
|
|
19
|
+
(compiler/loss-report.ts) keys only on the entry type, with an explicit severity from
|
|
20
|
+
hook-events.yaml overriding it.
|
|
4
21
|
|
|
5
22
|
entry_types:
|
|
6
23
|
command-as-skill: info
|
|
@@ -6,6 +6,13 @@ notes:
|
|
|
6
6
|
- No current agent file in projects/tangyr/agent-coding/agents/ declares `permissionMode`.
|
|
7
7
|
- This file exists because the target-state design expects permission intent to become an explicit canonical field later.
|
|
8
8
|
- Until that field exists in source artifacts, adapters must treat this file as reserved mapping policy rather than active input.
|
|
9
|
+
- active_targets stays at three because this file is reserved, not because coverage stops
|
|
10
|
+
at codex. No code path reads `canonical_permission_modes` at all (the loader exposes it;
|
|
11
|
+
nothing consumes it). Where `permissionMode` does appear on an agent, compiler/agents.ts
|
|
12
|
+
handles it directly for opencode (coarsened to an allow|ask|deny map) and cursor
|
|
13
|
+
(coarsened to a `readonly` boolean), recording `permission-coarsening` loss in both
|
|
14
|
+
cases - without consulting this file. Widening the list would imply an active
|
|
15
|
+
six-target policy that does not exist.
|
|
9
16
|
|
|
10
17
|
canonical_permission_modes:
|
|
11
18
|
read-only:
|
|
@@ -67,6 +67,18 @@ targets:
|
|
|
67
67
|
instructions: ~/.codex/AGENTS.md
|
|
68
68
|
agents: ~/.codex/agents
|
|
69
69
|
rules: ~/.codex/rules
|
|
70
|
+
# Not a typo, and not the odd one out by accident. Codex reads USER-scope
|
|
71
|
+
# skills from ~/.agents/skills, not from ~/.codex/skills alongside its
|
|
72
|
+
# other config. That is the only USER location OpenAI documents
|
|
73
|
+
# (https://learn.chatgpt.com/docs/build-skills: repo `.agents/skills`,
|
|
74
|
+
# user `$HOME/.agents/skills`, admin `/etc/codex/skills`), and it was
|
|
75
|
+
# measured on 2026-09-07 against Codex CLI 0.142.2 with
|
|
76
|
+
# `codex debug prompt-input`: marker skills planted in ~/.agents/skills
|
|
77
|
+
# and behind a wholesale relative symlink at that path both came back in
|
|
78
|
+
# the rendered <skills_instructions> block. ~/.codex/skills is read too,
|
|
79
|
+
# but it is a real directory Codex populates itself (it preinstalls its
|
|
80
|
+
# own skills under .system/), so it is not a wholesale-symlink target.
|
|
81
|
+
# Pinned by tests/unit/adapters/codex-skills-location.test.ts.
|
|
70
82
|
skills: ~/.agents/skills
|
|
71
83
|
hooks_shared_file: ~/.codex/hooks.json
|
|
72
84
|
hook_scripts: ~/.agents/hooks
|
package/mappings/rule-modes.yaml
CHANGED
|
@@ -5,6 +5,19 @@ active_targets: [claude-code, copilot, codex]
|
|
|
5
5
|
notes:
|
|
6
6
|
- Codex requires an explicit separation between behavioral guidance and execution-policy rules.
|
|
7
7
|
- This file gives the classification vocabulary for that split.
|
|
8
|
+
- >-
|
|
9
|
+
active_targets stays at three, but the `guidance` / `exec-policy` vocabulary is applied
|
|
10
|
+
beyond them by compiler/rules.ts, which reads the source `mode` field directly rather
|
|
11
|
+
than this table (no code path reads `canonical_rule_modes`). Measured behaviour of the
|
|
12
|
+
other three - opencode folds every rule into AGENTS.md as guidance and records
|
|
13
|
+
`rule-path-scoping`; cline emits a per-rule .md file and downgrades `exec-policy` to
|
|
14
|
+
guidance with a `rule-mode-downgrade` loss; cursor emits .mdc files keyed on
|
|
15
|
+
`alwaysApply`/`globs`/`description` and does not consult `mode` at all, so an
|
|
16
|
+
`exec-policy` rule reaches Cursor as ordinary guidance with no loss recorded.
|
|
17
|
+
- >-
|
|
18
|
+
Adding those three as columns is a behaviour-and-test change, not a documentation one.
|
|
19
|
+
tests/unit/mappings/declarations.test.ts asserts this file's active_targets length is
|
|
20
|
+
exactly 3. The cursor gap named above is the item worth filing separately.
|
|
8
21
|
|
|
9
22
|
canonical_rule_modes:
|
|
10
23
|
guidance:
|
package/mappings/tool-names.yaml
CHANGED
|
@@ -13,6 +13,18 @@ mapping_modes:
|
|
|
13
13
|
notes:
|
|
14
14
|
- The canonical tool names below are observed in current agent frontmatter.
|
|
15
15
|
- Copilot and Codex adapters should not assume that every canonical tool name has a stable one-to-one emitted literal.
|
|
16
|
+
- >-
|
|
17
|
+
active_targets stays at three deliberately. `canonical_tools` is read in exactly one
|
|
18
|
+
place - compiler/agents.ts (`mapToolsToCapabilities`, `deriveCodexSandbox`) - and only
|
|
19
|
+
for copilot capability names and codex sandbox derivation. The opencode, cursor and
|
|
20
|
+
cline agent compilers never consult it; they carry canonical tool names through
|
|
21
|
+
verbatim. Listing them here would claim a translation that does not happen.
|
|
22
|
+
- >-
|
|
23
|
+
This file translates a tool name to a capability class for agent frontmatter. It is not
|
|
24
|
+
the hook-matcher table. Rewriting a hook matcher to a target's literal tool spelling is
|
|
25
|
+
done by CURSOR_TOOL_NAMES and COPILOT_TOOL_NAMES in compiler/hooks.ts, which hold
|
|
26
|
+
measured target literals (`Bash` -> `Shell`, `Bash` -> `bash`) rather than capability
|
|
27
|
+
classes. See the "Scope limit" note under `hook-events.yaml` in mappings/README.md.
|
|
16
28
|
|
|
17
29
|
canonical_tools:
|
|
18
30
|
Read:
|