@delorenj/pjangler

中文文档
1.5.47发布于 2026/11/11MITES Module构建来源已验证近 30 天下载 5870

Project subsystem bootstrapper CLI

原始使用文档
文档目录11 节
  1. Install
  2. CLI usage
  3. Repository ignore contract
  4. Project notebook
  5. Parity audit
  6. Obsidian plugins
  7. Agents
  8. Orienting in a repo
  9. Last activity, not lifecycle status
  10. Shell prompt
  11. MCP server usage

pjangler

Project definitions now live in repository .project.json files with one case-insensitive project_id. Use pj info, pj list, and pj doctor; the singleton PostgreSQL registry indexes those manifests. See project registry for installation, migration, and compatibility details.

Project subsystem bootstrapper CLI + MCP server.

Install

Requires Node 24 or newer. Project skills use @delorenj/skillex 0.1.2; see the integration contract.

git submodule update --init --recursive   # templates/commonproject; a plain clone leaves it empty
npm install
npm run build

npm test (scripts/run-tests.mjs) needs that submodule: the check:submodule-checkout gate fails with the init command when templates/commonproject is empty. The Postgres-backed suites read the standard PG* variables; point them at a disposable server (CI uses a postgres:16 service). PJANGLER_REQUIRE_DISPOSABLE_POSTGRES=1 makes a missing postgres/psql/bun fail instead of skip, as CI does.

CLI usage

npm run build
node dist/index.js --help
# or if installed globally
pjangler --help

Repository ignore contract

CommonProject preserves an existing .gitignore and adds only portable project rules for secrets and local .agents projections. It never copies the operator's core.excludesFile. .agents/ is the sole canonical agent-config tree; .claude/, .codex/, and the other supported client roots are generated local projections covered by machine-wide ignore policy. bmad.cli-roots removes only exact obsolete lines previously generated by pjangler and never changes Git's index. Use the gitignore-maintenance skill to audit effective rule provenance and reconcile already-tracked ignored paths.

Project notebook

pjangler notebook manages one companion Open Notebook for a registered repository. The binding and stable Overview note IDs live in .project.json and the project registry; endpoint, authentication mode, defaults, and finite capture limits live in the registry's global notebook configuration.

pjangler notebook status . --json
pjangler notebook create . --live --json
pjangler notebook list notes . --json
pjangler notebook search notes "release evidence" . --json
pjangler notebook audit . --json
pjangler notebook migrate . --live --apply --json

True SessionStart and SessionEnd hooks are projected separately from the project-scoped hook masters. Their per-repository policy stays fail-open and disabled until explicitly enabled in .project.json.

Parity audit

BMAD recipes support an optional owner-provided g33 companion for registered 33GOD projects, with explicit opt-in/out, no-write previews, and structured optional outcomes. See g33 companion for the callable configuration and the actual pj recipe run bmad --dry-run --json commands.

pjangler audit runs the deterministic 33god parity rules against a repository and exits nonzero when any of them fails. pjangler migrate applies the idempotent fix the owning rule declares.

pjangler audit                                          # every rule, human report
pjangler audit --json                                   # machine-parseable
pjangler audit --rules mise.config-root,sot.project-json
pjangler migrate sot.project-json --dry-run
pjangler migrate --all

--rules reports only the rules you name. An unknown id is an error, never an empty pass — a caller probing for one rule learns that the rule is gone instead of reading a clean report over nothing.

pjangler audit --json and the pjangler_list_parity_rules MCP tool report the live catalog. The rules are owned by the recipes in src/recipes/, not by a central table, so that catalog is the only authority on which ones exist.

Obsidian plugins

pjangler init <name> --obsidian-plugin does everything a normal init does (registry, .project.json, board, BMAD, skills, hooks, mise, the init commit). The difference is the CommonProject render: it is the variant built on the canonical obsidian-sample-plugin. That means manifest.json, versions.json, npm + esbuild + TypeScript in src/, eslint-plugin-obsidianmd, and build/release workflows on the self-hosted runners.

pjangler init tag-wrangler --obsidian-plugin --description "Wrangle tags across a vault"
cd tag-wrangler && npm install && npm run dev
mise run plugin:link ~/Vaults/Main   # symlink into <vault>/.obsidian/plugins/<id>
  • The type is recorded as template.commonproject.project_type and in .copier-answers.yml. It is fixed at creation, and re-running init keeps it.
  • On an existing repo, the flag only records the type, and only when the repo already has an Obsidian manifest.json.
  • mise run version:bump keeps package.json, manifest.json and versions.json in step. It never tags. Release with npm version patch|minor|major, which commits and then tags a bare X.Y.Z (Obsidian matches that), and push the tag.
  • MCP takes the same choice as projectType: "obsidian-plugin" on pjangler_project_init and pjangler_bootstrap_33god_project.

Agents

pjangler does not hire, provision, or inspect agents. That is Flume's surface — flume hire, flume roster, flume record, flume review — and the org chart is Flume's record.

pjangler describe still reports a repository's employees, and pjangler init carries existing .project.json agents entries forward. Neither writes a new one: that block is a one-way projection of the org chart, not a place a project declares intent.

Orienting in a repo

describe reads a repo and reports what it actually is — detected type, installed subsystems, config files present, and what to do next. It is the first call for an agent (or a human) landing somewhere unfamiliar, and it works in any repo, 33GOD or not.

pjangler describe                # current directory
pjangler describe ../some-repo
pjangler describe --json         # machine-parseable, for agent context
pjangler describe --interactive  # tick off fixable findings, press A to apply

Subsystem presence and subsystem correctness are reported separately: presence comes from marker files on disk, parity from the recipe's own audit rules. A subsystem that was never installed reads absent, not broken.

Last activity, not lifecycle status

Projects report when work last happened, not a lifecycle word. The old status field said planned for 22 of 27 registered projects — including ones with commits the same day — so it never varied and never informed.

Activity is computed from git at read time, so it cannot go stale and no cron has to walk the registry. It spans more than the checked-out branch:

sourcecovers
refsevery local branch, remote-tracking branch, and tag
worktreesevery linked worktree's HEAD, including detached ones whose commits are on no ref
uncommittedworking-tree edits that are not committed yet

The newest of those wins, and the winning source is always reported. Remote state reflects your last fetch — nothing here touches the network.

pj list orders by that signal, newest work first.

Shell prompt

pjangler-prompt prints one compact line when the working directory is inside a pjangler project, and nothing at all when it is not:

pjangler (PJAN) · 3m

It is a separate binary from the main CLI on purpose — the CLI loads the whole parity rule set and takes ~52ms to boot, while this runs in ~30ms, well inside starship's 500ms budget.

Add it to ~/.config/starship.toml as a second, project-scoped prompt line:

format = "…$all${custom.pjangler}$line_break$character"

[custom.pjangler]
description = "pjangler project context"
when = true
shell = ["sh"]
symbol = "◆"
style = "bold purple"
# The newline lives INSIDE the conditional group, so nothing is emitted —
# not even a blank line — outside a pjangler project.
format = "(\n[$symbol $output]($style))"
command = 'exec pjangler-prompt 2>/dev/null'

$line_break must be named explicitly: it is otherwise absorbed by $all and the extra line lands in the wrong place.

MCP server usage

Run over stdio:

npm run mcp
# or
pjangler-mcp

Exposed tools:

  • pjangler_list_capabilities
  • pjangler_list_parity_rules
  • pjangler_audit_project
  • pjangler_migrate_project
  • pjangler_bootstrap_33god_project
  • pjangler_project_init
  • pjangler_project_list
  • pjangler_project_show
  • pjangler_info
  • pjangler_describe_project
  • pjangler_describe_recipe
  • pjangler_run_recipe

版本与发布记录

@delorenj/pjangler 共发布 73 个版本,首次发布于 2026/06/02;过去 12 个月发布了 73 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
1.5.47latest2026/11/11今天
1.5.462026/11/111 天前
1.5.452026/11/101 天前
1.5.442026/11/075 天前
1.5.432026/11/075 天前
1.5.422026/11/065 天前

关于 @delorenj/pjangler 的常见问题

@delorenj/pjangler 是什么?

Project subsystem bootstrapper CLI

如何安装 @delorenj/pjangler?

在项目目录运行 npm install @delorenj/pjangler,或使用 pnpm add / yarn add / bun add。它还提供命令行工具 pj、pjangler、pjangler-mcp、pjangler-prompt,可以用 npx pj 直接运行。

@delorenj/pjangler 支持 TypeScript 吗?

该包的 package.json 没有声明类型入口。需要类型提示时,可以在 npm 上查找社区维护的 @types/delorenj__pjangler 是否存在。

@delorenj/pjangler 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@delorenj/pjangler 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js >=24。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

@delorenj/pjangler 可以商用吗?

@delorenj/pjangler 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@delorenj/pjangler 的下载量有多少?

根据 npm 官方下载统计,@delorenj/pjangler 在 2026/10/12 – 2026/11/10 这 30 天内被下载 5,870 次,日均约 196 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@delorenj/pjangler 还在维护吗?

最新版本 1.5.47 发布于 2026/11/11(今天);至今共发布 73 个版本,其中过去 12 个月发布了 73 个;首次发布于 2026/06/02。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。