baller-maester 0.1.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/CHANGELOG.md +26 -0
- package/LICENSE +21 -0
- package/README.md +142 -0
- package/bin/maester.mjs +7 -0
- package/dist/cli/main.d.ts +4 -0
- package/dist/cli/main.js +3760 -0
- package/dist/cli/main.js.map +1 -0
- package/dist/index.d.ts +546 -0
- package/dist/index.js +1819 -0
- package/dist/index.js.map +1 -0
- package/package.json +73 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project are documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [0.1.0] - 2026-05-13
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
- **Pretty CLI** styling layer — themed colors (truecolor → 256 → 16 → no-color downgrade ladder), Unicode glyph catalog with ASCII fallbacks, leveled logger with `--verbose`, `--quiet`, `--json` modes, panel/box rendering (light, heavy, rounded), table rendering, and width-aware breakpoints (tiny / compact / default).
|
|
12
|
+
- **Citadel initialization** flow (`maester init`) — interactive walkthrough for registering remote git repositories as sources, with an optional `includes` step per source, secret-guarded env-var-name validation, optional destination overrides, idempotent `.gitignore` updates, and an idempotent `maester:sync` script entry in `package.json` when present.
|
|
13
|
+
- **Maester configuration** flow (`maester publish`) — interactive walkthrough that writes a `maester.yaml` publish manifest at the repo root, including optional descriptions, categories, and tags per entry, plus a README.md suggestion when one exists.
|
|
14
|
+
- **Maester sync** (`maester sync [names...]`) — single-shot sync of every (or scoped) configured source using partial-clone + sparse-checkout, with per-source progress, atomic destination promotion, `.maester-source.json` provenance markers, destination-clobber guard, and `--json` NDJSON output. Continues past individual source failures; non-zero exit if any failed. Each source is either **manifest-driven** (the remote publishes its own `maester.yaml`) or **includes-driven** (the citadel declares an `includes` list on the source); both modes are processed by the same command. Includes-driven sources emit a `no-matches` warning when their includes resolve to zero files at the resolved ref.
|
|
15
|
+
- **CLI banner** — pre-rendered figlet specimen with full + compact variants. Shown only on `--help`, `--version`, and the first-run welcome screen; suppressed below 40 cells and on non-TTY output. Opt-out via `--no-welcome` or `MAESTER_NO_WELCOME=1`.
|
|
16
|
+
- **Citadel status** (`maester status [names...]`) — read-only freshness check that reports each configured source as `up-to-date`, `behind`, or `failed` using a three-signal probe (never-synced, remote-ref-advanced, manifest-changed). Behind-aware exit codes (`0` / `1` / `2`), `--json` NDJSON output, and per-source scoping. Reuses sync's auth and provenance machinery without mutating the working tree.
|
|
17
|
+
- **Document state tagging** — every materialized citadel file carries an inline `state: draft | canon` declared at the source. Markdown frontmatter, HTML comments, top-level YAML/JSON keys, and first-line `state:` for plain text are all supported. Resolution is inline > matching rule (maester-config or citadel-includes) > default (`draft`). Per-source state breakdown appears in sync output (human + `--json`); a `--verbose` listing names the source-of-truth for each file; an informational warning surfaces when inline state disagrees with a rule.
|
|
18
|
+
- **Grand Maester agent skill** — opt-in installer that drops citadel-aware, state-aware, freshness-aware instructions into agent-specific locations: `.claude/skills/grand-maester/SKILL.md` plus a managed `maester` key in `.claude/settings.json` (Claude Code), `AGENTS.md` at the repo root (Codex CLI and a generic-fallback target dedup to the same file), and `.cursor/rules/grand-maester.mdc` (Cursor). Standalone CLI: `maester skill install [--target id]`, `maester skill upgrade [--check]`, `maester skill add-target <id>`, `maester skill status`. Claude Code receives a `PreToolUse` hook that calls `maester skill runtime preread`, which path-scopes to citadel reads and runs `maester status` only when needed, with a debounced cache at `.maester/.skill-cache.json` (TTL configurable via `MAESTER_SKILL_STATUS_TTL`, default 300s). Offered as a recommended opt-in step at the end of citadel-init. Every installed artifact carries an idempotent managed-region marker; upgrades preserve user content outside it.
|
|
19
|
+
- **Citadel YAML schema v1** — top-level `sources:` array. Each entry is a `Source`; the optional `includes` field decides the mode.
|
|
20
|
+
- **CI/CD** — GitHub Actions `ci.yml` matrix (Node 24 + 22) and `release.yml` tag-triggered `npm publish --provenance` via OIDC.
|
|
21
|
+
- Public library exports (`src/index.ts`): `loadCitadelConfig`, `loadMaesterConfig`, `runSync`, schema types (`CitadelConfig`, `Source`, `AuthRef`, `MaesterConfig`, `PublishedDocument`), and typed error classes.
|
|
22
|
+
|
|
23
|
+
### Changed
|
|
24
|
+
- Sync orchestration consolidated into a single `src/core/sources/fetcher.ts` (replacing the previously planned per-kind modules). The fetcher branches internally on whether the source declares an `includes` list.
|
|
25
|
+
- **Repo-root detection is now always the current working directory.** `npx maester` (and every subcommand) treats `process.cwd()` as the root unconditionally — the old walk-upward-for-`.git`/`package.json` behavior is removed. `citadel.yaml` and `maester.yaml` always land in the directory where you typed the command, never in an ancestor. An existing config file in an ancestor directory is invisible to the cwd model.
|
|
26
|
+
- Top-level `baseDir` field on `citadel.yaml` (optional). When set, every source whose `destination` is unset is surfaced at `<baseDir>/<source-name>/` instead of `citadel/<source-name>/`. Per-source `destination` overrides always win. Omitting `baseDir` is identical to today's behavior — fully backward compatible. The citadel-init walkthrough prompts for it with `citadel` pre-filled and omits the field from the generated YAML when the default is accepted.
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Baller Software
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
# Maester
|
|
2
|
+
|
|
3
|
+
> Aggregate documentation from many sources into one central knowledge home for developers and AI agents.
|
|
4
|
+
|
|
5
|
+
[](https://github.com/baller-software/maester/actions/workflows/ci.yml)
|
|
6
|
+
|
|
7
|
+
Maester is a Node CLI and helper library for teams whose knowledge is spread across multiple sources — Git repositories today, with hosted document tools and web sources planned next. A **citadel** gathers content from many remote git repositories into a structured knowledge base that is easier to read, update, and reason over.
|
|
8
|
+
|
|
9
|
+
A repo you own can publish a `maester.yaml` manifest declaring what it offers — the citadel consumes whatever the manifest publishes. For sources you do not own (public third-party repos, vendor docs you have read access to), the citadel can take ownership of the filter set by declaring an `includes` list directly on the source — see below.
|
|
10
|
+
|
|
11
|
+
## Two roles, two files
|
|
12
|
+
|
|
13
|
+
Maester defines two repository roles, each declared by a single committed YAML file at the directory where the CLI was invoked:
|
|
14
|
+
|
|
15
|
+
| Role | File | Created by |
|
|
16
|
+
|----------|----------------|--------------------|
|
|
17
|
+
| citadel | `citadel.yaml` | `maester init` |
|
|
18
|
+
| maester | `maester.yaml` | `maester publish` |
|
|
19
|
+
|
|
20
|
+
A directory can hold one role, the other, or both. There is at most one of each per directory.
|
|
21
|
+
|
|
22
|
+
### Where do the files land?
|
|
23
|
+
|
|
24
|
+
**Every maester command uses the current working directory as the root.** When you run `npx maester init` from a directory, `citadel.yaml` is created in that exact directory — never in an ancestor. The same goes for `npx maester publish` (writes `maester.yaml` here), `npx maester sync` (reads `citadel.yaml` from here), and the interactive menu (`npx maester`).
|
|
25
|
+
|
|
26
|
+
If you run a maester command from the wrong directory, `cd` to the intended directory and re-run. The CLI does not walk upward to find a project root, so a stray `.git/` or `package.json` in a parent directory will not pull configuration files away from where you typed the command.
|
|
27
|
+
|
|
28
|
+
## Quickstart
|
|
29
|
+
|
|
30
|
+
In the directory you want to populate with aggregated knowledge:
|
|
31
|
+
|
|
32
|
+
```sh
|
|
33
|
+
npx maester # interactive menu (uses cwd as root)
|
|
34
|
+
npx maester init # citadel walkthrough — creates ./citadel.yaml
|
|
35
|
+
npx maester sync # fetch all configured sources — reads ./citadel.yaml
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
In a directory that *publishes* docs to other citadels:
|
|
39
|
+
|
|
40
|
+
```sh
|
|
41
|
+
npx maester publish # maester manifest walkthrough — creates ./maester.yaml
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## Pulling from sources you don't own
|
|
45
|
+
|
|
46
|
+
Every entry in `citadel.yaml` is a **source** — a remote git repo. Each source is one of two modes, decided implicitly by whether you declare an `includes` list on it:
|
|
47
|
+
|
|
48
|
+
- **Manifest-driven** (no `includes`): the remote repo publishes its own `maester.yaml` declaring what it offers. The remote owns the publish surface; the citadel just consumes it. Use this for repos you own.
|
|
49
|
+
- **Includes-driven** (`includes` set): the citadel declares the filter set directly. The remote `maester.yaml` (if any) is ignored. Use this for public third-party repos, vendor docs you have read access to but cannot modify, and any other source that does not publish a manifest.
|
|
50
|
+
|
|
51
|
+
```yaml
|
|
52
|
+
# citadel.yaml (excerpt)
|
|
53
|
+
schemaVersion: 1
|
|
54
|
+
|
|
55
|
+
sources:
|
|
56
|
+
# Manifest-driven — the remote publishes its own maester.yaml.
|
|
57
|
+
- name: design-system
|
|
58
|
+
url: https://github.com/example-org/design-system.git
|
|
59
|
+
|
|
60
|
+
# Includes-driven — the citadel owns the filter set.
|
|
61
|
+
- name: react-docs
|
|
62
|
+
url: https://github.com/facebook/react.git
|
|
63
|
+
ref: main
|
|
64
|
+
includes:
|
|
65
|
+
- docs/**/*.md
|
|
66
|
+
- README.md
|
|
67
|
+
description: Upstream React documentation snapshot.
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
`npx maester sync` processes every source in one pass. The trade-off for the includes-driven mode: when the remote repo restructures, the citadel's `includes` may need to be updated. Sync prints a warning when an includes-driven source resolves to zero files so drift is visible.
|
|
71
|
+
|
|
72
|
+
## Prerequisites
|
|
73
|
+
|
|
74
|
+
- **Node.js** ≥ 24 LTS
|
|
75
|
+
- **git** ≥ 2.27 (older versions fall back automatically to `--depth=1` clones)
|
|
76
|
+
- **pnpm** 9.x for development (consumers can use any package manager)
|
|
77
|
+
|
|
78
|
+
## Local Development Setup
|
|
79
|
+
|
|
80
|
+
```sh
|
|
81
|
+
git clone https://github.com/<org>/maester.git
|
|
82
|
+
cd maester
|
|
83
|
+
pnpm install
|
|
84
|
+
pnpm run build
|
|
85
|
+
pnpm run test
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
## Available Scripts
|
|
89
|
+
|
|
90
|
+
| Script | Purpose |
|
|
91
|
+
|---|---|
|
|
92
|
+
| `pnpm run build` | Bundle CLI + library with `tsup` |
|
|
93
|
+
| `pnpm run dev` | Watch mode build |
|
|
94
|
+
| `pnpm run test` | Run Vitest unit + e2e tests once |
|
|
95
|
+
| `pnpm run test:watch` | Watch mode tests |
|
|
96
|
+
| `pnpm run lint` | Lint with Biome |
|
|
97
|
+
| `pnpm run lint:fix` | Lint and auto-fix |
|
|
98
|
+
| `pnpm run typecheck` | `tsc --noEmit` |
|
|
99
|
+
| `pnpm run format` | Format with Biome |
|
|
100
|
+
| `pnpm run prepublishOnly` | Full quality gate (lint + typecheck + test + build) |
|
|
101
|
+
|
|
102
|
+
## Try the CLI Locally
|
|
103
|
+
|
|
104
|
+
```sh
|
|
105
|
+
pnpm link --global
|
|
106
|
+
cd /tmp/my-scratch-repo
|
|
107
|
+
git init
|
|
108
|
+
maester
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
## Environment Variables
|
|
112
|
+
|
|
113
|
+
Maester reads tokens only at runtime; nothing secret is ever written to disk. Per-source token env-var **names** are stored in `citadel.yaml`; the values live in your shell, `.env` loader, or CI secret manager.
|
|
114
|
+
|
|
115
|
+
| Variable | Purpose |
|
|
116
|
+
|---|---|
|
|
117
|
+
| `<user-defined>` | Each source with `auth.type: "token"` reads from the env-var name in its config (e.g. `MAESTER_DOCS_TOKEN`). |
|
|
118
|
+
| `NO_COLOR` | Disable ANSI color. Standard. |
|
|
119
|
+
| `FORCE_COLOR` | Force color (`0`–`3`). Standard. |
|
|
120
|
+
| `MAESTER_THEME` | `light` or `dark` to override automatic detection. |
|
|
121
|
+
| `MAESTER_NO_MOTION` | Replace spinners with static elapsed counters. |
|
|
122
|
+
| `MAESTER_NO_WELCOME` | Suppress the first-run welcome banner. |
|
|
123
|
+
|
|
124
|
+
## Project Structure
|
|
125
|
+
|
|
126
|
+
```
|
|
127
|
+
src/
|
|
128
|
+
├── cli/ Commander dispatch + interactive walkthroughs
|
|
129
|
+
├── core/ Domain (config, git, sync, auth)
|
|
130
|
+
├── schemas/ Zod schemas for the two YAML configs
|
|
131
|
+
└── ui/ Theme + logger + terminal components
|
|
132
|
+
test/ Vitest unit + e2e tests
|
|
133
|
+
gspec/ Living specifications
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
## Specifications
|
|
137
|
+
|
|
138
|
+
This project is built from a living specification under `gspec/`. The product profile, technology stack, visual style guide, development practices, technical architecture, and per-feature PRDs all live there. Changes to behavior should update the relevant spec; see `CLAUDE.md` for the contract.
|
|
139
|
+
|
|
140
|
+
## License
|
|
141
|
+
|
|
142
|
+
MIT.
|
package/bin/maester.mjs
ADDED