Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions .claude-plugin/marketplace.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"name": "ost-tools",
"description": "Plugins for working with structured Obsidian markdown content using ost-tools.",
"owner": {
"name": "Roger Barnes",
"email": "roger@mindsocket.com.au"
},
"plugins": [
{
"name": "ost-tools",
"source": "./plugin/ost-tools"
}
]
}
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -36,4 +36,7 @@ report.[0-9]_.[0-9]_.[0-9]_.[0-9]_.json
.miro-cache/
config.json
.claude/settings.local.json
.claude/worktrees/
CLAUDE.local.md

hook-test/fixtures/.state/
29 changes: 20 additions & 9 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,36 +7,47 @@ Tools for working with Opportunity Solution Tree structures and other product ma
Get a list of commands: `bun run src/index.ts --help`
Space names (e.g. `personal`, `politics`) are resolved via a config file - `$OST_TOOLS_CONFIG`, `$XDG_CONFIG_HOME/ost-tools/config.json`, `--config <file>` param, or `./config.json`

## Claude Code Plugin

A Claude Code plugin lives at `plugin/`. It includes skills, commands and hooks used when working with collections of Obsidian markdown content (aka a space) in a vault.

## Definition of done

There are several places that need reviewing and updating with any new feature or change added:

- README.md - documentation, also displayed with `ost-tools readme` command
- AGENTS.md - this file
- docs/* - includes architecture, concepts etc
- skills/ost-tools/* - skills information for AI agents
- plugin/* - skills, commands, hooks, and scripts; update any affected parts

## Project Context

This project validates data in markdown files against a JSON schema representing product and strategy frameworks, including Opportunity Solution Trees.
This project validates data in markdown files against a JSON schema representing knowledge bases, and product and strategy frameworks, including Opportunity Solution Trees.

Before starting new work, review [docs/concepts.md](docs/concepts.md) for canonical terminology. Use and maintain the definitions there as the source of truth when naming things in code, tests, comments, and documentation.

## Key Files

- config — JSON5 file with spaces registered
- `schemas/` — Bundled default schema files (JSON5) using the ost-tools schema dialect and top-level `$metadata`. Files starting with `_` are "partials" (fragments for `$ref`) and are loaded automatically. Local partials in a schema's directory **must** have unique `$id`s.
- `src/metadata-contract.ts` — Single source of truth for the `$metadata` contract (TS `as const` + inferred types)
- `schemas/generated/_ost_tools_schema_meta.json` — Generated metaschema artifact (regenerate with `bun run generate:schema-meta`)
- `schemas/` — Bundled default schema files (JSON5) using the ost-tools schema dialect and top-level `$metadata`. Files starting with `_` are "partials" (fragments for `$ref`).
- `src/metadata-contract.ts` — Single source of truth for the `$metadata` contract
- `schemas/generated/_ost_tools_schema_meta.json` — Generated metaschema (generated on build or with `bun run generate:schema-meta`)

## Testing

For most development only the main unit tests need re-running regularly.
- `bun run test` — unit tests (fixtures in `tests/`)
- `bun run test:smoke` — smoke tests that run `validate` against every space in `config.json` (`smoke/`)
- `bun run test:hook` — unit test plugin hooks (`hook-test/unit/`) - hook development only
- `bun run test:hook:e2e` — test plugin hooks in Claude Code (`hook-test/`) - hook development only
- `bun run test:smoke` — smoke tests run against locally configured spaces - only use when changes could affect compatibility.

## Dual TypeScript Configuration

- **`tsconfig.json`** — Main config for type-checking across all code - use `bun run typecheck`
- **`tsconfig.build.json`** — Production build config (only compiles `src/` to `dist/`) - use `bun run build`

## Debugging

- `bun run src/index.ts dump <space>` — Output parsed node data with resolved parents, useful for debugging rule violations
- `bun run src/index.ts dump <space>` — Output parsed node data

## Hooks
A Stop hook runs linting, autoformatting and unit tests. If it reports issues related to change you made, address them.
Address issues related to change you made if a Stop hook reports them.
19 changes: 14 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,16 @@ bunx ost-tools validate <space>

## Setup for AI Agents

An AI agent skill is included with this project. To install it run:
A Claude Code plugin is included at `plugin/`. It provides validation hooks, slash commands, and agent skills. Install it with:

```
npx skills add mindsocket/ost-tools
claude plugin install mindsocket/ost-tools
```

Skills can also be installed standalone without the plugin:

```
npx skills add https://github.com/mindsocket/ost-tools/tree/main/plugin/skills/ost-tools
```

## Concepts
Expand Down Expand Up @@ -247,7 +253,7 @@ Filter expressions are used with `--filter` and in config `views`. They use a `S
| `SELECT {spec}` | Expand from all nodes via SELECT (no WHERE filter — returns all nodes, expanded per spec) |
| `{jsonata}` | Bare JSONata, treated as a WHERE predicate (convenience shorthand) |

The WHERE predicate is a [JSONata](https://docs.jsonata.org/overview) expression evaluated per node. Within the expression, each node's fields are accessible directly (e.g. `resolvedType`, `status`, any schema fields like `title`). Additionally, two pre-computed traversal arrays are available:
The WHERE predicate is a [JSONata](https://docs.jsonata.org/overview) expression evaluated per node. Within the expression, each node's fields are accessible directly (e.g. `resolvedType`, `status`, any schema fields like `title`). Two built-in fields are always available regardless of schema: `label` (relative file path, e.g. `"solutions/My Solution.md"`) and `title` (node display name). Additionally, two pre-computed traversal arrays are available:

- **`ancestors[]`** — flat array of ancestor nodes, nearest first, deduplicated. Each entry includes all schema fields of the ancestor node, plus:
- `_field` — the edge field name that connects to the ancestor
Expand Down Expand Up @@ -361,10 +367,13 @@ Keeps Obsidian template files in sync with schema examples:
# Run a command against a configured space
bun run src/index.ts validate personal

# Run unit tests
# Run type checking (checks all code including tests)
bun run typecheck

# Run core unit tests
bun run test

# Run smoke tests against all locally configured spaces
# Run occasional smoke tests against all locally configured spaces
bun run test:smoke

# Build compiled output
Expand Down
5 changes: 4 additions & 1 deletion biome.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"$schema": "https://biomejs.dev/schemas/2.4.8/schema.json",
"$schema": "https://biomejs.dev/schemas/2.4.10/schema.json",
"vcs": {
"enabled": true,
"clientKind": "git",
Expand All @@ -20,6 +20,9 @@
"recommended": true,
"style": {
"noNonNullAssertion": "off"
},
"suspicious": {
"noConsole": "off"
}
}
},
Expand Down
Loading
Loading