@erclx/aitk 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/LICENSE +21 -0
- package/README.md +99 -0
- package/claude/.claude-plugin/plugin.json +19 -0
- package/claude/skills/bash-script/SKILL.md +96 -0
- package/claude/skills/bash-script/references/patterns.md +349 -0
- package/claude/skills/ci-workflow/SKILL.md +52 -0
- package/claude/skills/ci-workflow/references/workflows.md +74 -0
- package/claude/skills/claude-address-review/SKILL.md +107 -0
- package/claude/skills/claude-autoship/SKILL.md +137 -0
- package/claude/skills/claude-design-extract/SKILL.md +69 -0
- package/claude/skills/claude-design-propose/SKILL.md +75 -0
- package/claude/skills/claude-diagram/SKILL.md +126 -0
- package/claude/skills/claude-docs/SKILL.md +204 -0
- package/claude/skills/claude-feature/REQUIREMENT.md +35 -0
- package/claude/skills/claude-feature/SKILL.md +148 -0
- package/claude/skills/claude-groundwork/SKILL.md +148 -0
- package/claude/skills/claude-groundwork/references/folder-format.md +107 -0
- package/claude/skills/claude-memory-capture/SKILL.md +80 -0
- package/claude/skills/claude-memory-review/REQUIREMENT.md +37 -0
- package/claude/skills/claude-memory-review/SKILL.md +206 -0
- package/claude/skills/claude-orchestrate/SKILL.md +125 -0
- package/claude/skills/claude-pr-review/SKILL.md +150 -0
- package/claude/skills/claude-review/SKILL.md +136 -0
- package/claude/skills/claude-roadmap/SKILL.md +61 -0
- package/claude/skills/claude-roadmap/references/roadmap.md +52 -0
- package/claude/skills/claude-screencast/SKILL.md +160 -0
- package/claude/skills/claude-seed-sync/SKILL.md +141 -0
- package/claude/skills/claude-slides-draft/SKILL.md +62 -0
- package/claude/skills/claude-standards-audit/REQUIREMENT.md +33 -0
- package/claude/skills/claude-standards-audit/SKILL.md +79 -0
- package/claude/skills/claude-standards-audit/references/branch.md +49 -0
- package/claude/skills/claude-standards-audit/references/pr.md +124 -0
- package/claude/skills/claude-tasks/SKILL.md +123 -0
- package/claude/skills/claude-ui-test/SKILL.md +75 -0
- package/claude/skills/claude-ux-audit/SKILL.md +78 -0
- package/claude/skills/claude-worktree/SKILL.md +79 -0
- package/claude/skills/cli-script/SKILL.md +47 -0
- package/claude/skills/cli-script/references/template.md +43 -0
- package/claude/skills/create-rule/SKILL.md +68 -0
- package/claude/skills/create-skill/REQUIREMENT.md +30 -0
- package/claude/skills/create-skill/SKILL.md +24 -0
- package/claude/skills/create-snippet/SKILL.md +28 -0
- package/claude/skills/create-snippet/references/snippets.md +57 -0
- package/claude/skills/create-standard/SKILL.md +31 -0
- package/claude/skills/create-standard/references/standard.md +52 -0
- package/claude/skills/docs-sync/SKILL.md +87 -0
- package/claude/skills/git-branch/REQUIREMENT.md +38 -0
- package/claude/skills/git-branch/SKILL.md +60 -0
- package/claude/skills/git-branch/references/branch.md +49 -0
- package/claude/skills/git-commit/REQUIREMENT.md +33 -0
- package/claude/skills/git-commit/SKILL.md +51 -0
- package/claude/skills/git-commit/references/commit.md +63 -0
- package/claude/skills/git-followup/REQUIREMENT.md +38 -0
- package/claude/skills/git-followup/SKILL.md +35 -0
- package/claude/skills/git-issue/REQUIREMENT.md +38 -0
- package/claude/skills/git-issue/SKILL.md +69 -0
- package/claude/skills/git-issue/references/issue.md +84 -0
- package/claude/skills/git-pr/REQUIREMENT.md +37 -0
- package/claude/skills/git-pr/SKILL.md +119 -0
- package/claude/skills/git-pr/references/branch.md +49 -0
- package/claude/skills/git-pr/references/pr.md +124 -0
- package/claude/skills/git-ship/REQUIREMENT.md +34 -0
- package/claude/skills/git-ship/SKILL.md +39 -0
- package/claude/skills/git-split/REQUIREMENT.md +38 -0
- package/claude/skills/git-split/SKILL.md +160 -0
- package/claude/skills/git-split/references/branch.md +49 -0
- package/claude/skills/git-split/references/pr.md +124 -0
- package/claude/skills/git-stage/REQUIREMENT.md +36 -0
- package/claude/skills/git-stage/SKILL.md +74 -0
- package/claude/skills/git-stage/references/commit.md +63 -0
- package/claude/skills/git-worktree/REQUIREMENT.md +37 -0
- package/claude/skills/git-worktree/SKILL.md +120 -0
- package/claude/skills/migration-claude-md/SKILL.md +74 -0
- package/claude/skills/migration-context/SKILL.md +93 -0
- package/claude/skills/migration-standards/SKILL.md +75 -0
- package/claude/skills/project-commands/SKILL.md +73 -0
- package/claude/skills/session-resume/SKILL.md +36 -0
- package/claude/skills/setup-gov/SKILL.md +71 -0
- package/claude/skills/setup-indexes/SKILL.md +148 -0
- package/claude/skills/setup-init/SKILL.md +114 -0
- package/claude/skills/setup-plugins/SKILL.md +81 -0
- package/claude/skills/setup-plugins/references/plugin-catalog.md +53 -0
- package/claude/skills/setup-verify/SKILL.md +51 -0
- package/claude/skills/systematic-debugging/SKILL.md +70 -0
- package/claude/skills/toolkit-cli/SKILL.md +38 -0
- package/claude/skills/toolkit-feedback/SKILL.md +80 -0
- package/claude/skills/toolkit-operator/SKILL.md +45 -0
- package/claude/skills/toolkit-triage/SKILL.md +63 -0
- package/claude/skills/youtube-transcripts/SKILL.md +34 -0
- package/docs/agents.md +371 -0
- package/docs/ai-workflow.md +157 -0
- package/docs/index.md +20 -0
- package/docs/operating-model.md +106 -0
- package/docs/target-projects.md +183 -0
- package/docs/visual-design-workflow.md +136 -0
- package/docs/zshrc-aliases.md +65 -0
- package/governance/rules/claude/500-prose.md +12 -0
- package/governance/rules/claude/510-context.md +16 -0
- package/governance/rules/claude/520-wireframes.md +12 -0
- package/governance/rules/claude/530-requirements.md +11 -0
- package/governance/rules/claude/540-architecture.md +11 -0
- package/governance/rules/claude/550-design.md +11 -0
- package/governance/rules/claude/555-tasks.md +12 -0
- package/governance/rules/claude/560-diagrams.md +11 -0
- package/governance/rules/claude/570-skill.md +18 -0
- package/governance/rules/claude/580-readme.md +11 -0
- package/governance/rules/claude/590-rule-authoring.md +12 -0
- package/governance/rules/core/000-constitution.md +30 -0
- package/governance/rules/core/010-testing.md +35 -0
- package/governance/rules/core/020-concurrency.md +22 -0
- package/governance/rules/core/030-error-handling.md +31 -0
- package/governance/rules/core/040-performance.md +20 -0
- package/governance/rules/core/050-logging.md +20 -0
- package/governance/rules/core/060-naming.md +19 -0
- package/governance/rules/core/070-planning.md +13 -0
- package/governance/rules/core/080-config-comments.md +22 -0
- package/governance/rules/framework/200-react.md +51 -0
- package/governance/rules/framework/210-astro.md +41 -0
- package/governance/rules/framework/220-fastapi.md +43 -0
- package/governance/rules/framework/230-nextjs.md +48 -0
- package/governance/rules/framework/250-tailwind.md +32 -0
- package/governance/rules/framework/260-shadcn.md +34 -0
- package/governance/rules/lang/100-typescript.md +40 -0
- package/governance/rules/lang/110-python.md +42 -0
- package/governance/rules/lib/300-testing-ts.md +38 -0
- package/governance/rules/lib/310-zod.md +25 -0
- package/governance/rules/lib/320-tanstack-query.md +32 -0
- package/governance/rules/lib/330-testing-py.md +44 -0
- package/governance/rules/lib/340-pydantic.md +38 -0
- package/governance/rules/lib/350-security-web.md +31 -0
- package/governance/rules/ui/400-ui.md +34 -0
- package/governance/rules/ui/410-a11y.md +44 -0
- package/governance/rules/ui/420-forms.md +34 -0
- package/governance/rules/ui/430-ux-completeness.md +62 -0
- package/governance/stacks/astro.toml +2 -0
- package/governance/stacks/base.toml +2 -0
- package/governance/stacks/node.toml +2 -0
- package/governance/stacks/python-fastapi.toml +2 -0
- package/governance/stacks/python.toml +2 -0
- package/governance/stacks/react.toml +2 -0
- package/package.json +67 -0
- package/scripts/config.sh +11 -0
- package/scripts/core/bootstrap.sh +81 -0
- package/scripts/core/check-plugin-boundary.sh +45 -0
- package/scripts/core/check-skill-paths.sh +25 -0
- package/scripts/core/clean.sh +36 -0
- package/scripts/core/install-check.sh +93 -0
- package/scripts/core/regen-claude-copies.sh +26 -0
- package/scripts/core/regen-indexes.sh +10 -0
- package/scripts/core/regen-skill-references.sh +27 -0
- package/scripts/core/snapshot.sh +132 -0
- package/scripts/core/update.sh +35 -0
- package/scripts/core/verify.sh +201 -0
- package/scripts/docs/list.sh +129 -0
- package/scripts/gov/list.sh +234 -0
- package/scripts/lib/frontmatter.sh +30 -0
- package/scripts/lib/gov.sh +14 -0
- package/scripts/lib/sandbox-fixtures.sh +109 -0
- package/scripts/lib/sandbox-git.sh +73 -0
- package/scripts/lib/tooling.sh +24 -0
- package/scripts/lib/ui.sh +173 -0
- package/scripts/lib/worktree.sh +20 -0
- package/scripts/manage-sandbox.sh +453 -0
- package/scripts/snippets/create.sh +156 -0
- package/scripts/standards/list.sh +91 -0
- package/scripts/tooling/create.sh +109 -0
- package/scripts/tooling/ref.sh +141 -0
- package/scripts/tooling/verify.sh +179 -0
- package/snippets/claude/decision-memo.md +39 -0
- package/snippets/claude/feature-recap.md +19 -0
- package/snippets/claude/figma-steps.md +18 -0
- package/snippets/claude/orchestrator-resume.md +23 -0
- package/snippets/claude/orchestrator-sweep.md +10 -0
- package/snippets/compact-summary.md +5 -0
- package/snippets/create-snippet.md +7 -0
- package/snippets/decision-help.md +6 -0
- package/snippets/meta-prompt.md +14 -0
- package/snippets/research-prompt.md +7 -0
- package/snippets/session-notes.md +11 -0
- package/snippets/snippets.toml +6 -0
- package/snippets/step-by-step.md +10 -0
- package/snippets/web-research.md +21 -0
- package/src/claude/gitignore.ts +51 -0
- package/src/claude/seeds-list.ts +47 -0
- package/src/claude/seeds.ts +124 -0
- package/src/claude/settings.ts +151 -0
- package/src/cli-run.ts +43 -0
- package/src/cli.ts +111 -0
- package/src/commands/claude.ts +349 -0
- package/src/commands/design.ts +39 -0
- package/src/commands/docs.ts +59 -0
- package/src/commands/feedback-format.ts +23 -0
- package/src/commands/feedback.ts +103 -0
- package/src/commands/gov.ts +268 -0
- package/src/commands/indexes.ts +182 -0
- package/src/commands/init.ts +117 -0
- package/src/commands/pass-through.ts +39 -0
- package/src/commands/sandbox.ts +315 -0
- package/src/commands/slides.ts +106 -0
- package/src/commands/snippets.ts +236 -0
- package/src/commands/standards.ts +89 -0
- package/src/commands/sync.ts +211 -0
- package/src/commands/tasks.ts +185 -0
- package/src/commands/tooling.ts +432 -0
- package/src/commands/transcripts.ts +48 -0
- package/src/commands/wiki.ts +101 -0
- package/src/copy.ts +30 -0
- package/src/design/parse.ts +79 -0
- package/src/design/render.ts +170 -0
- package/src/docs/read.ts +59 -0
- package/src/exec.ts +17 -0
- package/src/frontmatter.ts +13 -0
- package/src/github-format.ts +13 -0
- package/src/github.ts +20 -0
- package/src/gov/adapter.ts +73 -0
- package/src/gov/install.ts +103 -0
- package/src/gov/payload.ts +39 -0
- package/src/gov/stacks.ts +124 -0
- package/src/indexes/frontmatter.ts +46 -0
- package/src/indexes/regen.ts +84 -0
- package/src/indexes/render.ts +181 -0
- package/src/indexes/walk.ts +111 -0
- package/src/init/flags.ts +66 -0
- package/src/init/plan.ts +128 -0
- package/src/init/run.ts +46 -0
- package/src/init/steps.ts +91 -0
- package/src/sandbox/coverage.ts +115 -0
- package/src/sandbox/expect.ts +412 -0
- package/src/slides/layouts.ts +391 -0
- package/src/slides/open.ts +18 -0
- package/src/slides/parse.ts +84 -0
- package/src/slides/render.ts +88 -0
- package/src/slides/styles.ts +44 -0
- package/src/snippets/adapter.ts +34 -0
- package/src/snippets/categories.ts +59 -0
- package/src/snippets/install.ts +125 -0
- package/src/snippets/list.ts +32 -0
- package/src/snippets/presets.ts +50 -0
- package/src/standards/adapter.ts +51 -0
- package/src/standards/index-refresh.ts +44 -0
- package/src/standards/install.ts +52 -0
- package/src/sync/check.ts +269 -0
- package/src/sync/engine.ts +416 -0
- package/src/sync/git.ts +204 -0
- package/src/sync/stamp.ts +202 -0
- package/src/sync/target.ts +79 -0
- package/src/sync/workflow.ts +201 -0
- package/src/target.ts +43 -0
- package/src/tasks/archive.ts +304 -0
- package/src/tooling/gitignore.ts +122 -0
- package/src/tooling/inject.ts +214 -0
- package/src/tooling/list.ts +39 -0
- package/src/tooling/manifest.ts +178 -0
- package/src/tooling/package.ts +166 -0
- package/src/tooling/scan.ts +186 -0
- package/src/transcripts/fetch.ts +156 -0
- package/src/transcripts/metadata.ts +54 -0
- package/src/transcripts/vtt.ts +114 -0
- package/src/ui.ts +187 -0
- package/src/wiki/init.ts +85 -0
- package/standards/architecture.md +41 -0
- package/standards/bundled/branch.md +49 -0
- package/standards/bundled/commit.md +63 -0
- package/standards/bundled/issue.md +84 -0
- package/standards/bundled/pr.md +124 -0
- package/standards/bundled/roadmap.md +52 -0
- package/standards/bundled/snippets.md +57 -0
- package/standards/bundled/standard.md +52 -0
- package/standards/context.md +132 -0
- package/standards/design.md +31 -0
- package/standards/diagrams.md +55 -0
- package/standards/index.md +21 -0
- package/standards/prose.md +122 -0
- package/standards/readme.md +163 -0
- package/standards/requirements.md +61 -0
- package/standards/rule.md +79 -0
- package/standards/skill.md +257 -0
- package/standards/tasks.md +140 -0
- package/standards/versioning.md +47 -0
- package/standards/wireframes.md +67 -0
- package/tooling/astro/configs/astro.config.mjs +17 -0
- package/tooling/astro/configs/eslint.config.js +79 -0
- package/tooling/astro/configs/playwright.config.ts +25 -0
- package/tooling/astro/configs/tsconfig.json +12 -0
- package/tooling/astro/configs/vitest.config.ts +22 -0
- package/tooling/astro/manifest.toml +32 -0
- package/tooling/astro/reference.md +60 -0
- package/tooling/base/configs/.editorconfig +5 -0
- package/tooling/base/configs/.github/pull_request_template.md +18 -0
- package/tooling/base/configs/.github/workflows/verify.yml +35 -0
- package/tooling/base/configs/.husky/commit-msg +1 -0
- package/tooling/base/configs/.husky/post-merge +61 -0
- package/tooling/base/configs/.husky/post-rewrite +21 -0
- package/tooling/base/configs/.husky/pre-commit +1 -0
- package/tooling/base/configs/.husky/pre-push +1 -0
- package/tooling/base/configs/.prettierrc +12 -0
- package/tooling/base/configs/.shellcheckrc +1 -0
- package/tooling/base/configs/.vscode/extensions.json +9 -0
- package/tooling/base/configs/.vscode/settings.json +3 -0
- package/tooling/base/configs/commitlint.config.js +11 -0
- package/tooling/base/configs/scripts/clean.sh +45 -0
- package/tooling/base/configs/scripts/update.sh +49 -0
- package/tooling/base/configs/scripts/verify.sh +64 -0
- package/tooling/base/manifest.toml +32 -0
- package/tooling/base/reference.md +114 -0
- package/tooling/base/seeds/.claude/context/ci.md +27 -0
- package/tooling/base/seeds/.claude/context/development.md +32 -0
- package/tooling/base/seeds/.cspell/project-terms.txt +0 -0
- package/tooling/base/seeds/.cspell/tech-stack.txt +19 -0
- package/tooling/base/seeds/.lintstagedrc +8 -0
- package/tooling/base/seeds/.prettierignore +0 -0
- package/tooling/base/seeds/cspell.json +20 -0
- package/tooling/claude/manifest.toml +11 -0
- package/tooling/claude/reference.md +62 -0
- package/tooling/claude/seeds/.claude/ARCHITECTURE.md +13 -0
- package/tooling/claude/seeds/.claude/DESIGN.md +62 -0
- package/tooling/claude/seeds/.claude/REQUIREMENTS.md +18 -0
- package/tooling/claude/seeds/.claude/context/index.md +8 -0
- package/tooling/claude/seeds/.claude/hooks/index-reminder.sh +43 -0
- package/tooling/claude/seeds/.claude/hooks/scratch-guard.sh +45 -0
- package/tooling/claude/seeds/.claude/hooks/standards-audit.sh +61 -0
- package/tooling/claude/seeds/.claude/hooks/tasks-index.sh +60 -0
- package/tooling/claude/seeds/.claude/settings.json +39 -0
- package/tooling/claude/seeds/.claude/tasks/index.md +8 -0
- package/tooling/claude/seeds/.claude/wireframes/index.md +8 -0
- package/tooling/claude/seeds/CLAUDE.md +87 -0
- package/tooling/claude/user/settings.template.json +10 -0
- package/tooling/claude/user/statusline-command.sh +53 -0
- package/tooling/python/configs/.coveragerc +14 -0
- package/tooling/python/configs/.python-version +1 -0
- package/tooling/python/configs/mypy.ini +6 -0
- package/tooling/python/configs/pytest.ini +4 -0
- package/tooling/python/configs/ruff.toml +15 -0
- package/tooling/python/configs/scripts/verify.sh +77 -0
- package/tooling/python/manifest.toml +16 -0
- package/tooling/python/reference.md +66 -0
- package/tooling/python/seeds/.cspell/tech-stack.txt +19 -0
- package/tooling/python/seeds/tests/test_smoke.py +2 -0
- package/tooling/vite-react/configs/playwright.config.ts +25 -0
- package/tooling/vite-react/configs/tsconfig.json +35 -0
- package/tooling/vite-react/configs/vite.config.ts +14 -0
- package/tooling/vite-react/configs/vitest.config.ts +26 -0
- package/tooling/vite-react/manifest.toml +21 -0
- package/tooling/vite-react/reference.md +55 -0
- package/tooling/vite-react/seeds/.cspell/project-terms.txt +1 -0
- package/tooling/vite-react/seeds/.cspell/tech-stack.txt +1 -0
- package/tooling/web/configs/.github/workflows/verify.yml +134 -0
- package/tooling/web/configs/.vscode/extensions.json +13 -0
- package/tooling/web/configs/.vscode/settings.json +10 -0
- package/tooling/web/configs/e2e/home.spec.ts +6 -0
- package/tooling/web/configs/e2e/screenshot.ts +41 -0
- package/tooling/web/configs/eslint.config.js +82 -0
- package/tooling/web/configs/scripts/screenshot.sh +28 -0
- package/tooling/web/configs/scripts/verify.sh +80 -0
- package/tooling/web/configs/src/test/setup.ts +8 -0
- package/tooling/web/manifest.toml +57 -0
- package/tooling/web/reference.md +95 -0
- package/tooling/web/seeds/.cspell/tech-stack.txt +18 -0
- package/tsconfig.json +14 -0
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -e
|
|
3
|
+
set -o pipefail
|
|
4
|
+
|
|
5
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
6
|
+
PROJECT_ROOT="${PROJECT_ROOT:-$(cd "$SCRIPT_DIR/../.." && pwd)}"
|
|
7
|
+
|
|
8
|
+
source "$PROJECT_ROOT/scripts/lib/ui.sh"
|
|
9
|
+
source "$PROJECT_ROOT/scripts/lib/worktree.sh"
|
|
10
|
+
|
|
11
|
+
NESTED="${VERIFY_NESTED:-false}"
|
|
12
|
+
WRITE="${VERIFY_WRITE:-true}"
|
|
13
|
+
SCOPED=true
|
|
14
|
+
CHANGED_FILES=""
|
|
15
|
+
|
|
16
|
+
check_dependencies() {
|
|
17
|
+
command -v bun >/dev/null 2>&1 || log_error "bun is not installed"
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
print_usage() {
|
|
21
|
+
echo "Usage: bun run check [--all]"
|
|
22
|
+
echo " --all Run every stage instead of scoping shell, types, and tests to changed files"
|
|
23
|
+
echo " --help Print this message"
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
parse_args() {
|
|
27
|
+
local arg
|
|
28
|
+
for arg in "$@"; do
|
|
29
|
+
case "$arg" in
|
|
30
|
+
--all) SCOPED=false ;;
|
|
31
|
+
-h | --help)
|
|
32
|
+
print_usage
|
|
33
|
+
exit 0
|
|
34
|
+
;;
|
|
35
|
+
*) log_error "Unknown argument: $arg" ;;
|
|
36
|
+
esac
|
|
37
|
+
done
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
# Union of the branch's committed diff, the working tree, and untracked files.
|
|
41
|
+
# A wider set only means running more stages, so every fallback widens.
|
|
42
|
+
collect_changed_files() {
|
|
43
|
+
[ "$SCOPED" = true ] || return 0
|
|
44
|
+
|
|
45
|
+
local base head local_baseline=false
|
|
46
|
+
# origin/main, not local main. On main itself the local ref is HEAD, so a commit
|
|
47
|
+
# not yet pushed would drop out of the changed set and skip the scoped stages.
|
|
48
|
+
base=$(git -C "$PROJECT_ROOT" merge-base HEAD origin/main 2>/dev/null) || base=""
|
|
49
|
+
if [ -z "$base" ]; then
|
|
50
|
+
local_baseline=true
|
|
51
|
+
base=$(git -C "$PROJECT_ROOT" merge-base HEAD main 2>/dev/null) || base=""
|
|
52
|
+
fi
|
|
53
|
+
if [ -z "$base" ]; then
|
|
54
|
+
SCOPED=false
|
|
55
|
+
log_warn "No merge base with main. Running every stage."
|
|
56
|
+
return 0
|
|
57
|
+
fi
|
|
58
|
+
|
|
59
|
+
# Without a remote baseline, a merge base equal to HEAD hides committed work.
|
|
60
|
+
if [ "$local_baseline" = true ]; then
|
|
61
|
+
head=$(git -C "$PROJECT_ROOT" rev-parse HEAD 2>/dev/null) || head=""
|
|
62
|
+
if [ -z "$head" ] || [ "$base" = "$head" ]; then
|
|
63
|
+
SCOPED=false
|
|
64
|
+
log_warn "No pushed baseline to compare against. Running every stage."
|
|
65
|
+
return 0
|
|
66
|
+
fi
|
|
67
|
+
fi
|
|
68
|
+
|
|
69
|
+
CHANGED_FILES=$({
|
|
70
|
+
git -C "$PROJECT_ROOT" diff --name-only "$base" HEAD
|
|
71
|
+
git -C "$PROJECT_ROOT" diff --name-only HEAD
|
|
72
|
+
git -C "$PROJECT_ROOT" ls-files --others --exclude-standard
|
|
73
|
+
} | sort -u)
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
has_changed() {
|
|
77
|
+
[ "$SCOPED" = true ] || return 0
|
|
78
|
+
printf '%s\n' "$CHANGED_FILES" | grep -qE "$1"
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
run_check() {
|
|
82
|
+
local cmd=$1
|
|
83
|
+
local err_msg=$2
|
|
84
|
+
local output
|
|
85
|
+
if ! output=$(eval "$cmd" 2>&1); then
|
|
86
|
+
echo "$output" | pipe_output
|
|
87
|
+
log_error "$err_msg"
|
|
88
|
+
fi
|
|
89
|
+
echo "$output" | pipe_output
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
# Whatever plugin and marketplace manifests the repo currently carries, so the
|
|
93
|
+
# stage picks up a new one without an edit here. Both listings honor .gitignore,
|
|
94
|
+
# which keeps linked worktrees and dependency copies out.
|
|
95
|
+
collect_plugin_manifests() {
|
|
96
|
+
{
|
|
97
|
+
git -C "$PROJECT_ROOT" ls-files -- '*.claude-plugin/plugin.json' '*.claude-plugin/marketplace.json'
|
|
98
|
+
git -C "$PROJECT_ROOT" ls-files --others --exclude-standard -- '*.claude-plugin/plugin.json' '*.claude-plugin/marketplace.json'
|
|
99
|
+
} | sort -u
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
assert_no_drift() {
|
|
103
|
+
local paths=$1
|
|
104
|
+
local err_msg=$2
|
|
105
|
+
run_check "cd $PROJECT_ROOT && git diff --exit-code --quiet -- $paths" "$err_msg"
|
|
106
|
+
run_check "cd $PROJECT_ROOT && [ -z \"\$(git ls-files --others --exclude-standard -- $paths)\" ]" "$err_msg"
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
main() {
|
|
110
|
+
check_dependencies
|
|
111
|
+
parse_args "$@"
|
|
112
|
+
|
|
113
|
+
if [ "$NESTED" = false ]; then echo -e "${GREY}┌${NC}"; fi
|
|
114
|
+
|
|
115
|
+
repair_bare_flag
|
|
116
|
+
collect_changed_files
|
|
117
|
+
|
|
118
|
+
if [ "$WRITE" = true ]; then
|
|
119
|
+
echo -e "${GREY}├${NC} ${WHITE}Formatting${NC}"
|
|
120
|
+
run_check "bun run format" "Format failed"
|
|
121
|
+
log_info "Format applied"
|
|
122
|
+
else
|
|
123
|
+
echo -e "${GREY}├${NC} ${WHITE}Format check${NC}"
|
|
124
|
+
run_check "bun run check:format" "Format check failed"
|
|
125
|
+
log_info "Format check passed"
|
|
126
|
+
fi
|
|
127
|
+
|
|
128
|
+
log_step "Indexes"
|
|
129
|
+
run_check "bash $PROJECT_ROOT/scripts/core/regen-indexes.sh" "Index regen failed"
|
|
130
|
+
assert_no_drift "'*index.md'" "Indexes drifted. Run bun run check and commit the updated index files."
|
|
131
|
+
log_info "Indexes clean"
|
|
132
|
+
|
|
133
|
+
log_step "Consumed copies"
|
|
134
|
+
run_check "bash $PROJECT_ROOT/scripts/core/regen-claude-copies.sh" "Consumed-copy regen failed"
|
|
135
|
+
assert_no_drift ".claude/standards .claude/snippets .claude/internal" "Consumed copies drifted. Run bun run check and commit .claude/standards, .claude/snippets, and .claude/internal."
|
|
136
|
+
log_info "Consumed copies clean"
|
|
137
|
+
|
|
138
|
+
log_step "Skill references"
|
|
139
|
+
run_check "bash $PROJECT_ROOT/scripts/core/regen-skill-references.sh" "Skill-reference regen failed"
|
|
140
|
+
assert_no_drift "claude/skills/*/references" "Skill references drifted. Run bun run check and commit the updated reference files."
|
|
141
|
+
log_info "Skill references clean"
|
|
142
|
+
|
|
143
|
+
log_step "Skill paths"
|
|
144
|
+
run_check "bash $PROJECT_ROOT/scripts/core/check-skill-paths.sh" "Shipped skills reference a repo-local path."
|
|
145
|
+
log_info "Skill paths clean"
|
|
146
|
+
|
|
147
|
+
log_step "Plugin boundary"
|
|
148
|
+
run_check "bash $PROJECT_ROOT/scripts/core/check-plugin-boundary.sh" "Plugin ships toolkit-internal content."
|
|
149
|
+
log_info "Plugin boundary clean"
|
|
150
|
+
|
|
151
|
+
log_step "Plugin manifests"
|
|
152
|
+
if ! command -v claude >/dev/null 2>&1; then
|
|
153
|
+
log_info "Skipped, claude is not installed"
|
|
154
|
+
else
|
|
155
|
+
local manifests manifest
|
|
156
|
+
manifests=$(collect_plugin_manifests)
|
|
157
|
+
if [ -z "$manifests" ]; then
|
|
158
|
+
log_info "Skipped, no manifests present"
|
|
159
|
+
else
|
|
160
|
+
while IFS= read -r manifest; do
|
|
161
|
+
run_check "cd $PROJECT_ROOT && claude plugin validate --strict '$manifest'" "Manifest validation failed: $manifest"
|
|
162
|
+
done <<<"$manifests"
|
|
163
|
+
log_info "Manifests valid"
|
|
164
|
+
fi
|
|
165
|
+
fi
|
|
166
|
+
|
|
167
|
+
log_step "Spelling"
|
|
168
|
+
run_check "bun run check:spell" "Spell check failed"
|
|
169
|
+
log_info "Spell check passed"
|
|
170
|
+
|
|
171
|
+
log_step "Shell"
|
|
172
|
+
if has_changed '\.sh$|^package\.json$'; then
|
|
173
|
+
run_check "bun run check:shell" "Shell check failed"
|
|
174
|
+
log_info "Shell check passed"
|
|
175
|
+
else
|
|
176
|
+
log_info "Skipped, no shell changes"
|
|
177
|
+
fi
|
|
178
|
+
|
|
179
|
+
log_step "Types"
|
|
180
|
+
if has_changed '^src/|^tsconfig\.json$|^package\.json$'; then
|
|
181
|
+
run_check "bun run check:types" "Typecheck failed"
|
|
182
|
+
log_info "Typecheck passed"
|
|
183
|
+
else
|
|
184
|
+
log_info "Skipped, no TypeScript changes"
|
|
185
|
+
fi
|
|
186
|
+
|
|
187
|
+
log_step "Tests"
|
|
188
|
+
if has_changed '^src/|^vitest\.config\.ts$|^tsconfig\.json$|^package\.json$'; then
|
|
189
|
+
run_check "bun run test" "Tests failed"
|
|
190
|
+
log_info "Tests passed"
|
|
191
|
+
else
|
|
192
|
+
log_info "Skipped, no TypeScript changes"
|
|
193
|
+
fi
|
|
194
|
+
|
|
195
|
+
if [ "$NESTED" = false ]; then
|
|
196
|
+
echo -e "${GREY}└${NC}\n"
|
|
197
|
+
echo -e "${GREEN}✓ Verification passed${NC}"
|
|
198
|
+
fi
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
main "$@"
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -e
|
|
3
|
+
set -o pipefail
|
|
4
|
+
|
|
5
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
6
|
+
PROJECT_ROOT="${PROJECT_ROOT:-$(dirname "$(dirname "$SCRIPT_DIR")")}"
|
|
7
|
+
|
|
8
|
+
source "$PROJECT_ROOT/scripts/lib/ui.sh"
|
|
9
|
+
source "$PROJECT_ROOT/scripts/lib/frontmatter.sh"
|
|
10
|
+
|
|
11
|
+
DOCS_DIR="$PROJECT_ROOT/docs"
|
|
12
|
+
CONTEXT_DIR="$PROJECT_ROOT/.claude/context"
|
|
13
|
+
|
|
14
|
+
INTERNAL_TOPICS=" ci development extensions sandbox "
|
|
15
|
+
|
|
16
|
+
show_help() {
|
|
17
|
+
echo -e "${GREY}┌${NC}"
|
|
18
|
+
echo -e "${GREY}├${NC} ${WHITE}Usage:${NC} aitk docs list [options]"
|
|
19
|
+
echo -e "${GREY}│${NC}"
|
|
20
|
+
echo -e "${GREY}│${NC} ${WHITE}Options:${NC}"
|
|
21
|
+
echo -e "${GREY}│${NC} --json ${GREY}# Emit machine-readable JSON${NC}"
|
|
22
|
+
echo -e "${GREY}│${NC} -h, --help ${GREY}# Show this help message${NC}"
|
|
23
|
+
echo -e "${GREY}└${NC}"
|
|
24
|
+
exit 0
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
is_target_facing() {
|
|
28
|
+
case "$1" in
|
|
29
|
+
"Agent surface" | "Domain references") return 0 ;;
|
|
30
|
+
*) return 1 ;;
|
|
31
|
+
esac
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
is_internal_topic() {
|
|
35
|
+
case "$INTERNAL_TOPICS" in
|
|
36
|
+
*" $1 "*) return 0 ;;
|
|
37
|
+
*) return 1 ;;
|
|
38
|
+
esac
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
list_text() {
|
|
42
|
+
local file name description category
|
|
43
|
+
log_step "Docs"
|
|
44
|
+
while IFS= read -r file; do
|
|
45
|
+
name=$(basename "$file" .md)
|
|
46
|
+
[ "$name" = "index" ] && continue
|
|
47
|
+
category=$(read_frontmatter_field "$file" "category")
|
|
48
|
+
is_target_facing "$category" || continue
|
|
49
|
+
description=$(read_frontmatter_field "$file" "description")
|
|
50
|
+
log_info "$name : $description"
|
|
51
|
+
done < <(find "$DOCS_DIR" -maxdepth 1 -type f -name "*.md" | sort)
|
|
52
|
+
|
|
53
|
+
# Absent in a registry install, which ships docs/ without .claude/
|
|
54
|
+
if [ -d "$CONTEXT_DIR" ]; then
|
|
55
|
+
log_step "Domain context"
|
|
56
|
+
while IFS= read -r file; do
|
|
57
|
+
name=$(basename "$file" .md)
|
|
58
|
+
[ "$name" = "index" ] && continue
|
|
59
|
+
is_internal_topic "$name" && continue
|
|
60
|
+
description=$(read_frontmatter_field "$file" "description")
|
|
61
|
+
log_info "$name : $description"
|
|
62
|
+
done < <(find "$CONTEXT_DIR" -maxdepth 1 -type f -name "*.md" | sort)
|
|
63
|
+
fi
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
emit_json_entry() {
|
|
67
|
+
local name="$1" description="$2" category="$3" target="$4"
|
|
68
|
+
[ "$JSON_FIRST" -eq 0 ] && printf ','
|
|
69
|
+
jq -nc \
|
|
70
|
+
--arg name "$name" \
|
|
71
|
+
--arg description "$description" \
|
|
72
|
+
--arg category "$category" \
|
|
73
|
+
--arg target "$target" \
|
|
74
|
+
'{name: $name, description: $description, category: $category, target: $target}'
|
|
75
|
+
JSON_FIRST=0
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
list_json() {
|
|
79
|
+
local file name description category
|
|
80
|
+
JSON_FIRST=1
|
|
81
|
+
printf '['
|
|
82
|
+
while IFS= read -r file; do
|
|
83
|
+
name=$(basename "$file" .md)
|
|
84
|
+
[ "$name" = "index" ] && continue
|
|
85
|
+
category=$(read_frontmatter_field "$file" "category")
|
|
86
|
+
is_target_facing "$category" || continue
|
|
87
|
+
description=$(read_frontmatter_field "$file" "description")
|
|
88
|
+
emit_json_entry "$name" "$description" "$category" "docs/$(basename "$file")"
|
|
89
|
+
done < <(find "$DOCS_DIR" -maxdepth 1 -type f -name "*.md" | sort)
|
|
90
|
+
|
|
91
|
+
if [ -d "$CONTEXT_DIR" ]; then
|
|
92
|
+
while IFS= read -r file; do
|
|
93
|
+
name=$(basename "$file" .md)
|
|
94
|
+
[ "$name" = "index" ] && continue
|
|
95
|
+
is_internal_topic "$name" && continue
|
|
96
|
+
description=$(read_frontmatter_field "$file" "description")
|
|
97
|
+
emit_json_entry "$name" "$description" "" ".claude/context/$(basename "$file")"
|
|
98
|
+
done < <(find "$CONTEXT_DIR" -maxdepth 1 -type f -name "*.md" | sort)
|
|
99
|
+
fi
|
|
100
|
+
printf ']'
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
main() {
|
|
104
|
+
local json=0
|
|
105
|
+
|
|
106
|
+
while [[ $# -gt 0 ]]; do
|
|
107
|
+
case "$1" in
|
|
108
|
+
-h | --help) show_help ;;
|
|
109
|
+
--json)
|
|
110
|
+
json=1
|
|
111
|
+
shift
|
|
112
|
+
;;
|
|
113
|
+
*) log_error "Unknown option: $1" ;;
|
|
114
|
+
esac
|
|
115
|
+
done
|
|
116
|
+
|
|
117
|
+
trap close_timeline EXIT
|
|
118
|
+
|
|
119
|
+
if [ "$json" -eq 1 ]; then
|
|
120
|
+
printf '{"docs":'
|
|
121
|
+
list_json
|
|
122
|
+
printf '}\n'
|
|
123
|
+
exit 0
|
|
124
|
+
fi
|
|
125
|
+
|
|
126
|
+
list_text
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
main "$@"
|
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -e
|
|
3
|
+
set -o pipefail
|
|
4
|
+
|
|
5
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
6
|
+
PROJECT_ROOT="${PROJECT_ROOT:-$(dirname "$(dirname "$SCRIPT_DIR")")}"
|
|
7
|
+
|
|
8
|
+
source "$PROJECT_ROOT/scripts/lib/ui.sh"
|
|
9
|
+
|
|
10
|
+
STACKS_DIR="$PROJECT_ROOT/governance/stacks"
|
|
11
|
+
RULES_DIR="$PROJECT_ROOT/governance/rules"
|
|
12
|
+
|
|
13
|
+
show_help() {
|
|
14
|
+
echo -e "${GREY}┌${NC}"
|
|
15
|
+
echo -e "${GREY}├${NC} ${WHITE}Usage:${NC} aitk gov list [options]"
|
|
16
|
+
echo -e "${GREY}│${NC}"
|
|
17
|
+
echo -e "${GREY}│${NC} ${WHITE}Options:${NC}"
|
|
18
|
+
echo -e "${GREY}│${NC} --stacks ${GREY}# Only list stacks${NC}"
|
|
19
|
+
echo -e "${GREY}│${NC} --rules ${GREY}# Only list rules${NC}"
|
|
20
|
+
echo -e "${GREY}│${NC} --json ${GREY}# Emit machine-readable JSON${NC}"
|
|
21
|
+
echo -e "${GREY}│${NC} -h, --help ${GREY}# Show this help message${NC}"
|
|
22
|
+
echo -e "${GREY}└${NC}"
|
|
23
|
+
exit 0
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
read_frontmatter_field() {
|
|
27
|
+
local file="$1"
|
|
28
|
+
local field="$2"
|
|
29
|
+
awk -v f="$field" '
|
|
30
|
+
BEGIN { fm = 0 }
|
|
31
|
+
/^---$/ { fm++; if (fm > 1) exit; next }
|
|
32
|
+
fm == 1 {
|
|
33
|
+
if (match($0, "^" f ":")) {
|
|
34
|
+
val = substr($0, RLENGTH + 1)
|
|
35
|
+
sub(/^[[:space:]]+/, "", val)
|
|
36
|
+
sub(/^[\x27"]/, "", val)
|
|
37
|
+
sub(/[\x27"]$/, "", val)
|
|
38
|
+
print val
|
|
39
|
+
exit
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
' "$file"
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
read_frontmatter_paths() {
|
|
46
|
+
local file="$1"
|
|
47
|
+
awk '
|
|
48
|
+
BEGIN { fm = 0; in_paths = 0 }
|
|
49
|
+
/^---$/ { fm++; if (fm > 1) exit; next }
|
|
50
|
+
fm == 1 {
|
|
51
|
+
if (in_paths) {
|
|
52
|
+
if (match($0, /^[[:space:]]*-[[:space:]]+/)) {
|
|
53
|
+
val = substr($0, RLENGTH + 1)
|
|
54
|
+
sub(/^[\x27"]/, "", val)
|
|
55
|
+
sub(/[\x27"]$/, "", val)
|
|
56
|
+
print val
|
|
57
|
+
next
|
|
58
|
+
}
|
|
59
|
+
in_paths = 0
|
|
60
|
+
}
|
|
61
|
+
if ($0 == "paths:") { in_paths = 1 }
|
|
62
|
+
}
|
|
63
|
+
' "$file"
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
rule_domain() {
|
|
67
|
+
local file="$1"
|
|
68
|
+
local rel="${file#"$RULES_DIR"/}"
|
|
69
|
+
echo "${rel%%/*}"
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
stack_rules_array() {
|
|
73
|
+
local toml="$1"
|
|
74
|
+
grep -oE '"[0-9]{3}-[a-z0-9-]+"' "$toml" | sed 's/"//g'
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
json_escape() {
|
|
78
|
+
local s="$1"
|
|
79
|
+
s="${s//\\/\\\\}"
|
|
80
|
+
s="${s//\"/\\\"}"
|
|
81
|
+
printf '%s' "$s"
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
list_stacks_text() {
|
|
85
|
+
log_step "Stacks"
|
|
86
|
+
local toml
|
|
87
|
+
for toml in "$STACKS_DIR"/*.toml; do
|
|
88
|
+
local name
|
|
89
|
+
name=$(basename "$toml" .toml)
|
|
90
|
+
local extends
|
|
91
|
+
extends=$(grep '^extends' "$toml" | cut -d'"' -f2)
|
|
92
|
+
local rule_count
|
|
93
|
+
rule_count=$(stack_rules_array "$toml" | wc -l)
|
|
94
|
+
if [ -n "$extends" ]; then
|
|
95
|
+
log_info "$name (extends: $extends, $rule_count rules)"
|
|
96
|
+
else
|
|
97
|
+
log_info "$name ($rule_count rules)"
|
|
98
|
+
fi
|
|
99
|
+
done
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
list_rules_text() {
|
|
103
|
+
log_step "Rules"
|
|
104
|
+
local file
|
|
105
|
+
while IFS= read -r file; do
|
|
106
|
+
local name
|
|
107
|
+
name=$(basename "$file" .md)
|
|
108
|
+
local domain
|
|
109
|
+
domain=$(rule_domain "$file")
|
|
110
|
+
local desc
|
|
111
|
+
desc=$(read_frontmatter_field "$file" "description")
|
|
112
|
+
log_info "$name [$domain] $desc"
|
|
113
|
+
done < <(find "$RULES_DIR" -type f -name "*.md" | sort)
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
list_stacks_json() {
|
|
117
|
+
local first=1
|
|
118
|
+
local toml
|
|
119
|
+
printf '['
|
|
120
|
+
for toml in "$STACKS_DIR"/*.toml; do
|
|
121
|
+
local name
|
|
122
|
+
name=$(basename "$toml" .toml)
|
|
123
|
+
local extends
|
|
124
|
+
extends=$(grep '^extends' "$toml" | cut -d'"' -f2)
|
|
125
|
+
local rules_json="["
|
|
126
|
+
local first_rule=1
|
|
127
|
+
local rule
|
|
128
|
+
while IFS= read -r rule; do
|
|
129
|
+
[ -z "$rule" ] && continue
|
|
130
|
+
if [ "$first_rule" -eq 0 ]; then
|
|
131
|
+
rules_json+=","
|
|
132
|
+
fi
|
|
133
|
+
rules_json+="\"$rule\""
|
|
134
|
+
first_rule=0
|
|
135
|
+
done < <(stack_rules_array "$toml")
|
|
136
|
+
rules_json+="]"
|
|
137
|
+
if [ "$first" -eq 0 ]; then
|
|
138
|
+
printf ','
|
|
139
|
+
fi
|
|
140
|
+
if [ -n "$extends" ]; then
|
|
141
|
+
printf '{"name":"%s","extends":"%s","rules":%s}' "$name" "$extends" "$rules_json"
|
|
142
|
+
else
|
|
143
|
+
printf '{"name":"%s","extends":null,"rules":%s}' "$name" "$rules_json"
|
|
144
|
+
fi
|
|
145
|
+
first=0
|
|
146
|
+
done
|
|
147
|
+
printf ']'
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
list_rules_json() {
|
|
151
|
+
local first=1
|
|
152
|
+
local file
|
|
153
|
+
printf '['
|
|
154
|
+
while IFS= read -r file; do
|
|
155
|
+
local name
|
|
156
|
+
name=$(basename "$file" .md)
|
|
157
|
+
local domain
|
|
158
|
+
domain=$(rule_domain "$file")
|
|
159
|
+
local desc
|
|
160
|
+
desc=$(read_frontmatter_field "$file" "description")
|
|
161
|
+
|
|
162
|
+
local paths_json="null"
|
|
163
|
+
local paths_collected=()
|
|
164
|
+
while IFS= read -r p; do
|
|
165
|
+
[ -n "$p" ] && paths_collected+=("$p")
|
|
166
|
+
done < <(read_frontmatter_paths "$file")
|
|
167
|
+
if [ "${#paths_collected[@]}" -gt 0 ]; then
|
|
168
|
+
paths_json="["
|
|
169
|
+
local first_p=1
|
|
170
|
+
local p
|
|
171
|
+
for p in "${paths_collected[@]}"; do
|
|
172
|
+
[ "$first_p" -eq 0 ] && paths_json+=","
|
|
173
|
+
paths_json+="\"$(json_escape "$p")\""
|
|
174
|
+
first_p=0
|
|
175
|
+
done
|
|
176
|
+
paths_json+="]"
|
|
177
|
+
fi
|
|
178
|
+
|
|
179
|
+
if [ "$first" -eq 0 ]; then
|
|
180
|
+
printf ','
|
|
181
|
+
fi
|
|
182
|
+
printf '{"name":"%s","domain":"%s","description":"%s","paths":%s}' \
|
|
183
|
+
"$name" "$domain" "$(json_escape "$desc")" "$paths_json"
|
|
184
|
+
first=0
|
|
185
|
+
done < <(find "$RULES_DIR" -type f -name "*.md" | sort)
|
|
186
|
+
printf ']'
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
main() {
|
|
190
|
+
local show_stacks=1
|
|
191
|
+
local show_rules=1
|
|
192
|
+
local json=0
|
|
193
|
+
|
|
194
|
+
while [[ $# -gt 0 ]]; do
|
|
195
|
+
case "$1" in
|
|
196
|
+
-h | --help) show_help ;;
|
|
197
|
+
--stacks)
|
|
198
|
+
show_rules=0
|
|
199
|
+
shift
|
|
200
|
+
;;
|
|
201
|
+
--rules)
|
|
202
|
+
show_stacks=0
|
|
203
|
+
shift
|
|
204
|
+
;;
|
|
205
|
+
--json)
|
|
206
|
+
json=1
|
|
207
|
+
shift
|
|
208
|
+
;;
|
|
209
|
+
*) log_error "Unknown option: $1" ;;
|
|
210
|
+
esac
|
|
211
|
+
done
|
|
212
|
+
|
|
213
|
+
trap close_timeline EXIT
|
|
214
|
+
|
|
215
|
+
if [ "$json" -eq 1 ]; then
|
|
216
|
+
printf '{'
|
|
217
|
+
if [ "$show_stacks" -eq 1 ]; then
|
|
218
|
+
printf '"stacks":'
|
|
219
|
+
list_stacks_json
|
|
220
|
+
[ "$show_rules" -eq 1 ] && printf ','
|
|
221
|
+
fi
|
|
222
|
+
if [ "$show_rules" -eq 1 ]; then
|
|
223
|
+
printf '"rules":'
|
|
224
|
+
list_rules_json
|
|
225
|
+
fi
|
|
226
|
+
printf '}\n'
|
|
227
|
+
exit 0
|
|
228
|
+
fi
|
|
229
|
+
|
|
230
|
+
[ "$show_stacks" -eq 1 ] && list_stacks_text
|
|
231
|
+
[ "$show_rules" -eq 1 ] && list_rules_text
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
main "$@"
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
|
|
3
|
+
# Reads one frontmatter field from a markdown file.
|
|
4
|
+
#
|
|
5
|
+
# Kept in bash because the list commands call it once per field per file
|
|
6
|
+
# inside a loop, where shelling into the CLI would cost a process per read.
|
|
7
|
+
# The index engine that used to live here is TypeScript, in src/indexes/.
|
|
8
|
+
read_frontmatter_field() {
|
|
9
|
+
local file="$1"
|
|
10
|
+
local key="$2"
|
|
11
|
+
awk -v key="$key" '
|
|
12
|
+
NR == 1 && /^---$/ { in_fm = 1; next }
|
|
13
|
+
in_fm && /^---$/ { exit }
|
|
14
|
+
in_fm {
|
|
15
|
+
prefix = key ": "
|
|
16
|
+
if (index($0, prefix) == 1) {
|
|
17
|
+
val = substr($0, length(prefix) + 1)
|
|
18
|
+
if (length(val) >= 2) {
|
|
19
|
+
first = substr(val, 1, 1)
|
|
20
|
+
last = substr(val, length(val), 1)
|
|
21
|
+
if ((first == "\"" && last == "\"") || (first == "'\''" && last == "'\''")) {
|
|
22
|
+
val = substr(val, 2, length(val) - 2)
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
print val
|
|
26
|
+
exit
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
' "$file"
|
|
30
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
|
|
3
|
+
# Sole survivor of the gov lib. Called once per rule file inside install and
|
|
4
|
+
# sandbox loops, where routing through the CLI would cost a process per file.
|
|
5
|
+
|
|
6
|
+
rule_subdir() {
|
|
7
|
+
local src="$1"
|
|
8
|
+
local rules_root="${2:-$PROJECT_ROOT/governance/rules}"
|
|
9
|
+
local rel="${src#"$rules_root/"}"
|
|
10
|
+
local subdir
|
|
11
|
+
subdir=$(dirname "$rel")
|
|
12
|
+
[ "$subdir" = "." ] && subdir=""
|
|
13
|
+
echo "$subdir"
|
|
14
|
+
}
|