@freetesh/zeno 0.9.0 → 0.9.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.
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://anthropic.com/claude-code/plugin.schema.json",
3
3
  "name": "zeno",
4
- "version": "0.9.0",
4
+ "version": "0.9.1",
5
5
  "description": "Keeps your domain knowledge and AI rules local and enforces them, so Claude hallucinates less.",
6
6
  "author": {
7
7
  "name": "Ritesh Firodiya",
package/README.md CHANGED
@@ -1,10 +1,28 @@
1
- # zeno
1
+ <p align="center">
2
+ <img src=".github/assets/icon.svg" width="96" height="96" alt="zeno icon">
3
+ </p>
2
4
 
3
- A productivity tool for the whole product development lifecycle (PDLC), from
4
- idea to release. zeno keeps your domain knowledge, decisions and AI rules local,
5
- in your own repos, and enforces them: Claude searches them before it answers,
6
- weighs a request against them before it acts, and `zeno check` fails when code
7
- or docs break them. The AI hallucinates less, and your team ships faster.
5
+ <h1 align="center">zeno</h1>
6
+
7
+ <p align="center">
8
+ <b>Facts, not assumptions.</b> Your rules, kept in your repo. Enforced.<br>
9
+ A Claude Code plugin and CLI · MIT
10
+ </p>
11
+
12
+ <p align="center">
13
+ <a href="https://www.npmjs.com/package/@freetesh/zeno"><img alt="npm" src="https://img.shields.io/npm/v/@freetesh/zeno"></a>
14
+ <a href="LICENSE"><img alt="MIT license" src="https://img.shields.io/badge/license-MIT-blue"></a>
15
+ </p>
16
+
17
+ zeno keeps your domain knowledge, decisions and AI rules in your own repos, and
18
+ enforces them. Claude searches them before it answers. It weighs each request
19
+ against them before it acts, and it checks every claim in the request against
20
+ facts. `zeno check` fails when code or docs break a rule. The AI guesses less,
21
+ and you redo less work.
22
+
23
+ <p align="center">
24
+ <img src=".github/assets/demo.svg" alt="zeno weighs a request. Two of three claims have no facts and the request breaks a decided rule, so it pushes back and stops until the user brings facts, agrees to terms, or drops it.">
25
+ </p>
8
26
 
9
27
  It has two halves that read the same config:
10
28
 
@@ -87,17 +105,6 @@ starter `.dependency-cruiser.cjs` to your layers. `evals/fixtures/streaks` is a
87
105
  small product with a wiki and decision records, if you want to see the
88
106
  `.context/` layout before touching your own repo.
89
107
 
90
- For local development of zeno itself, link the repo as a skills-dir plugin so
91
- edits apply on the next session: `ln -s "$PWD" ~/.claude/skills/zeno`.
92
- Run the CLI from source (Node 23.6+ runs the TypeScript directly):
93
- `pnpm install && ln -s "$PWD/cli/src/index.ts" ~/.local/bin/zeno`.
94
- `pnpm test`, `pnpm typecheck` and `pnpm build` run from the repo root.
95
-
96
- **Releasing.** Bump `version` in `package.json` and `.claude-plugin/plugin.json`,
97
- then push or merge to `main`. The `release` workflow runs the tests, publishes
98
- `@freetesh/zeno` to npm, tags `vX.Y.Z` and creates the GitHub release. A push
99
- without a bump releases nothing. It needs the `NPM_TOKEN` Actions secret.
100
-
101
108
  ## CLI
102
109
 
103
110
  ```bash
@@ -145,7 +152,7 @@ context:
145
152
 
146
153
  ```yaml
147
154
  # <repo>/.claude/zeno.yaml — written by `zeno init`
148
- zeno: 0.6.0
155
+ zeno: 0.9.0
149
156
  kind: expo-app # expo-app | web | content
150
157
  modules: [docs, knowledge, code, listing] # all optional; design is added when .context/designs exists, metrics only when asked
151
158
  packs: [expo]
@@ -164,7 +171,7 @@ carry a `reason:`, and `zeno check` lists every override.
164
171
 
165
172
  | zeno default | What it holds |
166
173
  |---|---|
167
- | `constitution.md` | Principles C-01–C-13 a request is weighed against. A team adds C-20+ in its own `constitution.md`. |
174
+ | `constitution.md` | Principles C-01–C-15 a request is weighed against. A team adds C-20+ in its own `constitution.md`. |
168
175
  | `wiki-schema.md` | Wiki page types, frontmatter, required sections, lint rules |
169
176
  | `context-layout.md` | The `.context/` ten-folder layout, `features/` and `tasks.md` |
170
177
  | `agent-contract.md` | What every agent does before, during and after work |
@@ -199,3 +206,16 @@ scripts/ log-verdict.mjs — append-only override log
199
206
  cli/ the zeno CLI (TypeScript, vitest; built to cli/dist for npm)
200
207
  evals/ plugin evals and the fixture product
201
208
  ```
209
+
210
+ ## Develop zeno
211
+
212
+ Link the repo as a skills-dir plugin so edits apply on the next session:
213
+ `ln -s "$PWD" ~/.claude/skills/zeno`.
214
+ Run the CLI from source (Node 23.6+ runs the TypeScript directly):
215
+ `pnpm install && ln -s "$PWD/cli/src/index.ts" ~/.local/bin/zeno`.
216
+ `pnpm test`, `pnpm typecheck` and `pnpm build` run from the repo root.
217
+
218
+ **Releasing.** Bump `version` in `package.json` and `.claude-plugin/plugin.json`,
219
+ then push or merge to `main`. The `release` workflow runs the tests, publishes
220
+ `@freetesh/zeno` to npm, tags `vX.Y.Z` and creates the GitHub release. A push
221
+ without a bump releases nothing. It needs the `NPM_TOKEN` Actions secret.
@@ -3,8 +3,9 @@ import { join } from "node:path";
3
3
  import { parseFrontmatter } from "../lib/frontmatter.js";
4
4
  import { wikiPages } from "./wiki-frontmatter.js";
5
5
  // zeno has no connectors: a source page must say which MCP server, skill or CLI
6
- // reads it, or the weigh gate cannot turn a claim into a fact.
7
- const ACCESS = /^(mcp|skill|cli):\s*(\S+)/;
6
+ // reads it, or that a person reads it by hand (`manual:`), or the weigh gate
7
+ // cannot turn a claim into a fact.
8
+ const ACCESS = /^(mcp|skill|cli|manual):\s*(\S+)/;
8
9
  const HOW_TO_QUERY = /^## How to query\s*$/m;
9
10
  function accessValue(body, id) {
10
11
  const row = body.split("\n").find((line) => line.replace(/\s/g, "").startsWith(`|${id}.ACCESS|`));
@@ -13,7 +14,7 @@ function accessValue(body, id) {
13
14
  export const sources = {
14
15
  id: "sources",
15
16
  module: "docs",
16
- description: "each SOURCE.* page says how to read it (mcp, skill or a cli in doctor.tools) and has a How to query section",
17
+ description: "each SOURCE.* page says how to read it (mcp, skill, manual, or a cli in doctor.tools) and has a How to query section",
17
18
  run({ repo, config }) {
18
19
  const tools = new Set(config.doctor.tools.map((tool) => tool.tool));
19
20
  return wikiPages(repo).flatMap((file) => {
@@ -30,7 +31,7 @@ export const sources = {
30
31
  if (access === null)
31
32
  add(`no ${id}.ACCESS row — say how to read it`);
32
33
  else if (!match)
33
- add(`${id}.ACCESS is "${access}" — write mcp: <server>, skill: <name> or cli: <command>`);
34
+ add(`${id}.ACCESS is "${access}" — write mcp: <server>, skill: <name>, cli: <command> or manual: <where>`);
34
35
  else if (match[1] === "cli" && !tools.has(match[2]))
35
36
  add(`cli ${match[2]} is not in doctor.tools — zeno doctor cannot report it missing`);
36
37
  return findings;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@freetesh/zeno",
3
- "version": "0.9.0",
3
+ "version": "0.9.1",
4
4
  "description": "zeno CLI: keep your domain knowledge and AI rules in your repo, and enforce them.",
5
5
  "license": "MIT",
6
6
  "author": "Ritesh Firodiya",
@@ -49,8 +49,9 @@ product's `.claude/zeno.yaml` may tighten this under `weigh.trivial`.
49
49
  **not backed**, with the fact and its source. Look in what step 3 read, the
50
50
  code and `.context/raw/`. When that is not enough, look for a data source:
51
51
  query qmd for `SOURCE` pages in this product's wiki. Each says what it holds,
52
- how to read it (`mcp:`, `skill:` or `cli:`) and which claims it answers. If
53
- one fits, run its query and follow the query rules in `wiki-schema.md`
52
+ how to read it (`mcp:`, `skill:`, `cli:` or `manual:`) and which claims it
53
+ answers. For `manual:`, ask the user for the numbers and say where to find
54
+ them; do not guess. If one fits, run its query and follow the query rules in `wiki-schema.md`
54
55
  ("Data sources"): read only, one or two small queries, counts not people.
55
56
  Save a result that decides the verdict to `.context/raw/`. If the tool is not
56
57
  available, say so and leave the claim not backed. If no source fits, name
@@ -114,7 +115,9 @@ Open questions: <only if a real ambiguity blocks a good answer>
114
115
  already accepted it and **Assumed** is "none"; otherwise stop and ask.
115
116
  - **PUSH BACK** → stop. Do not start the work, not even a part of it.
116
117
  - **Something is assumed** → stop, and give the user three choices: bring the
117
- facts (and say where they would go), agree to terms, or drop it.
118
+ facts (and say where they would go), agree to terms, or drop it. Any terms
119
+ you show, here or later, are a numbered list, so the user can agree line by
120
+ line.
118
121
 
119
122
  Write the whole reply in plain words (C-15): short sentences, common words, no
120
123
  jargon the wiki does not define.
@@ -67,8 +67,9 @@ The claims this source can answer, and one example query for each.
67
67
  ```
68
68
 
69
69
  zeno has no connector of its own. The repo picks what does the reading, and
70
- `ACCESS` names it: `mcp: <server>`, `skill: <name>` or `cli: <command>`. A
71
- `cli:` must also be in `doctor.tools` in `.claude/zeno.yaml`, so `zeno doctor`
70
+ `ACCESS` names it: `mcp: <server>`, `skill: <name>`, `cli: <command>`, or
71
+ `manual: <where>` for a dashboard with no API, which a person reads and pastes
72
+ into `raw/`. A `cli:` must also be in `doctor.tools` in `.claude/zeno.yaml`, so `zeno doctor`
72
73
  reports when it is missing. `zeno check` fails a source page that breaks either
73
74
  rule or has no `## How to query`. Never put a key or token on the page.
74
75