@open-agent-toolkit/cli 0.2.30 → 0.2.32
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/assets/bundle-metadata.json +1 -1
- package/assets/docs/cli-utilities/configuration.md +41 -0
- package/assets/docs/contributing/code.md +19 -7
- package/assets/docs/contributing/explainer-kit-verification.md +9 -1
- package/assets/docs/contributing/skills.md +9 -0
- package/assets/docs/provider-sync/commands.md +15 -10
- package/assets/docs/provider-sync/manifest-and-drift.md +23 -0
- package/assets/docs/provider-sync/providers.md +8 -2
- package/assets/docs/provider-sync/scope-and-surface.md +3 -1
- package/assets/docs/reference/file-locations.md +5 -0
- package/assets/docs/reference/troubleshooting.md +18 -0
- package/assets/docs/workflows/skills/explainer-kit-providers.md +16 -5
- package/assets/docs/workflows/skills/explainer-kit.md +98 -38
- package/assets/public-package-versions.json +4 -4
- package/assets/skills/create-agnostic-skill/references/docs/skills-guide.md +34 -22
- package/assets/skills/explainer-kit/SKILL.md +33 -8
- package/assets/skills/explainer-kit/briefs/project-recap.md +25 -7
- package/assets/skills/explainer-kit/recipes/project-recap.v2.json +72 -0
- package/assets/skills/explainer-kit/references/contracts.md +49 -17
- package/assets/skills/explainer-kit/references/destination-contract.md +141 -25
- package/assets/skills/explainer-kit/references/extension-contract.md +19 -10
- package/assets/skills/explainer-kit/references/visual-authoring.md +24 -0
- package/assets/skills/explainer-kit/references/visual-review.md +19 -5
- package/assets/skills/explainer-kit/schemas/author-request.v3.schema.json +241 -0
- package/assets/skills/explainer-kit/schemas/publish-receipt.v2.schema.json +215 -0
- package/assets/skills/explainer-kit/schemas/publish-request.v2.schema.json +34 -0
- package/assets/skills/explainer-kit/schemas/run-request.schema.json +4 -1
- package/assets/skills/explainer-kit/schemas/terminal-evidence.v1.schema.json +81 -0
- package/assets/skills/explainer-kit/schemas/visual-review-evidence.v1.schema.json +66 -0
- package/assets/skills/explainer-kit/scripts/lib/catalog.mjs +109 -3
- package/assets/skills/explainer-kit/scripts/lib/contracts.mjs +550 -17
- package/assets/skills/explainer-kit/scripts/lib/durability.mjs +90 -8
- package/assets/skills/explainer-kit/scripts/lib/fs-safe.mjs +5 -0
- package/assets/skills/explainer-kit/scripts/lib/internal-references.mjs +538 -0
- package/assets/skills/explainer-kit/scripts/lib/package-coverage.mjs +129 -11
- package/assets/skills/explainer-kit/scripts/lib/publication-policy.mjs +54 -0
- package/assets/skills/explainer-kit/scripts/lib/recipes.mjs +2 -1
- package/assets/skills/explainer-kit/scripts/lib/records.mjs +139 -22
- package/assets/skills/explainer-kit/scripts/lib/s3-roots.mjs +353 -0
- package/assets/skills/explainer-kit/scripts/lib/s3-static.mjs +237 -107
- package/assets/skills/explainer-kit/scripts/lib/set-plan.mjs +1 -0
- package/assets/skills/explainer-kit/scripts/lib/terminal-evidence.mjs +157 -0
- package/assets/skills/explainer-kit/scripts/lib/visual-review.mjs +26 -6
- package/assets/skills/explainer-kit/scripts/run.mjs +1006 -144
- package/assets/skills/oat-agent-instructions-analyze/references/docs/provider-reference.md +14 -2
- package/assets/skills/oat-agent-instructions-apply/references/docs/provider-reference.md +14 -2
- package/assets/skills/oat-explainer-kit/SKILL.md +16 -3
- package/assets/skills/oat-explainer-kit/references/config-contract.md +13 -8
- package/assets/skills/oat-explainer-kit/references/lifecycle-contract.md +50 -6
- package/assets/skills/oat-explainer-kit/references/migration.md +2 -1
- package/assets/skills/oat-explainer-kit/references/visual-review-callback.md +11 -0
- package/assets/skills/oat-explainer-kit/scripts/bind-project-sources.mjs +37 -15
- package/assets/skills/oat-explainer-kit/scripts/check-terminal-outcome.mjs +83 -0
- package/assets/skills/oat-explainer-kit/scripts/derive-destination.mjs +91 -0
- package/assets/skills/oat-explainer-kit/scripts/finalize-tracked-run.mjs +66 -10
- package/assets/skills/oat-explainer-kit/scripts/resolve-config.mjs +60 -21
- package/assets/skills/oat-explainer-kit/scripts/resolve-paths.mjs +52 -8
- package/assets/skills/oat-explainer-kit/scripts/run.mjs +271 -36
- package/assets/skills/oat-project-autonomous/references/gate-inventory.md +2 -2
- package/assets/skills/oat-project-complete/SKILL.md +19 -3
- package/assets/skills/oat-project-document/references/docs/autonomy-contract.md +2 -2
- package/assets/skills/oat-project-implement/references/completion-and-closeout.md +8 -0
- package/assets/skills/oat-project-implement/references/docs/autonomy-contract.md +2 -2
- package/assets/skills/oat-project-pr-final/references/docs/autonomy-contract.md +2 -2
- package/assets/skills/oat-project-quick-start/references/docs/autonomy-contract.md +2 -2
- package/dist/commands/config/index.d.ts.map +1 -1
- package/dist/commands/config/index.js +18 -0
- package/dist/commands/init/index.d.ts +2 -2
- package/dist/commands/init/index.d.ts.map +1 -1
- package/dist/commands/init/index.js +22 -13
- package/dist/commands/project/archive/archive-utils.d.ts.map +1 -1
- package/dist/commands/project/archive/archive-utils.js +57 -7
- package/dist/commands/project/archive/explainer-terminal-evidence.d.ts +29 -0
- package/dist/commands/project/archive/explainer-terminal-evidence.d.ts.map +1 -0
- package/dist/commands/project/archive/explainer-terminal-evidence.js +37 -0
- package/dist/commands/remove/skill/remove-skill.d.ts +4 -1
- package/dist/commands/remove/skill/remove-skill.d.ts.map +1 -1
- package/dist/commands/remove/skill/remove-skill.js +44 -5
- package/dist/commands/shared/adopt-stray.d.ts +5 -0
- package/dist/commands/shared/adopt-stray.d.ts.map +1 -1
- package/dist/commands/shared/adopt-stray.js +25 -4
- package/dist/commands/shared/native-skill-disposition.d.ts +22 -0
- package/dist/commands/shared/native-skill-disposition.d.ts.map +1 -0
- package/dist/commands/shared/native-skill-disposition.js +60 -0
- package/dist/commands/status/index.d.ts +2 -2
- package/dist/commands/status/index.d.ts.map +1 -1
- package/dist/commands/status/index.js +22 -13
- package/dist/config/oat-config.d.ts +2 -0
- package/dist/config/oat-config.d.ts.map +1 -1
- package/dist/config/oat-config.js +4 -0
- package/dist/config/resolve.d.ts.map +1 -1
- package/dist/config/resolve.js +1 -0
- package/dist/engine/compute-plan.d.ts +3 -2
- package/dist/engine/compute-plan.d.ts.map +1 -1
- package/dist/engine/compute-plan.js +1 -1
- package/dist/engine/index.d.ts +1 -1
- package/dist/engine/index.d.ts.map +1 -1
- package/dist/engine/index.js +1 -1
- package/dist/providers/copilot/paths.d.ts.map +1 -1
- package/dist/providers/copilot/paths.js +6 -4
- package/package.json +2 -2
- package/dist/commands/shared/cursor-skill-disposition.d.ts +0 -17
- package/dist/commands/shared/cursor-skill-disposition.d.ts.map +0 -1
- package/dist/commands/shared/cursor-skill-disposition.js +0 -41
- /package/assets/skills/explainer-kit/recipes/{project-recap.json → project-recap.v1.json} +0 -0
- /package/assets/skills/explainer-kit/schemas/{publish-receipt.schema.json → publish-receipt.v1.schema.json} +0 -0
- /package/assets/skills/explainer-kit/schemas/{publish-request.schema.json → publish-request.v1.schema.json} +0 -0
|
@@ -279,13 +279,24 @@ supported home for Cursor-only skills. Cursor also reads `.claude/skills/` and
|
|
|
279
279
|
**Skill locations:**
|
|
280
280
|
|
|
281
281
|
- Project:
|
|
282
|
-
- `.
|
|
282
|
+
- `.agents/skills/<skill-name>/SKILL.md` (**native canonical path**)
|
|
283
|
+
- `.github/skills/<skill-name>/SKILL.md` (**legacy/adoption path**)
|
|
283
284
|
- `.claude/skills/<skill-name>/SKILL.md` (**Claude compatibility**)
|
|
284
285
|
- Personal:
|
|
285
|
-
- `~/.
|
|
286
|
+
- `~/.agents/skills/<skill-name>/SKILL.md` (**native canonical path**)
|
|
287
|
+
- `~/.copilot/skills/<skill-name>/SKILL.md` (**legacy/adoption path**)
|
|
286
288
|
- `~/.claude/skills/<skill-name>/SKILL.md` (**Claude compatibility**; Copilot coding agent and GitHub Copilot CLI only)
|
|
287
289
|
|
|
288
|
-
**Notable:** Like Cursor, Copilot reads
|
|
290
|
+
**Notable:** Like Cursor, Copilot reads canonical `.agents/skills/` at project
|
|
291
|
+
and personal scope. OAT does not generate `.github/skills` or
|
|
292
|
+
`~/.copilot/skills` views; existing packages there remain adoption inputs.
|
|
293
|
+
Copilot agents and project rules still use `.github/agents`,
|
|
294
|
+
`~/.copilot/agents`, and `.github/instructions`.
|
|
295
|
+
|
|
296
|
+
OAT asks whether to adopt each unresolved legacy Copilot skill into canonical
|
|
297
|
+
storage or keep it Copilot-only as an exact known stray. Same-name canonical
|
|
298
|
+
collisions block keep-local. Legacy cleanup removes only verified clean managed
|
|
299
|
+
views and preserves changed or unverifiable content.
|
|
289
300
|
|
|
290
301
|
**Notes:** The `license` field may be required in practice even though the spec marks it optional (see https://github.com/github/copilot-cli/issues/894).
|
|
291
302
|
|
|
@@ -343,16 +354,14 @@ Installs skills from GitHub repos, local paths, or GitLab URLs to any supported
|
|
|
343
354
|
|
|
344
355
|
### Symlink Approach (Recommended)
|
|
345
356
|
|
|
346
|
-
Author skills in `.agents/skills/` (canonical) and distribute to
|
|
357
|
+
Author skills in `.agents/skills/` (canonical) and distribute only to providers
|
|
358
|
+
that require a provider-specific directory:
|
|
347
359
|
|
|
348
360
|
```bash
|
|
349
361
|
# Claude Code
|
|
350
362
|
ln -s ../../.agents/skills/my-skill .claude/skills/my-skill
|
|
351
363
|
|
|
352
|
-
#
|
|
353
|
-
ln -s ../../.agents/skills/my-skill .github/skills/my-skill
|
|
354
|
-
|
|
355
|
-
# Cursor, Codex, and Gemini read .agents/skills/ natively — no symlink needed
|
|
364
|
+
# Cursor, Copilot, Codex, and Gemini read .agents/skills/ natively — no symlink needed
|
|
356
365
|
```
|
|
357
366
|
|
|
358
367
|
For automated distribution, use **OAT sync** (for local/internal skills) or **`npx skills add`** (for remote/community skills):
|
|
@@ -365,11 +374,12 @@ oat sync --scope all
|
|
|
365
374
|
npx skills add github-user/skill-repo -a claude-code -a github-copilot
|
|
366
375
|
```
|
|
367
376
|
|
|
368
|
-
**Result: one canonical source,
|
|
377
|
+
**Result: one canonical source, one symlink, five tools.**
|
|
369
378
|
|
|
370
|
-
**Note:** Cursor, Codex, and Gemini read `.agents/skills/` directly at
|
|
371
|
-
and user scope. Keep `.cursor/skills/` for intentionally Cursor-only
|
|
372
|
-
not as a generated mirror of canonical content.
|
|
379
|
+
**Note:** Cursor, Copilot, Codex, and Gemini read `.agents/skills/` directly at
|
|
380
|
+
project and user scope. Keep `.cursor/skills/` for intentionally Cursor-only
|
|
381
|
+
skills, not as a generated mirror of canonical content. Treat `.github/skills/`
|
|
382
|
+
and `~/.copilot/skills/` as legacy Copilot adoption inputs, not mirrors.
|
|
373
383
|
|
|
374
384
|
---
|
|
375
385
|
|
|
@@ -523,31 +533,33 @@ The proposal has community interest but no official timeline or maintainer respo
|
|
|
523
533
|
|
|
524
534
|
**Source:** https://platform.claude.com/docs/en/agents-and-tools/agent-skills/best-practices, https://github.com/agentskills/agentskills/tree/main/skills-ref
|
|
525
535
|
|
|
526
|
-
### Q:
|
|
536
|
+
### Q: Do native `.agents/skills/` mappings eliminate all provider views?
|
|
527
537
|
|
|
528
|
-
**Answer:** No. Cursor, Codex, and Gemini need no skill mirror, but
|
|
529
|
-
|
|
538
|
+
**Answer:** No. Cursor, Copilot, Codex, and Gemini need no skill mirror, but
|
|
539
|
+
Claude Code still uses a provider-specific path. Provider-specific agent and
|
|
540
|
+
rule views also remain where those runtimes require them:
|
|
530
541
|
|
|
531
542
|
| Tool | Native Path | Reads `.claude/skills/`? | Reads `.agents/skills/`? |
|
|
532
543
|
| -------------- | ----------------- | ------------------------ | ------------------------ |
|
|
533
544
|
| Claude Code | `.claude/skills/` | ✅ (native) | ❌ |
|
|
534
545
|
| Cursor | `.agents/skills/` | ✅ (compatibility) | ✅ (native) |
|
|
535
546
|
| Codex CLI | `.agents/skills/` | ❌ | ✅ (native) |
|
|
536
|
-
| GitHub Copilot | `.
|
|
547
|
+
| GitHub Copilot | `.agents/skills/` | ✅ (compatibility) | ✅ (native) |
|
|
537
548
|
| Gemini CLI | `.agents/skills/` | ❌ | ✅ (native alias) |
|
|
538
549
|
|
|
539
|
-
**Recommended approach:** Author skills in `.agents/skills/` (tool-agnostic
|
|
550
|
+
**Recommended approach:** Author skills in `.agents/skills/` (tool-agnostic
|
|
551
|
+
canonical source), then symlink only where needed:
|
|
540
552
|
|
|
541
553
|
```bash
|
|
542
|
-
#
|
|
554
|
+
# One symlink needed:
|
|
543
555
|
ln -s ../../.agents/skills/my-skill .claude/skills/my-skill # Claude Code + Copilot compatibility
|
|
544
|
-
|
|
545
|
-
# Cursor, Codex, and Gemini read .agents/skills/ natively — no symlink needed
|
|
556
|
+
# Cursor, Copilot, Codex, and Gemini read .agents/skills/ natively — no symlink needed
|
|
546
557
|
```
|
|
547
558
|
|
|
548
|
-
**One canonical source,
|
|
559
|
+
**One canonical source, one symlink, five tools.** Legacy `.github/skills` and
|
|
560
|
+
`~/.copilot/skills` entries are migration candidates, not recommended mirrors.
|
|
549
561
|
|
|
550
|
-
**Note (updated
|
|
562
|
+
**Note (updated August 2026):** Cursor, Copilot, Codex, and Gemini read
|
|
551
563
|
`.agents/skills/` natively at project and user scope. No skill symlinks are
|
|
552
564
|
needed for those providers.
|
|
553
565
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: explainer-kit
|
|
3
|
-
version: 2.0
|
|
3
|
+
version: 2.1.0
|
|
4
4
|
description: Use when building destination-neutral visual explainer artifacts from explicit, versioned inputs.
|
|
5
5
|
user-invocable: true
|
|
6
6
|
allowed-tools: Read, Write, Edit, Bash, Grep, Glob, Agent, mcp__*
|
|
@@ -74,11 +74,13 @@ request.
|
|
|
74
74
|
The recipe — never the author — selects each artifact's authoring path. Floor
|
|
75
75
|
entries and expansion profiles declare `authoring: markdown` for the narrative
|
|
76
76
|
path or `authoring: html` for the artistic path. The core invokes the author
|
|
77
|
-
once per artifact with an `explainer-kit.author-request/
|
|
77
|
+
once per artifact with an `explainer-kit.author-request/v3` payload carrying the
|
|
78
78
|
artifact identity and type, its authoring path, the inlined brief from
|
|
79
79
|
`briefs/`, the reconciled fact base, the resolved theme, the shell source for
|
|
80
|
-
artistic artifacts,
|
|
81
|
-
artifacts
|
|
80
|
+
artistic artifacts, the required narrative sections for narrative floor
|
|
81
|
+
artifacts, and canonical `artifactLinks` with explicit `index.html` site paths
|
|
82
|
+
and receiver-relative hrefs. Version 2 requests remain readable for replay. It
|
|
83
|
+
accepts only a schema-valid
|
|
82
84
|
`explainer-kit.author-result/v2` with exactly one of `content.markdown` or
|
|
83
85
|
`content.html` plus non-secret provenance, rejects excessive verbatim source
|
|
84
86
|
overlap, retains each validated result under `source/author/` and its content
|
|
@@ -107,11 +109,28 @@ continues. Accepted expansion artifacts render to
|
|
|
107
109
|
`site/{directory}/{slug}/{artifactId}/index.html` and are linked from the floor
|
|
108
110
|
hub; floor artifacts keep their existing paths.
|
|
109
111
|
|
|
112
|
+
`project-recap@2` requires one complete navigational hub and makes diagrams,
|
|
113
|
+
decks, and deep dives adaptive expansions. The planner proposes one only when
|
|
114
|
+
it can name a distinct reader question, the supporting source evidence, and why
|
|
115
|
+
that medium improves on adding more hub prose. The prose brief governs
|
|
116
|
+
typographic roles, hierarchy, slide archetypes, diagram semantics,
|
|
117
|
+
fit-to-content composition, density, repetition, and medium choice. These are
|
|
118
|
+
editorial judgments, not new request fields or renderer rules.
|
|
119
|
+
`project-recap@1` remains readable for replay with its historical three-artifact
|
|
120
|
+
floor.
|
|
121
|
+
|
|
110
122
|
## Review, Approval, and Warnings
|
|
111
123
|
|
|
112
|
-
Approval runs after theme, render,
|
|
113
|
-
render QA, immediately before publish and
|
|
114
|
-
rendered artifacts and the complete warning
|
|
124
|
+
Approval runs after theme, render, hard internal-reference validation, safety
|
|
125
|
+
validation, the guideline checker, and render QA, immediately before publish and
|
|
126
|
+
durability — so a reviewer approves rendered artifacts and the complete warning
|
|
127
|
+
set, not raw prose. The reference gate resolves `href`, `src`, `srcset`,
|
|
128
|
+
fragments, and safe embedded references against explicit manifest/site-tree
|
|
129
|
+
files. It may invoke the existing correction author once, then rerenders and
|
|
130
|
+
revalidates before any browser or visual review. A later visual correction also
|
|
131
|
+
rerenders and passes through the validation-only reference gate without
|
|
132
|
+
receiving another correction attempt. An exhausted `E_INTERNAL_REFERENCE`
|
|
133
|
+
finding fails closed and cannot reach durability.
|
|
115
134
|
|
|
116
135
|
Interactive runs stop with an `incomplete` outcome once artifacts are built and
|
|
117
136
|
checked. Review the rendered `site/` tree, the sources under `source/content/`,
|
|
@@ -144,7 +163,13 @@ succeed.
|
|
|
144
163
|
|
|
145
164
|
Visual critics use the independent whole-set rubric in
|
|
146
165
|
`references/visual-review.md`, which separates review judgment from
|
|
147
|
-
medium-specific authoring rules.
|
|
166
|
+
medium-specific authoring rules. They assess typography, hierarchy,
|
|
167
|
+
composition, density, medium leverage, template repetition, diagram semantics,
|
|
168
|
+
and cross-artifact cohesion from rendered browser evidence. The rubric keeps
|
|
169
|
+
the existing provider-neutral result contract: `pass` means no required
|
|
170
|
+
correction remains, while `correct` carries concrete artifact-scoped actions
|
|
171
|
+
into the one bounded correction round. It does not assign design scores or
|
|
172
|
+
encode geometry thresholds.
|
|
148
173
|
|
|
149
174
|
Render QA is opt-in. It runs only against an injected `browserProbe`, and the
|
|
150
175
|
core never launches a browser of its own — reviewing the rendered output in a
|
|
@@ -34,14 +34,32 @@ Use the same terms, statuses, and numbers throughout.
|
|
|
34
34
|
|
|
35
35
|
## Floor
|
|
36
36
|
|
|
37
|
-
Produce one rich
|
|
38
|
-
|
|
39
|
-
and
|
|
40
|
-
useful without
|
|
37
|
+
Produce one rich navigational hub covering all six sections above. It must
|
|
38
|
+
orient the reader, expose the project state and outcome in the first viewport,
|
|
39
|
+
and link every selected artifact with descriptive labels. The hub should remain
|
|
40
|
+
complete and useful without an expansion artifact.
|
|
41
|
+
|
|
42
|
+
Establish deliberate typographic roles for the title, framing statement,
|
|
43
|
+
section headings, labels, body text, and evidence annotations. Build hierarchy
|
|
44
|
+
through scale, spacing, contrast, and grouping instead of applying one repeated
|
|
45
|
+
card or section treatment everywhere. Keep density fit to the material: shorten
|
|
46
|
+
or restructure crowded passages, but do not pad sparse evidence with decorative
|
|
47
|
+
filler. Choose tables, lists, diagrams, and prose only when each medium makes
|
|
48
|
+
the evidence easier to understand.
|
|
41
49
|
|
|
42
50
|
## Expansion license
|
|
43
51
|
|
|
44
|
-
Propose
|
|
45
|
-
|
|
46
|
-
|
|
52
|
+
Propose a supporting diagram, walkthrough deck, or deep-dive only when it
|
|
53
|
+
answers a distinct reader question that the hub cannot answer cleanly. For
|
|
54
|
+
every proposal, identify the reader question, the source evidence that supports
|
|
55
|
+
it, and the rationale for choosing that medium. Do not expand to repeat the
|
|
47
56
|
same story in another format.
|
|
57
|
+
|
|
58
|
+
Use a diagram when topology, direction, ownership, or flow carries meaning.
|
|
59
|
+
Preserve branches, fan-in, cycles, labels, and explicit relationships, and fit
|
|
60
|
+
the frame to the content rather than leaving a tiny graph in a large canvas.
|
|
61
|
+
Use a deck only when pacing adds value; choose slide archetypes to match the
|
|
62
|
+
story, such as an outcome opener, comparison, system view, decision, evidence,
|
|
63
|
+
or next-action frame. Vary composition to fit each claim instead of repeating
|
|
64
|
+
one template. Use a deep-dive when source-backed mechanics or trade-offs need
|
|
65
|
+
more room than the hub can give them.
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schemaVersion": "explainer-kit.recipe/v2",
|
|
3
|
+
"id": "project-recap",
|
|
4
|
+
"version": "2",
|
|
5
|
+
"sourceRoles": [
|
|
6
|
+
{
|
|
7
|
+
"role": "project",
|
|
8
|
+
"required": true,
|
|
9
|
+
"accepts": ["file", "directory", "git", "github"],
|
|
10
|
+
"minBindings": 1,
|
|
11
|
+
"maxBindings": 1
|
|
12
|
+
}
|
|
13
|
+
],
|
|
14
|
+
"floor": [
|
|
15
|
+
{
|
|
16
|
+
"id": "project-recap",
|
|
17
|
+
"type": "hub",
|
|
18
|
+
"authoring": "html",
|
|
19
|
+
"template": "house-style",
|
|
20
|
+
"required": true,
|
|
21
|
+
"briefRef": "briefs/project-recap.md",
|
|
22
|
+
"requiredNarrative": [
|
|
23
|
+
"original-request",
|
|
24
|
+
"key-agent-decisions",
|
|
25
|
+
"as-built-architecture",
|
|
26
|
+
"implementation-record",
|
|
27
|
+
"validation-evidence",
|
|
28
|
+
"outcome"
|
|
29
|
+
]
|
|
30
|
+
}
|
|
31
|
+
],
|
|
32
|
+
"expansion": {
|
|
33
|
+
"profiles": [
|
|
34
|
+
{
|
|
35
|
+
"profileId": "supporting-diagram",
|
|
36
|
+
"type": "diagram",
|
|
37
|
+
"authoring": "html",
|
|
38
|
+
"briefRef": "briefs/supporting-diagram.md",
|
|
39
|
+
"shell": "diagram-shell",
|
|
40
|
+
"maxCount": 1
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
"profileId": "walkthrough-deck",
|
|
44
|
+
"type": "deck",
|
|
45
|
+
"authoring": "html",
|
|
46
|
+
"briefRef": "briefs/walkthrough-deck.md",
|
|
47
|
+
"shell": "deck-shell",
|
|
48
|
+
"maxCount": 1
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
"profileId": "deep-dive",
|
|
52
|
+
"type": "explainer",
|
|
53
|
+
"authoring": "markdown",
|
|
54
|
+
"briefRef": "briefs/deep-dive.md",
|
|
55
|
+
"maxCount": 3
|
|
56
|
+
}
|
|
57
|
+
],
|
|
58
|
+
"limits": {
|
|
59
|
+
"maxArtifacts": 5
|
|
60
|
+
}
|
|
61
|
+
},
|
|
62
|
+
"fallback": {
|
|
63
|
+
"mode": "deterministic-markdown",
|
|
64
|
+
"selection": "explicit",
|
|
65
|
+
"authoring": "markdown",
|
|
66
|
+
"scope": "portfolio"
|
|
67
|
+
},
|
|
68
|
+
"discoveryLimits": {
|
|
69
|
+
"consecutiveNoNewFindingsRounds": 2,
|
|
70
|
+
"maxRounds": 8
|
|
71
|
+
}
|
|
72
|
+
}
|
|
@@ -34,25 +34,34 @@ Every run, interactive or unattended, also requires a provider-neutral author
|
|
|
34
34
|
callback; a run without one fails `E_AUTHOR_REQUIRED`. An in-process caller
|
|
35
35
|
supplies `options.author(request)`; a JSON-only CLI caller uses
|
|
36
36
|
`--author-module author.mjs`. The core invokes it once per resolved artifact
|
|
37
|
-
with an `explainer-kit.author-request/
|
|
37
|
+
with an `explainer-kit.author-request/v3` payload containing the artifact
|
|
38
38
|
identity and type, the artifact's authoring path, the inlined brief, the bundled
|
|
39
39
|
`visualAuthoringGuidance`, the reconciled fact base, the resolved theme, the
|
|
40
40
|
shell source for artistic artifacts, the required narrative sections for
|
|
41
|
-
narrative floor artifacts,
|
|
41
|
+
narrative floor artifacts, bounded-discovery context, and `artifactLinks`.
|
|
42
|
+
Each canonical link entry names the planned artifact, its explicit site-relative
|
|
43
|
+
path ending in `index.html`, and the relative `href` from the receiving
|
|
44
|
+
artifact's own location. The guidance is
|
|
42
45
|
loaded only from the installed skill's `references/visual-authoring.md`; no
|
|
43
46
|
ambient or home-directory file is consulted. The callback must return an
|
|
44
47
|
`explainer-kit.author-result/v2` carrying exactly one of `content.markdown` or
|
|
45
48
|
`content.html`, matching the artifact's declared authoring path, plus non-secret
|
|
46
49
|
provenance. The executable callback is never persisted in `run-request.json`.
|
|
47
50
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
51
|
+
New project recap producers select immutable `project-recap@2`. Its
|
|
52
|
+
navigational hub is the only mandatory artifact. A diagram, deck, or deep dive
|
|
53
|
+
is an optional expansion only when its justification states a distinct reader
|
|
54
|
+
question, supporting source evidence, and the rationale for using that medium.
|
|
55
|
+
Project recap requests also have an explicit `recapMode`. Omitting it selects
|
|
56
|
+
and persists `artistic`, which keeps the recipe's rich HTML floor. Selecting
|
|
57
|
+
`deterministic-markdown` before the run applies the recipe-owned fallback to the
|
|
58
|
+
complete planned portfolio — the hub plus any accepted expansions — without
|
|
59
|
+
changing its artifact identities. The resulting Markdown author records and
|
|
60
|
+
`source/content/*.md` paths remain distinct in the manifest and immutable
|
|
61
|
+
rebuild package. An artistic author failure fails the run; the core never
|
|
62
|
+
silently retries or downgrades it as Markdown. `project-recap@1` is immutable
|
|
63
|
+
replay guidance only: retained v1 requests remain readable, but current
|
|
64
|
+
producers do not select it.
|
|
56
65
|
|
|
57
66
|
Before artifact authoring, a caller supplies one provider-neutral `planSet`
|
|
58
67
|
callback. It receives the reconciled fact base and recipe policy and returns
|
|
@@ -62,7 +71,7 @@ callback. It receives the reconciled fact base and recipe policy and returns
|
|
|
62
71
|
{
|
|
63
72
|
"schemaVersion": "explainer-kit.set-plan/v1",
|
|
64
73
|
"planId": "project-recap-set",
|
|
65
|
-
"recipe": { "id": "project-recap", "version": "
|
|
74
|
+
"recipe": { "id": "project-recap", "version": "2" },
|
|
66
75
|
"sourceIds": ["plan"],
|
|
67
76
|
"ledger": {
|
|
68
77
|
"terminology": [],
|
|
@@ -87,9 +96,11 @@ The set plan owns the shared terminology/status/number ledger, source coverage,
|
|
|
87
96
|
adaptive portfolio, per-artifact draft, and visual intent. Optional entries add
|
|
88
97
|
a source-backed `justification`; undeclared sources, conflicting ledger values,
|
|
89
98
|
duplicate artifact IDs, and unjustified optional entries are invalid. Each
|
|
90
|
-
`author-request/
|
|
99
|
+
`author-request/v3` carries the complete immutable `setContext` plus the exact
|
|
91
100
|
matching `plannedArtifact`. The planner finalizes floor and expansion entries
|
|
92
101
|
before authoring; author results cannot add, remove, or replace artifacts.
|
|
102
|
+
Version 2 requests remain valid for deterministic replay; new runs emit only
|
|
103
|
+
the complete v3 request.
|
|
93
104
|
When a planner draft contains a supported non-linear graph, the request also
|
|
94
105
|
carries its closed `graphSemantics` (direction, nodes, edges, and topology).
|
|
95
106
|
Artistic HTML must expose one exact `data-direction`. Each planned node requires
|
|
@@ -183,12 +194,33 @@ The core executes:
|
|
|
183
194
|
5. author every planned artifact against the same set context
|
|
184
195
|
6. render typed artifacts through the narrative renderer or validate
|
|
185
196
|
agent-composed HTML, per each artifact's declared authoring path
|
|
186
|
-
7.
|
|
197
|
+
7. validate every post-render `href`, `src`, `srcset`, and embedded reference
|
|
198
|
+
against the manifest paths and generated site tree; reject directory links,
|
|
199
|
+
escapes, missing files or fragments, malformed references, and unsafe
|
|
200
|
+
embedded resources
|
|
201
|
+
8. optionally apply one bounded author correction, then rerender and revalidate
|
|
202
|
+
the complete site before any browser callback
|
|
203
|
+
9. run structural and guideline QA, plus required browser and independent
|
|
187
204
|
visual review for unattended project recaps
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
205
|
+
10. close any unresolved recap review gate before external persistence
|
|
206
|
+
11. resolve content approval — the interactive gate pauses here, after render and
|
|
207
|
+
QA and before anything is published or persisted externally
|
|
208
|
+
12. write the manifest and build record
|
|
209
|
+
|
|
210
|
+
The internal-reference gate uses a bounded tokenizer/classifier rather than a
|
|
211
|
+
general HTML parser. Relative references resolve from the current explicit file
|
|
212
|
+
with an isolated HTTPS base, then must bind exactly to the manifest/site tree.
|
|
213
|
+
Referenced fragments must resolve to exactly one ID in the target document;
|
|
214
|
+
unused duplicate renderer-generated IDs do not fail indexing. Safe base64 image
|
|
215
|
+
data references and same-document fragments are classified separately. A
|
|
216
|
+
malformed, unresolved, or ambiguous reference fails `E_INTERNAL_REFERENCE`.
|
|
217
|
+
Once the one correction is exhausted, including after visual correction, the run
|
|
218
|
+
fails hard: the QA stage is recorded `failed` with code-only evidence and the
|
|
219
|
+
scrubbed message `The qa stage failed.`, and the run is not durability- or
|
|
220
|
+
publication-eligible. No finding is retained and nothing names the broken
|
|
221
|
+
reference — terminal evidence is code-only by design, and the failure is
|
|
222
|
+
attributed to the `link-validation` evidence stage rather than to
|
|
223
|
+
`browser-review`.
|
|
192
224
|
|
|
193
225
|
An incomplete interactive result includes
|
|
194
226
|
`approval.resumeToken: "ekrt2:<64 lowercase hex characters>"`. The token is an
|
|
@@ -10,15 +10,39 @@ node scripts/publish.mjs \
|
|
|
10
10
|
--confirm-publish
|
|
11
11
|
```
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
13
|
+
New requests use `explainer-kit.publish-request/v2` and explicitly declare
|
|
14
|
+
`publicAccess` as `public` or `protected`. V1 remains readable as public-mode
|
|
15
|
+
replay. Credentials come only from the standard AWS credential chain or the
|
|
16
|
+
request's optional profile. Never put access keys, secret keys, session tokens,
|
|
17
|
+
or SSO tokens in a request.
|
|
18
|
+
|
|
19
|
+
## How the two roots compose
|
|
20
|
+
|
|
21
|
+
`s3Uri` and `publicBaseUrl` are each normalized without trailing slashes. For a
|
|
22
|
+
path `P` relative to `siteRoot`, the connector writes `<s3Uri>/P` and verifies
|
|
23
|
+
`<publicBaseUrl>/P`. That composition is the whole of the relationship.
|
|
24
|
+
|
|
25
|
+
**No relational validation is performed between the two roots, by design.** The
|
|
26
|
+
mapping from an S3 key to a public URL is underdetermined by these two strings:
|
|
27
|
+
it lives in CDN configuration the connector cannot read. Both of these are
|
|
28
|
+
legitimate, and they disagree structurally:
|
|
29
|
+
|
|
30
|
+
| Shape | `s3Uri` | `publicBaseUrl` |
|
|
31
|
+
| ----- | ---------------------------- | ----------------------------- |
|
|
32
|
+
| A | `s3://bucket/repositories/x` | `https://host/repositories/x` |
|
|
33
|
+
| B | `s3://bucket/explainers` | `https://host` |
|
|
34
|
+
|
|
35
|
+
B is an ordinary CloudFront **Origin Path** deployment, where a bucket prefix is
|
|
36
|
+
mapped to the distribution root. Requiring the public path to equal the S3 key
|
|
37
|
+
prefix rejects it. Suffix-containment does not rescue the rule either — an empty
|
|
38
|
+
public path is a suffix of everything, so B would pass vacuously while
|
|
39
|
+
path-rewriting deployments (CloudFront Functions, Lambda@Edge, custom origins)
|
|
40
|
+
still produce false rejections.
|
|
41
|
+
|
|
42
|
+
Divergence between the two paths is therefore reported as a **non-blocking
|
|
43
|
+
warning**, never a failure. Correctness of an advertised URL is established by
|
|
44
|
+
verification, not by string shape — which is also why `publicAccess: protected`,
|
|
45
|
+
where no anonymous fetch happens, cannot establish it at all.
|
|
22
46
|
|
|
23
47
|
For example:
|
|
24
48
|
|
|
@@ -32,7 +56,39 @@ For example:
|
|
|
32
56
|
| public URL | `https://cdn.example.com/published/initiatives/demo/index.html` |
|
|
33
57
|
|
|
34
58
|
Use explicit `index.html` URLs. Directory redirects are not portable evidence.
|
|
35
|
-
The destination must serve uploaded bytes at the
|
|
59
|
+
The destination must serve the uploaded bytes at the composed public path. That
|
|
60
|
+
is a requirement on the deployment, not something the connector validates from
|
|
61
|
+
the two root strings; see below.
|
|
62
|
+
|
|
63
|
+
## The manifest a connector receives is intentionally incomplete
|
|
64
|
+
|
|
65
|
+
The core persists the manifest **before** it invokes the publisher callback, so
|
|
66
|
+
the file at `manifestPath` carries `outcome: "incomplete"` while the `publish`
|
|
67
|
+
stage is still `running`. This is a contractually intended intermediate state,
|
|
68
|
+
not a corrupt or half-written record, and a connector must not reject it on the
|
|
69
|
+
strength of `outcome` alone.
|
|
70
|
+
|
|
71
|
+
Do not decide publishability from the manifest by itself. Read the build record
|
|
72
|
+
named by `manifest.buildRecord.path` (resolved relative to the manifest) and
|
|
73
|
+
require all of:
|
|
74
|
+
|
|
75
|
+
- the manifest carries no `visual-review-required:` warning;
|
|
76
|
+
- the build record's own `outcome` is `incomplete`;
|
|
77
|
+
- its `publish` stage exists and is `running`; and
|
|
78
|
+
- every stage before `publish` is `passed`, `warned`, or `skipped` and carries
|
|
79
|
+
no `visual-review-required:` warning.
|
|
80
|
+
|
|
81
|
+
Only that combination makes an `incomplete` manifest publishable. The one other
|
|
82
|
+
eligible shape is a finalized `built-durable` manifest that is not
|
|
83
|
+
review-flagged. Any other `incomplete` manifest, and every manifest whose run is
|
|
84
|
+
flagged, failed, or superseded, must be refused. The built-in connector performs
|
|
85
|
+
exactly this check before its first network call; third-party connectors are
|
|
86
|
+
required to perform an equivalent one.
|
|
87
|
+
|
|
88
|
+
The published bytes cannot diverge from the finalized manifest: the catalog
|
|
89
|
+
projection omits `outcome` and `warnings`, and both manifest writes share one
|
|
90
|
+
`finalizedAt`. After the callback returns a valid receipt, the core rewrites the
|
|
91
|
+
manifest with its terminal outcome.
|
|
36
92
|
|
|
37
93
|
## Safety and ordering
|
|
38
94
|
|
|
@@ -41,16 +97,22 @@ site-relative paths before network access. It then:
|
|
|
41
97
|
|
|
42
98
|
1. uploads a sentinel whose path contains the run ID and a random 128-bit
|
|
43
99
|
suffix;
|
|
44
|
-
2. verifies the sentinel with
|
|
45
|
-
|
|
100
|
+
2. verifies the sentinel with a service-computed SHA-256 checksum or an
|
|
101
|
+
authenticated download hash;
|
|
102
|
+
3. for public destinations, fetches that exact sentinel anonymously through the
|
|
103
|
+
public root; protected destinations skip this public fetch explicitly;
|
|
46
104
|
4. deletes only that sentinel;
|
|
47
105
|
5. uploads or idempotently skips each declared artifact;
|
|
48
|
-
6. verifies object
|
|
49
|
-
|
|
50
|
-
|
|
106
|
+
6. verifies exact object bytes from service-computed SHA-256 evidence or an
|
|
107
|
+
authenticated download hash, then additionally verifies the exact anonymous
|
|
108
|
+
response bytes for public destinations; and
|
|
109
|
+
7. atomically writes `explainer-kit.publish-receipt/v2` with separate
|
|
110
|
+
authenticated-object and anonymous-public verification facts.
|
|
51
111
|
|
|
52
|
-
If
|
|
53
|
-
|
|
112
|
+
If required sentinel verification fails or its verification capability is
|
|
113
|
+
unavailable, no artifact is uploaded. The connector attempts sentinel cleanup
|
|
114
|
+
and emits no successful receipt. An undeclared `401` or `403` in public mode is
|
|
115
|
+
a verification failure, never evidence that the destination is protected.
|
|
54
116
|
|
|
55
117
|
Publishing is additive. The implementation uses individual `put-object`,
|
|
56
118
|
`head-object`, and sentinel-only `delete-object` operations. It never performs
|
|
@@ -74,10 +136,13 @@ Every upload sets metadata explicitly:
|
|
|
74
136
|
| other | manifest media type or `application/octet-stream` |
|
|
75
137
|
|
|
76
138
|
Artifacts use `Cache-Control: public, max-age=300`. The connector stores the
|
|
77
|
-
SHA-256 digest as object metadata for idempotency and
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
139
|
+
SHA-256 digest as object metadata for idempotency and supplies
|
|
140
|
+
`--checksum-sha256` on upload. It requests service checksum evidence with
|
|
141
|
+
`--checksum-mode ENABLED`; caller-authored metadata and ETags are never treated
|
|
142
|
+
as object-byte proof. When service SHA-256 evidence is unavailable, the
|
|
143
|
+
connector hashes bytes from an authenticated download. Public verification
|
|
144
|
+
separately hashes response bytes without text decoding, so binary artifacts and
|
|
145
|
+
stale wrong-byte 200 responses are covered.
|
|
81
146
|
|
|
82
147
|
## Failures and retries
|
|
83
148
|
|
|
@@ -86,9 +151,60 @@ not run `aws sso login`, retry with another profile, expose AWS diagnostics, or
|
|
|
86
151
|
persist credentials. Refresh credentials separately and rerun after approval.
|
|
87
152
|
|
|
88
153
|
Only transient individual object-operation failures receive bounded retries.
|
|
89
|
-
Input, authorization,
|
|
90
|
-
|
|
154
|
+
Input, authorization, metadata, and public-verification failures are not
|
|
155
|
+
retried. A failed publish preserves the local package.
|
|
91
156
|
|
|
92
157
|
Public roots must be credential-free HTTPS URLs with no username, password,
|
|
93
|
-
query, or fragment.
|
|
94
|
-
|
|
158
|
+
query, or fragment. Three further rejections apply, all before any AWS or HTTP
|
|
159
|
+
operation, and none of them are ever persisted in receipts:
|
|
160
|
+
|
|
161
|
+
- **Control characters.** Any codepoint in `0x00`–`0x1f` or `0x7f`–`0x9f`, and
|
|
162
|
+
any backslash, in either root. These otherwise reach S3 object keys, composed
|
|
163
|
+
public URLs, the catalog, the receipt and `aws` argv; `0x9b` is the 8-bit CSI.
|
|
164
|
+
- **Non-public addresses.** Loopback, link-local (`169.254.0.0/16`, `fe80::/10`,
|
|
165
|
+
including the `169.254.169.254` instance-metadata address), unique-local
|
|
166
|
+
(`fc00::/7`) and RFC 1918 private hosts, in both literal IPv4 and IPv6 forms
|
|
167
|
+
including IPv4-mapped spellings. Public verification issues an outbound GET
|
|
168
|
+
against whatever the root names, so an unconstrained root is a request
|
|
169
|
+
primitive aimed at internal addresses. Set
|
|
170
|
+
`EXPLAINER_KIT_ALLOW_PRIVATE_PUBLIC_ROOT=1` to opt back in for a genuinely
|
|
171
|
+
internal mirror. The policy is address-literal only: a hostname that happens
|
|
172
|
+
to resolve inward is not detected.
|
|
173
|
+
- **Redirects.** Public verification uses `redirect: 'error'`. A canonical
|
|
174
|
+
artifact URL is uploaded to a known key and should never legitimately
|
|
175
|
+
redirect, so any redirecting destination is a hard verification failure rather
|
|
176
|
+
than something to follow. A destination that requires redirects is
|
|
177
|
+
incompatible with this connector and will report as such rather than failing
|
|
178
|
+
opaquely later.
|
|
179
|
+
|
|
180
|
+
## The generated initiative catalog
|
|
181
|
+
|
|
182
|
+
The connector generates one auxiliary artifact the manifest does not declare: an
|
|
183
|
+
initiative catalog at `site/initiatives/<slug>/catalog.json`, uploaded alongside
|
|
184
|
+
the declared artifacts and recorded in the receipt as
|
|
185
|
+
`source: { kind: 'auxiliary', name: 'catalog' }`.
|
|
186
|
+
|
|
187
|
+
A third-party connector must reproduce it **byte for byte**, because
|
|
188
|
+
`recordDurability` rebuilds it from the manifest and compares hashes; a mismatch
|
|
189
|
+
rejects the publication with `cross-record-mismatch`. Build it with
|
|
190
|
+
`catalogFromManifest(manifest, publicBaseUrl, { publicAccess })` and serialize
|
|
191
|
+
with `serializeInitiativeCatalog`, rather than constructing it by hand.
|
|
192
|
+
|
|
193
|
+
Two properties matter most:
|
|
194
|
+
|
|
195
|
+
- The `{ publicAccess }` option is **required**. Omitting it raises a
|
|
196
|
+
`TypeError` rather than defaulting, because the policy selects a field inside
|
|
197
|
+
the serialized bytes and therefore changes the hash. Pass
|
|
198
|
+
`{ publicAccess: undefined }` for `publish-request/v1`, which has no such
|
|
199
|
+
field and is public by definition.
|
|
200
|
+
- `publicVerification` carries **policy, never outcome**: `"required"` for
|
|
201
|
+
public destinations and `"skipped-by-policy"` for protected ones. The catalog
|
|
202
|
+
is serialized and hashed before the first upload and long before any
|
|
203
|
+
per-artifact verification runs, so it cannot carry a verification result
|
|
204
|
+
without invalidating its own hash. The authoritative outcome lives in the
|
|
205
|
+
publish receipt, which the catalog's `runId` identifies. Never write
|
|
206
|
+
`"verified"` into a catalog.
|
|
207
|
+
|
|
208
|
+
Publishability is gated by `assertManifestPublishable`, which raises
|
|
209
|
+
`E_PUBLISH_OUTCOME` for a manifest that is not eligible; see the intermediate
|
|
210
|
+
`incomplete` state described above.
|