@journeykit/canon 0.6.0 → 0.8.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/dist/index.js +12 -2
- package/dist/skills/SKILL.src.md +46 -0
- package/dist/skills/reference/canon-artifact-ingest.md +72 -0
- package/dist/skills/reference/canon-authoring.md +155 -0
- package/dist/skills/reference/canon-context.md +137 -0
- package/dist/skills/reference/canon-fmt.md +43 -0
- package/dist/skills/reference/canon-gate.md +199 -0
- package/dist/skills/reference/canon-inventory.md +102 -0
- package/dist/skills/reference/canon-learn.md +245 -0
- package/dist/skills/reference/canon-plan-import.md +143 -0
- package/dist/skills/reference/canon-plugins.md +131 -0
- package/dist/skills/reference/canon-policy.md +119 -0
- package/dist/skills/reference/canon-report-dashboard.md +343 -0
- package/dist/skills/reference/canon-retrieve.md +123 -0
- package/dist/skills/reference/canon-session-ingest.md +214 -0
- package/dist/skills/reference/canon-storage.md +152 -0
- package/dist/skills/reference/canon-subject.md +161 -0
- package/dist/skills/reference/canon-vocab.md +115 -0
- package/dist/skills/scripts/canon-retrieve-pre-dispatch.sh +126 -0
- package/package.json +6 -4
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
#!/bin/sh
|
|
2
|
+
# canon-retrieve-pre-dispatch.sh — S8's generic pre-dispatch hook
|
|
3
|
+
# (`s8-retrieve-before-task`, design.md decision 4, tasks.md task 3.1):
|
|
4
|
+
# fires at a PreToolUse-equivalent point, generalized to any
|
|
5
|
+
# `task`-shaped dispatch (Claude Code's `Task` tool / Codex's
|
|
6
|
+
# equivalent subagent-dispatch tool call), mirroring a donor
|
|
7
|
+
# harness's `pre-edit-pattern-lookup.ts` fail-soft, advisory-only
|
|
8
|
+
# PreToolUse contract (design.md Context) — applied here to
|
|
9
|
+
# role-scoped strategy retrieval instead of edit-pattern lookup.
|
|
10
|
+
#
|
|
11
|
+
# WIRING (design decision 4 — reuses S5's install-hooks mechanism
|
|
12
|
+
# verbatim, invents no second convention): install the standard
|
|
13
|
+
# `{matcher, hooks: [{type: "command", command, timeout}]}` entry via
|
|
14
|
+
# the ALREADY-GENERIC `canon gate install-hooks` (S5, `s5-trust-spine-
|
|
15
|
+
# gate`) — this script adds NO new installer code:
|
|
16
|
+
#
|
|
17
|
+
# canon gate install-hooks --repo . --event PreToolUse \
|
|
18
|
+
# --matcher Task --command "sh /path/to/pre-dispatch.sh" \
|
|
19
|
+
# --timeout 15
|
|
20
|
+
#
|
|
21
|
+
# Place this file wherever your repo keeps materialized hook scripts
|
|
22
|
+
# (e.g. `.claude/hooks/canon-retrieve-pre-dispatch.sh`, following the
|
|
23
|
+
# manual-placement convention for materialized hook scripts)
|
|
24
|
+
# and point `--command` at that path — same manual-
|
|
25
|
+
# placement discipline canon-gate's own `PRE_COMMIT_SCRIPT` documents
|
|
26
|
+
# ("install it directly as `.git/hooks/pre-commit`, or invoke it from
|
|
27
|
+
# a lefthook/husky `run:` line").
|
|
28
|
+
#
|
|
29
|
+
# FAIL-SOFT, ADVISORY-ONLY — this script NEVER blocks the dispatch and
|
|
30
|
+
# NEVER emits a `permissionDecision`; it only ever adds
|
|
31
|
+
# `additionalContext` (Claude Code's `PreToolUse` hook output
|
|
32
|
+
# contract) or stays silent. Every one of the following degrades to a
|
|
33
|
+
# SILENT no-op, never a nonzero exit:
|
|
34
|
+
# - `canon` (or `jq`) not on PATH.
|
|
35
|
+
# - the dispatched tool is not task-shaped (`tool_name != "Task"`) —
|
|
36
|
+
# re-checked here even though the install recipe above already
|
|
37
|
+
# scopes the hook via `--matcher Task`, so this script stays a
|
|
38
|
+
# safe no-op if installed with a broader/no matcher.
|
|
39
|
+
# - no role derivable from the tool input, or empty/malformed stdin.
|
|
40
|
+
# - `canon retrieve` returns empty guidance — it is ALREADY
|
|
41
|
+
# fail-soft (S8Core's `retrieve_guidance` never errors; canon-
|
|
42
|
+
# cli's own CLI boundary never exits nonzero for a store outage,
|
|
43
|
+
# `crates/canon-cli/src/retrieve.rs`'s own module doc) — this
|
|
44
|
+
# script never adds a SECOND failure mode on top of that.
|
|
45
|
+
#
|
|
46
|
+
# ROLE/REGIME DERIVATION (an explicit design.md Open Question this
|
|
47
|
+
# script resolves, pinned here): Claude Code's `Task` tool call
|
|
48
|
+
# carries a `subagent_type` field naming which specialist role is
|
|
49
|
+
# about to run — read directly as `--role` (kebab-cased). `--regime`'s
|
|
50
|
+
# `<role>/<repo>/<area>/<hash>` is NOT fully recoverable from a bare
|
|
51
|
+
# tool-call payload (S6's `area`/`hash` taxonomy is repo-specific, not
|
|
52
|
+
# something a generic script can infer) — this ships a CONSERVATIVE
|
|
53
|
+
# default (`area=general`, a stable hash of that area) a repo is
|
|
54
|
+
# expected to override once it adopts a real regime taxonomy:
|
|
55
|
+
# - `CANON_RETRIEVE_ROLE` overrides the auto-derived role.
|
|
56
|
+
# - `CANON_RETRIEVE_AREA` overrides the default `general` area.
|
|
57
|
+
# - `CANON_RETRIEVE_HASH` overrides the derived hash segment.
|
|
58
|
+
# - `CANON_RETRIEVE_REGIME` overrides the whole assembled
|
|
59
|
+
# `regime_key`, bypassing all of the above.
|
|
60
|
+
set -eu
|
|
61
|
+
|
|
62
|
+
command -v canon >/dev/null 2>&1 || exit 0
|
|
63
|
+
command -v jq >/dev/null 2>&1 || exit 0
|
|
64
|
+
|
|
65
|
+
INPUT="$(cat 2>/dev/null || true)"
|
|
66
|
+
[ -n "$INPUT" ] || exit 0
|
|
67
|
+
|
|
68
|
+
TOOL_NAME="$(printf '%s' "$INPUT" | jq -r '.tool_name // empty' 2>/dev/null || true)"
|
|
69
|
+
[ "$TOOL_NAME" = "Task" ] || exit 0
|
|
70
|
+
|
|
71
|
+
# `slugify` is used ONLY for the ROLE segment: `RoleId`'s grammar is
|
|
72
|
+
# strict kebab (`[a-z0-9]+(-[a-z0-9]+)*`), and a kebab string is a
|
|
73
|
+
# fixed point of `regime_key`'s own segment canonicalizer, so the
|
|
74
|
+
# derived `--role` still equals the assembled regime_key's leading
|
|
75
|
+
# segment. The repo/area segments are NOT slugified here — they are
|
|
76
|
+
# canonicalized by `canon regime-key` below (the write-path serializer).
|
|
77
|
+
slugify() {
|
|
78
|
+
printf '%s' "$1" | tr '[:upper:]' '[:lower:]' | tr -c 'a-z0-9' '-' | sed -E 's/-+/-/g; s/^-//; s/-$//'
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
ROLE="${CANON_RETRIEVE_ROLE:-}"
|
|
82
|
+
if [ -z "$ROLE" ]; then
|
|
83
|
+
ROLE="$(printf '%s' "$INPUT" | jq -r '.tool_input.subagent_type // empty' 2>/dev/null || true)"
|
|
84
|
+
fi
|
|
85
|
+
ROLE="$(slugify "$ROLE")"
|
|
86
|
+
[ -n "$ROLE" ] || exit 0
|
|
87
|
+
|
|
88
|
+
REGIME="${CANON_RETRIEVE_REGIME:-}"
|
|
89
|
+
if [ -z "$REGIME" ]; then
|
|
90
|
+
REPO_ROOT="$(git rev-parse --show-toplevel 2>/dev/null || pwd)"
|
|
91
|
+
REPO_RAW="$(basename "$REPO_ROOT")"
|
|
92
|
+
AREA_RAW="${CANON_RETRIEVE_AREA:-general}"
|
|
93
|
+
HASH="${CANON_RETRIEVE_HASH:-}"
|
|
94
|
+
if [ -z "$HASH" ]; then
|
|
95
|
+
HASH="$(printf '%s' "$AREA_RAW" | sha256sum 2>/dev/null | cut -c1-12)"
|
|
96
|
+
[ -n "$HASH" ] || HASH="$(printf '%s' "$AREA_RAW" | shasum -a 256 2>/dev/null | cut -c1-12)"
|
|
97
|
+
fi
|
|
98
|
+
[ -n "$HASH" ] || exit 0
|
|
99
|
+
# Assemble the regime_key through canon's OWN serializer (`canon
|
|
100
|
+
# regime-key` -> `canon_model::ids::regime_key`), the identical
|
|
101
|
+
# normalizer the S4/S6/S14 WRITE path uses — never a second shell
|
|
102
|
+
# derivation. A prior local `slugify` of the repo segment mapped a
|
|
103
|
+
# written `my_repo` to a queried `my-repo`, so `retrieve_guidance`
|
|
104
|
+
# fail-softed to empty and silently missed the namespace. `--role`
|
|
105
|
+
# is the already-kebab ROLE (a fixed point of that canonicalizer, so
|
|
106
|
+
# it still equals the assembled key's leading segment). Malformed
|
|
107
|
+
# segments make `canon regime-key` exit nonzero -> `|| true` -> empty
|
|
108
|
+
# REGIME -> the silent no-op just below.
|
|
109
|
+
REGIME="$(canon regime-key --role "$ROLE" --repo "$REPO_RAW" --area "$AREA_RAW" --hash "$HASH" 2>/dev/null || true)"
|
|
110
|
+
[ -n "$REGIME" ] || exit 0
|
|
111
|
+
fi
|
|
112
|
+
|
|
113
|
+
GUIDANCE_JSON="$(canon retrieve --role "$ROLE" --regime "$REGIME" --json 2>/dev/null || true)"
|
|
114
|
+
[ -n "$GUIDANCE_JSON" ] || exit 0
|
|
115
|
+
|
|
116
|
+
COUNT="$(printf '%s' "$GUIDANCE_JSON" | jq 'length' 2>/dev/null || echo 0)"
|
|
117
|
+
[ "$COUNT" -gt 0 ] 2>/dev/null || exit 0
|
|
118
|
+
|
|
119
|
+
CONTEXT="$(printf '%s' "$GUIDANCE_JSON" | jq -r --arg role "$ROLE" '
|
|
120
|
+
(["[canon-retrieve] guidance for role " + $role + ":"]
|
|
121
|
+
+ (map("- " + .title + ": " + .content))) | join("\n")
|
|
122
|
+
' 2>/dev/null || true)"
|
|
123
|
+
[ -n "$CONTEXT" ] || exit 0
|
|
124
|
+
|
|
125
|
+
jq -n --arg ctx "$CONTEXT" '{hookSpecificOutput: {hookEventName: "PreToolUse", additionalContext: $ctx}}'
|
|
126
|
+
exit 0
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@journeykit/canon",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.0",
|
|
4
4
|
"description": "canon — harness knowledge substrate. JS launcher: platform detection + native binary resolution.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -22,14 +22,16 @@
|
|
|
22
22
|
"directory": "packages/cli"
|
|
23
23
|
},
|
|
24
24
|
"scripts": {
|
|
25
|
-
"
|
|
25
|
+
"bundle-skills": "bun run scripts/bundle-skills.ts",
|
|
26
|
+
"build": "bun run bundle-skills && bun build src/index.ts --outdir dist --target node --format esm",
|
|
26
27
|
"dev": "bun src/index.ts",
|
|
27
28
|
"start": "node dist/index.js"
|
|
28
29
|
},
|
|
29
30
|
"dependencies": {},
|
|
30
31
|
"optionalDependencies": {
|
|
31
|
-
"@journeykit/canon-core-darwin-arm64": "0.
|
|
32
|
-
"@journeykit/canon-core-linux-x64": "0.
|
|
32
|
+
"@journeykit/canon-core-darwin-arm64": "0.8.0",
|
|
33
|
+
"@journeykit/canon-core-linux-x64": "0.8.0",
|
|
34
|
+
"@journeykit/canon-core-win32-x64": "0.8.0"
|
|
33
35
|
},
|
|
34
36
|
"devDependencies": {
|
|
35
37
|
"@types/node": "^20.0.0",
|