@marwansaab/obsidian-vault-bootstrap 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.
@@ -0,0 +1,87 @@
1
+ # Contributing
2
+
3
+ ## Commit-message convention
4
+
5
+ Every commit in this project follows the convention below. It is a superset
6
+ of [Conventional Commits](https://www.conventionalcommits.org/) — the
7
+ `type(scope): description` subject is the same; the body conventions
8
+ layered on top are project-specific.
9
+
10
+ ### Subject line (≤72 chars, no trailing period)
11
+
12
+ ```
13
+ <type>(<scope>): <description>
14
+ ```
15
+
16
+ - **`type`** — one of: `feat`, `fix`, `chore`, `docs`, `ci`, `refactor`,
17
+ `test`, `perf`.
18
+ - **`scope`** — the spec/feature ID when one exists (e.g. `013`,
19
+ `specs/009`); otherwise a component name (e.g. `git-extension`,
20
+ `release`, `readme`, `ci`).
21
+ - **`description`** — lowercase, imperative present tense ("add",
22
+ "implement", "bump", "clarify", "remediate", "pivot to", "mark",
23
+ "scaffold", "revert", "enable"). Sentence fragment, no period. May end
24
+ with a parenthetical clarifier like `(round 4)`,
25
+ `(consistency + coverage)`, or a task-ID list like `(T001, T003, T006)`.
26
+
27
+ Examples:
28
+
29
+ - `feat(013): implement find_and_replace MCP tool with three-layer composition`
30
+ - `docs(013): clarify enumeration and count semantics for find_and_replace (round 3)`
31
+ - `chore(release): bump to 0.5.0 — spec 008 list_tags`
32
+
33
+ ### Body (blank line after subject, wrap ~72 cols)
34
+
35
+ Lead with the **WHY** and **WHAT**, not the HOW (the diff shows the how).
36
+
37
+ 1. One-paragraph summary of what this commit does and why it exists
38
+ (link to the user clarification, spike outcome, analyzer finding, or
39
+ upstream dependency that prompted it).
40
+ 2. Itemised detail using bullets. Group related items under a SHOUTY-CAPS
41
+ prefix when categorising — e.g. `LAYER 1 — …`,
42
+ `T002 spike outcome (YYYY-MM-DD): NEGATIVE.`, `MINOR bump:` /
43
+ `PATCH bump:`, `F1 (HIGH) — …` (analyzer finding ID + severity),
44
+ `I2 (MEDIUM) — …` (consistency-issue ID + severity).
45
+ 3. Reference identifiers wherever they apply, in their native form, no
46
+ decoration: `FR-NNN` (functional requirement), `SC-NNN` (success
47
+ criterion), `TNNN` (task ID, e.g. `T009a`), `RNN` (research item, e.g.
48
+ `R12`), `Q1` (clarification question), `file/path.ts:LINE` (when
49
+ pointing at code), `PR #NN`, `commit shortsha`. Don't gloss IDs as
50
+ "the requirement" — name them.
51
+ 4. Be honest about tradeoffs, deferrals, and negative outcomes. If a
52
+ spike failed, say "NEGATIVE" and explain. If something is gated on
53
+ another piece of work, name the gate. If a task is deferred, say so
54
+ explicitly.
55
+ 5. Close with quality-gate results when the commit changes code:
56
+ `Quality gates: lint clean, typecheck clean, build clean, 572/572
57
+ tests pass (was 422 baseline, +150 new, 0 regressions).` Include
58
+ coverage % when the project tracks a coverage floor.
59
+ 6. For semver bumps, state the bump category and the rationale in one
60
+ sentence: `MINOR bump: adds the X public tool. Backward compatible —
61
+ no existing tool surface changes.` `PATCH bump (0.5.0 → 0.5.1) is the
62
+ honest signal: this PR ships internal preparation but no user-visible
63
+ capability.`
64
+
65
+ Bodies are **mandatory** for `feat`, spec, and analyzer-remediation
66
+ commits. They are optional for tiny one-line `fix`/`chore` commits, but
67
+ even those keep the `type(scope): subject` form.
68
+
69
+ ### Trailers (blank line before, one per line, no wrap)
70
+
71
+ For AI-assisted commits, append:
72
+
73
+ ```
74
+ Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
75
+ ```
76
+
77
+ Substitute the actual model name + version of the assistant session
78
+ that drafted the message.
79
+
80
+ ### Tone
81
+
82
+ Direct, technical, no marketing language, no emoji. Prefer concrete
83
+ nouns ("the dispatcher's `getRestService` throw path") over abstractions
84
+ ("the error handling"). Be willing to write things like "the templated
85
+ commit messages are too generic to be useful" when reverting something.
86
+ Write so a maintainer reading `git log` six months later can reconstruct
87
+ the WHY without opening the PR.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Marwan Saab
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,75 @@
1
+ # @marwansaab/obsidian-vault-bootstrap
2
+
3
+ Initialise a complete Obsidian vault — folder structure, templates, MOCs,
4
+ frontmatter conventions — and generate matching agent-instruction files for
5
+ Claude, Cursor, Cline, or any AI coding assistant. Q&A-driven, npm-versioned,
6
+ single source across your portfolio.
7
+
8
+ > **Governance.** Every change in this repository is measured against the
9
+ > project constitution:
10
+ > [`.specify/memory/constitution.md`](.specify/memory/constitution.md) (v1.0.0,
11
+ > ratified 2026-05-18). Principles I–VII are non-negotiable; reviewers cite
12
+ > them by Roman numeral when accepting or rejecting changes.
13
+
14
+ ## Quickstart
15
+
16
+ ```bash
17
+ git clone https://github.com/marwansaab/obsidian-vault-bootstrap.git
18
+ cd obsidian-vault-bootstrap
19
+ nvm use 22 # or fnm / volta — Node >= 22.13.0 is required
20
+ npm ci # honours the lockfile and .npmrc engine-strict
21
+ npm run build
22
+ npx . --help
23
+ ```
24
+
25
+ v0.1 ships a placeholder CLI only — `npx . --help` and `npx . --version` are
26
+ the entire end-user surface. See **Limitations (v0.1)** below for what does
27
+ not work yet.
28
+
29
+ ## Quality gates
30
+
31
+ The same six gates run locally and in CI (single source of truth per FR-014).
32
+ Each gate exits non-zero on any failure and names the offending file in its
33
+ output (FR-006).
34
+
35
+ | Gate | Command | Strictness bar |
36
+ | ------------ | ----------------------- | ---------------------------------------------- |
37
+ | format-check | `npm run format:check` | `prettier --check .` — zero divergence |
38
+ | lint | `npm run lint` | `eslint . --max-warnings 0` |
39
+ | typecheck | `npm run typecheck` | `tsc --noEmit` — zero diagnostics, strict mode |
40
+ | build | `npm run build` | `tsc` — zero warning-severity emit |
41
+ | test | `npm test` | `vitest run` — non-zero on any failure |
42
+ | coverage | `npm run test:coverage` | statements ≥ 80% (vitest threshold) |
43
+
44
+ `npm run format` is the local fix-it command (writes prettier-formatted files
45
+ back); it is **not** a CI gate.
46
+
47
+ ## Limitations (v0.1)
48
+
49
+ v0.1 is a scaffold. The following are deliberately deferred — each will land
50
+ with the spec that first consumes it. The full version history is in
51
+ [`CHANGELOG.md`](CHANGELOG.md).
52
+
53
+ - No content-rendering pipeline yet — `core/`, `families/`, `templates/`, and
54
+ `projects/` ship empty (with `.gitkeep` placeholders) and will be populated
55
+ by subsequent specs.
56
+ - No end-user subcommands beyond `--help` / `--version` — no `init`, no
57
+ `bootstrap`, no profile-driven render.
58
+ - No interactive Q&A flow.
59
+ - No content-bearing fixtures (instruction-content files, template files,
60
+ project-profile files arrive in later specs).
61
+ - Not published to the public npm registry.
62
+ - No Obsidian vault-folder initialisation pipeline.
63
+ - **Single supported OS in CI: `ubuntu-latest`.** The package itself is Node
64
+ and runs anywhere Node does; the gate-verified OS in CI is Linux only.
65
+ Windows and macOS contributors can use the package, but their environment
66
+ is not covered by the CI matrix.
67
+ - No code-graph integration.
68
+
69
+ ## Attributions
70
+
71
+ v0.1 ships no upstream-derived code; every source file in this commit carries
72
+ an `// Original — no upstream. <intent>.` header per constitution Principle
73
+ VII. This section exists as a stable insertion point — future modules
74
+ adapted from external projects will be listed here with their SPDX
75
+ identifier and pinned commit hash.
package/dist/cli.d.ts ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env node
2
+ export interface CliResult {
3
+ readonly exitCode: number;
4
+ readonly stdout: string;
5
+ readonly stderr: string;
6
+ }
7
+ export declare function main(argv: readonly string[]): CliResult;
8
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAOA,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAuBD,wBAAgB,IAAI,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,CAwBvD"}
package/dist/cli.js ADDED
@@ -0,0 +1,70 @@
1
+ #!/usr/bin/env node
2
+ // Original — no upstream. Placeholder CLI entry-point for the v1 scaffold.
3
+ import { parseArgs } from "node:util";
4
+ import { readFileSync } from "node:fs";
5
+ import { fileURLToPath } from "node:url";
6
+ import { dirname, resolve } from "node:path";
7
+ const HELP_TEXT = `obsidian-vault-bootstrap
8
+
9
+ Usage:
10
+ npx . [--help|--version]
11
+
12
+ Options:
13
+ -h, --help Show this help text and exit.
14
+ -v, --version Print the package version and exit.
15
+
16
+ v0.1 ships a placeholder CLI only. See README.md for the v0.1 limitations
17
+ and .specify/memory/constitution.md for the governance constitution.
18
+ `;
19
+ function readPackageVersion() {
20
+ const here = dirname(fileURLToPath(import.meta.url));
21
+ const pkgPath = resolve(here, "..", "package.json");
22
+ const raw = readFileSync(pkgPath, "utf8");
23
+ const parsed = JSON.parse(raw);
24
+ return parsed.version;
25
+ }
26
+ export function main(argv) {
27
+ try {
28
+ const { values } = parseArgs({
29
+ args: [...argv],
30
+ options: {
31
+ help: { type: "boolean", short: "h" },
32
+ version: { type: "boolean", short: "v" },
33
+ },
34
+ strict: true,
35
+ allowPositionals: false,
36
+ });
37
+ if (values.version) {
38
+ return { exitCode: 0, stdout: `${readPackageVersion()}\n`, stderr: "" };
39
+ }
40
+ return { exitCode: 0, stdout: HELP_TEXT, stderr: "" };
41
+ }
42
+ catch (err) {
43
+ const message = err instanceof Error ? err.message : String(err);
44
+ return {
45
+ exitCode: 1,
46
+ stdout: "",
47
+ stderr: `${message}\nUse --help for usage information.\n`,
48
+ };
49
+ }
50
+ }
51
+ function invokedDirectly() {
52
+ const entry = process.argv[1];
53
+ if (!entry)
54
+ return false;
55
+ try {
56
+ return fileURLToPath(import.meta.url) === resolve(entry);
57
+ }
58
+ catch {
59
+ return false;
60
+ }
61
+ }
62
+ if (invokedDirectly()) {
63
+ const result = main(process.argv.slice(2));
64
+ if (result.stdout)
65
+ process.stdout.write(result.stdout);
66
+ if (result.stderr)
67
+ process.stderr.write(result.stderr);
68
+ process.exit(result.exitCode);
69
+ }
70
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA,2EAA2E;AAC3E,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAQ7C,MAAM,SAAS,GAAG;;;;;;;;;;;CAWjB,CAAC;AAEF,SAAS,kBAAkB;IACzB,MAAM,IAAI,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;IACrD,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,EAAE,IAAI,EAAE,cAAc,CAAC,CAAC;IACpD,MAAM,GAAG,GAAG,YAAY,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IAC1C,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAwB,CAAC;IACtD,OAAO,MAAM,CAAC,OAAO,CAAC;AACxB,CAAC;AAED,MAAM,UAAU,IAAI,CAAC,IAAuB;IAC1C,IAAI,CAAC;QACH,MAAM,EAAE,MAAM,EAAE,GAAG,SAAS,CAAC;YAC3B,IAAI,EAAE,CAAC,GAAG,IAAI,CAAC;YACf,OAAO,EAAE;gBACP,IAAI,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,GAAG,EAAE;gBACrC,OAAO,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,GAAG,EAAE;aACzC;YACD,MAAM,EAAE,IAAI;YACZ,gBAAgB,EAAE,KAAK;SACxB,CAAC,CAAC;QAEH,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;YACnB,OAAO,EAAE,QAAQ,EAAE,CAAC,EAAE,MAAM,EAAE,GAAG,kBAAkB,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC;QAC1E,CAAC;QACD,OAAO,EAAE,QAAQ,EAAE,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC;IACxD,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QACjE,OAAO;YACL,QAAQ,EAAE,CAAC;YACX,MAAM,EAAE,EAAE;YACV,MAAM,EAAE,GAAG,OAAO,uCAAuC;SAC1D,CAAC;IACJ,CAAC;AACH,CAAC;AAED,SAAS,eAAe;IACtB,MAAM,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAC9B,IAAI,CAAC,KAAK;QAAE,OAAO,KAAK,CAAC;IACzB,IAAI,CAAC;QACH,OAAO,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,OAAO,CAAC,KAAK,CAAC,CAAC;IAC3D,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,IAAI,eAAe,EAAE,EAAE,CAAC;IACtB,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IAC3C,IAAI,MAAM,CAAC,MAAM;QAAE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IACvD,IAAI,MAAM,CAAC,MAAM;QAAE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IACvD,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;AAChC,CAAC"}
package/package.json ADDED
@@ -0,0 +1,38 @@
1
+ {
2
+ "name": "@marwansaab/obsidian-vault-bootstrap",
3
+ "version": "0.1.0",
4
+ "type": "module",
5
+ "engines": {
6
+ "node": ">=22.13.0"
7
+ },
8
+ "bin": {
9
+ "obsidian-vault-bootstrap": "./dist/cli.js"
10
+ },
11
+ "files": [
12
+ "dist",
13
+ "README.md",
14
+ "LICENSE",
15
+ "CONTRIBUTING.md"
16
+ ],
17
+ "scripts": {
18
+ "format:check": "prettier --check .",
19
+ "format": "prettier --write .",
20
+ "lint": "eslint . --max-warnings 0",
21
+ "typecheck": "tsc --noEmit",
22
+ "build": "tsc",
23
+ "test": "vitest run",
24
+ "test:coverage": "vitest run --coverage",
25
+ "prepare": "npm run build"
26
+ },
27
+ "devDependencies": {
28
+ "@eslint/js": "^9.0.0",
29
+ "@types/node": "^22.0.0",
30
+ "@vitest/coverage-v8": "^3.2.4",
31
+ "eslint": "^9.0.0",
32
+ "eslint-config-prettier": "^9.0.0",
33
+ "prettier": "^3.0.0",
34
+ "typescript": "^5.6.0",
35
+ "typescript-eslint": "^8.0.0",
36
+ "vitest": "^3.2.4"
37
+ }
38
+ }