@friedbotstudio/create-baseline 0.1.0 → 0.2.1
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 +5 -0
- package/bin/cli.js +8 -2
- package/obj/template/.claude/skills/audit-baseline/audit.sh +11 -5
- package/obj/template/.claude/skills/google-analytics/SKILL.md +129 -0
- package/obj/template/.claude/skills/google-analytics/references/audiences.md +389 -0
- package/obj/template/.claude/skills/google-analytics/references/bigquery.md +470 -0
- package/obj/template/.claude/skills/google-analytics/references/custom-dimensions.md +355 -0
- package/obj/template/.claude/skills/google-analytics/references/custom-events.md +383 -0
- package/obj/template/.claude/skills/google-analytics/references/data-management.md +416 -0
- package/obj/template/.claude/skills/google-analytics/references/debugview.md +364 -0
- package/obj/template/.claude/skills/google-analytics/references/events-fundamentals.md +398 -0
- package/obj/template/.claude/skills/google-analytics/references/gtag.md +502 -0
- package/obj/template/.claude/skills/google-analytics/references/gtm-integration.md +483 -0
- package/obj/template/.claude/skills/google-analytics/references/measurement-protocol.md +519 -0
- package/obj/template/.claude/skills/google-analytics/references/privacy.md +441 -0
- package/obj/template/.claude/skills/google-analytics/references/recommended-events.md +464 -0
- package/obj/template/.claude/skills/google-analytics/references/reporting.md +397 -0
- package/obj/template/.claude/skills/google-analytics/references/setup.md +344 -0
- package/obj/template/.claude/skills/google-analytics/references/user-tracking.md +417 -0
- package/obj/template/.claude/skills/optimize-seo/SKILL.md +313 -0
- package/obj/template/.claude/skills/optimize-seo/scripts/pagespeed.mjs +197 -0
- package/obj/template/.claude/skills/pagespeed-insights/LICENSE.md +37 -0
- package/obj/template/.claude/skills/pagespeed-insights/SKILL.md +446 -0
- package/obj/template/.claude/skills/pagespeed-insights/reference.md +50 -0
- package/obj/template/CLAUDE.md +3 -3
- package/obj/template/docs/init/seed.md +2 -2
- package/obj/template/manifest.json +27 -6
- package/package.json +7 -2
- package/src/CLAUDE.template.md +3 -3
- package/src/cli/install.js +14 -4
- package/src/seed.template.md +2 -2
- package/obj/template/.claude/hooks/lib/__pycache__/resume_writer.cpython-314.pyc +0 -0
package/src/CLAUDE.template.md
CHANGED
|
@@ -267,15 +267,15 @@ The vendored `impeccable` skill stays untouched (Article IX). `design-ui` is the
|
|
|
267
267
|
|
|
268
268
|
## Article XI — Skill provenance and the baseline manifest
|
|
269
269
|
|
|
270
|
-
|
|
270
|
+
A skill at `.claude/skills/<slug>/SKILL.md` is **baseline-owned** iff its YAML frontmatter declares `owner: baseline`. Every other skill on disk — those without an `owner:` field, or those declaring `owner: user` — is user/third-party and out-of-scope of baseline audit checks. Absence-of-`owner` is the deliberate default so a project with pre-existing skills can install the baseline without annotating any of its own files. The build script `scripts/build-manifest.mjs` reads each `owner:` value and emits the canonical baseline-skill set into `obj/template/manifest.json` under `owners.skills` (a JSON object mapping slug → `"baseline"`). The CLI mirrors this manifest verbatim to `<target>/.claude/.baseline-manifest.json` on install. The audit at `.claude/skills/audit-baseline/audit.sh` consumes `manifest.owners.skills` as the canonical baseline-skill enumeration — the previous hard-coded `EXPECTED_SKILLS` set is removed.
|
|
271
271
|
|
|
272
272
|
You SHALL:
|
|
273
273
|
|
|
274
|
-
1. **Declare ownership.**
|
|
274
|
+
1. **Declare baseline ownership only.** A SKILL.md that ships in the baseline SHALL declare `owner: baseline` in its frontmatter directly after `name:`. Authoring a user/third-party skill does NOT require any `owner:` annotation — absence is the default. Explicit `owner: user` is permitted but never required. The only frontmatter-related FAIL the audit emits is `invalid owner=<value>` (a present-but-malformed `owner:` field, e.g. typo). Missing-`owner:` is silently skipped.
|
|
275
275
|
2. **Trust the manifest.** The shipped `obj/template/manifest.json` (mirrored to `<target>/.claude/.baseline-manifest.json` on install) is the canonical record of baseline-owned skills and their content hashes. You SHALL NOT maintain a separate hard-coded list of baseline-skill slugs anywhere in the codebase.
|
|
276
276
|
3. **Re-derive on drift.** The audit re-derives sha256 hashes from `manifest.files` for every path under `.claude/skills/<slug>/` whose slug appears in `owners.skills`, and compares against on-disk content. Mismatches surface as `hash mismatch at <path>`. A baseline-listed slug missing from disk surfaces as `baseline skill missing`. These are hard FAIL — drift detection has no opt-out.
|
|
277
277
|
4. **Preserve constitutional citation.** This Article XI SHALL remain in CLAUDE.md AND in `src/CLAUDE.template.md` (byte-equal mirror). The genesis §17 in `docs/init/seed.md` SHALL remain present, with `src/seed.template.md` mirroring it. The audit verifies both citations and reports `CLAUDE.md missing Article XI citation` or `seed.md missing §17 citation` on absence.
|
|
278
|
-
5. **
|
|
278
|
+
5. **Out-of-scope skills don't break the audit.** Any skill on disk that doesn't declare `owner: baseline` is out-of-scope: excluded from the baseline count, the names-match check, and the hash-drift check. Installing the baseline into a project that already has its own skills is zero-friction — no per-file annotation required. Maintenance of those skills is the user's responsibility.
|
|
279
279
|
|
|
280
280
|
Cryptographic supply-chain attestation, signed lock files, and per-skill aggregate merkle hashes are non-goals. The per-file `manifest.files` map already covers every file in every skill directory. A future `npx @friedbotstudio/create-baseline upgrade` subcommand will consume `manifest.owners.skills` + `manifest.files` to re-overlay baseline-owned files safely while leaving user-added or locally-customized files untouched — that subcommand is out of scope of this Article.
|
|
281
281
|
|
package/src/cli/install.js
CHANGED
|
@@ -12,6 +12,15 @@ const NPMRC_TEMPLATE_PATH = join(PACKAGE_ROOT, 'src/.npmrc.template');
|
|
|
12
12
|
|
|
13
13
|
export const NEVER_TOUCH = Object.freeze(['.claude/project.json']);
|
|
14
14
|
export const SPECIAL_MERGE = Object.freeze(['.mcp.json']);
|
|
15
|
+
// Files present in the shipped template that must NOT be cp'd to target. These
|
|
16
|
+
// are reference artifacts the CLI consults from templateDir (or that ship for
|
|
17
|
+
// inspection-time provenance), never materialized at consumer project root.
|
|
18
|
+
// `manifest.json`: the shipped sha256 table. The CLI's runtime manifest lives
|
|
19
|
+
// at `target/.claude/.baseline-manifest.json` (written by writeBaselineManifest);
|
|
20
|
+
// `target/manifest.json` would be a confusing duplicate. Keep the file in the
|
|
21
|
+
// published tarball so anyone inspecting `node_modules/<pkg>/obj/template/` can
|
|
22
|
+
// see what shipped, but exclude it from the fresh/force install copy.
|
|
23
|
+
export const COPY_EXCLUDE = Object.freeze(['manifest.json']);
|
|
15
24
|
|
|
16
25
|
async function listFiles(root, base = root, acc = []) {
|
|
17
26
|
for (const entry of await readdir(root, { withFileTypes: true })) {
|
|
@@ -37,6 +46,7 @@ function makeFilter(opts) {
|
|
|
37
46
|
return (src, _dest) => {
|
|
38
47
|
const rel = relative(opts.templateRoot, src).split(sep).join('/');
|
|
39
48
|
if (rel === '') return true;
|
|
49
|
+
if (COPY_EXCLUDE.includes(rel)) return false;
|
|
40
50
|
if (NEVER_TOUCH.includes(rel) && opts.skipNeverTouch) return false;
|
|
41
51
|
if (SPECIAL_MERGE.includes(rel) && opts.skipSpecialMerge) return false;
|
|
42
52
|
return true;
|
|
@@ -76,18 +86,18 @@ async function materializeNpmrc(target) {
|
|
|
76
86
|
await writeFile(dst, bytes);
|
|
77
87
|
}
|
|
78
88
|
|
|
79
|
-
export async function freshInstall(templateDir, target) {
|
|
89
|
+
export async function freshInstall(templateDir, target, opts = {}) {
|
|
80
90
|
const filter = makeFilter({ templateRoot: templateDir, skipNeverTouch: false, skipSpecialMerge: true });
|
|
81
91
|
await cp(templateDir, target, { recursive: true, force: false, filter });
|
|
82
92
|
await applySpecialAndNeverTouch(templateDir, target);
|
|
83
|
-
await materializeNpmrc(target);
|
|
93
|
+
if (opts.withNpmrc === true) await materializeNpmrc(target);
|
|
84
94
|
await writeBaselineManifest(target);
|
|
85
95
|
}
|
|
86
96
|
|
|
87
|
-
export async function forceInstall(templateDir, target) {
|
|
97
|
+
export async function forceInstall(templateDir, target, opts = {}) {
|
|
88
98
|
const filter = makeFilter({ templateRoot: templateDir, skipNeverTouch: true, skipSpecialMerge: true });
|
|
89
99
|
await cp(templateDir, target, { recursive: true, force: true, filter });
|
|
90
100
|
await applySpecialAndNeverTouch(templateDir, target);
|
|
91
|
-
await materializeNpmrc(target);
|
|
101
|
+
if (opts.withNpmrc === true) await materializeNpmrc(target);
|
|
92
102
|
await writeBaselineManifest(target);
|
|
93
103
|
}
|
package/src/seed.template.md
CHANGED
|
@@ -576,9 +576,9 @@ Until `/init-project` runs, this section stays empty. Once populated, every fiel
|
|
|
576
576
|
|
|
577
577
|
## §17 — Skill provenance and the baseline manifest
|
|
578
578
|
|
|
579
|
-
|
|
579
|
+
A skill at `.claude/skills/<slug>/SKILL.md` is **baseline-owned** iff its YAML frontmatter declares `owner: baseline`. Baseline-owned skills are those that ship with the baseline; every other skill on disk — those without an `owner:` field, or those declaring `owner: user` — is user/third-party and out-of-scope of baseline audit checks. Absence-of-`owner` is the deliberate default so a project that already has its own skills can install the baseline without annotating any of those files. The build script `scripts/build-manifest.mjs` reads each `owner:` value at release time and emits the canonical baseline-skill set into `obj/template/manifest.json` under `owners.skills` (a JSON object mapping slug → `"baseline"`). The CLI mirrors this manifest verbatim to `<target>/.claude/.baseline-manifest.json` on `freshInstall`/`forceInstall`/`merge`.
|
|
580
580
|
|
|
581
|
-
The audit at `.claude/skills/audit-baseline/audit.sh` consumes `manifest.owners.skills` as the canonical baseline-skill enumeration (replacing the previous hard-coded `EXPECTED_SKILLS` set). For every baseline-owned skill, the audit re-derives sha256 hashes from `manifest.files` and compares against on-disk content; a mismatch is reported as `hash mismatch at <path>` against the named slug. A baseline skill present in the manifest but absent from disk is reported as `baseline skill missing`. A SKILL.md
|
|
581
|
+
The audit at `.claude/skills/audit-baseline/audit.sh` consumes `manifest.owners.skills` as the canonical baseline-skill enumeration (replacing the previous hard-coded `EXPECTED_SKILLS` set). For every baseline-owned skill, the audit re-derives sha256 hashes from `manifest.files` and compares against on-disk content; a mismatch is reported as `hash mismatch at <path>` against the named slug. A baseline skill present in the manifest but absent from disk is reported as `baseline skill missing`. A SKILL.md whose `owner:` field is present but carries an invalid value (anything other than `baseline` or `user`) is reported as `invalid owner=<value>`. SKILL.md files without an `owner:` field are treated as user/third-party and silently skipped — they are excluded from the baseline count, the names-match check, and the hash-drift check, so installing the baseline into a project that already has its own skills never breaks the audit.
|
|
582
582
|
|
|
583
583
|
The audit also verifies constitutional citation: CLAUDE.md SHALL contain the literal string "Article XI" and a reference to the manifest, and `docs/init/seed.md` SHALL contain "§17" and a manifest reference. Missing citations trigger FAIL with `CLAUDE.md missing Article XI citation` or `seed.md missing §17 citation`.
|
|
584
584
|
|
|
Binary file
|