project-mgr 0.3.1 → 0.3.2

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 CHANGED
@@ -1,5 +1,9 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.3.2 - 2026-10-16
4
+
5
+ - Add general and per-command CLI help, no-argument help, and package version aliases without opening the database.
6
+
3
7
  ## 0.3.1 - 2026-10-16
4
8
 
5
9
  ### Changed
package/README.md CHANGED
@@ -127,6 +127,20 @@ Delete `/tmp/project-mgr-manual-test.sqlite` when it is no longer needed.
127
127
 
128
128
  Automated tests use an in-memory database or SQLite files in the system temporary directory; they do not read or write the default database. `PMGR_DB_PATH=:memory:` also works for one command, but each CLI command runs in a separate process and its data disappears when the command exits, so it is not suitable for consecutive manual tests.
129
129
 
130
+ ## CLI help and version
131
+
132
+ ```bash
133
+ pmgr # Show general help
134
+ pmgr -h # Also: --help or help
135
+ pmgr add --help # Command usage and available options
136
+ pmgr help history # Equivalent to history -h
137
+ pmgr -v # Also: -V, --version, or version
138
+ ```
139
+
140
+ Help and version commands exit successfully without opening or creating a database.
141
+ Version output comes from the installed package metadata. The compatible
142
+ `pmgr status <command> --help` form is also supported.
143
+
130
144
  ## Quick start
131
145
 
132
146
  Append a project status:
package/dist/cli.js CHANGED
@@ -3,22 +3,32 @@ import { readFileSync, realpathSync } from "node:fs";
3
3
  import { basename } from "node:path";
4
4
  import { pathToFileURL } from "node:url";
5
5
  import { addStatus, at, current, history, importLedger, exportLedger, changeCompletion, listProjects, openLedger, parseTime, setProjectMetadata, startServer, ValidationError, } from "./index.js";
6
+ const booleanFlags = new Set([
7
+ "json",
8
+ "clear-description",
9
+ "clear-notes",
10
+ "open",
11
+ "no-open",
12
+ "help",
13
+ "version",
14
+ ]);
6
15
  const repeats = new Set(["next", "blocker", "decision", "tag", "completes"]);
7
16
  function parse(argv) {
8
17
  const command = [];
9
18
  const flags = Object.create(null);
10
19
  for (let index = 0; index < argv.length; index += 1) {
11
- const token = argv[index];
20
+ const raw = argv[index];
21
+ const token = raw === "-h"
22
+ ? "--help"
23
+ : raw === "-v" || raw === "-V"
24
+ ? "--version"
25
+ : raw;
12
26
  if (!token.startsWith("--")) {
13
27
  command.push(token);
14
28
  continue;
15
29
  }
16
30
  const key = token.slice(2);
17
- if (key === "json" ||
18
- key === "clear-description" ||
19
- key === "clear-notes" ||
20
- key === "open" ||
21
- key === "no-open") {
31
+ if (booleanFlags.has(key)) {
22
32
  if (flags[key] !== undefined)
23
33
  throw new ValidationError(`--${key} may only be supplied once`);
24
34
  flags[key] = true;
@@ -83,6 +93,78 @@ const allowedFlags = new Map([
83
93
  ["export", new Set(["project", "format"])],
84
94
  ["serve", new Set(["port", "host", "open", "no-open", "json"])],
85
95
  ]);
96
+ const commandHelp = {
97
+ add: [
98
+ "Append a status snapshot",
99
+ "--project <name> --summary <text> [options]",
100
+ ],
101
+ complete: [
102
+ "Link a completed activity to its follow-up",
103
+ "--entry <id-or-uid> --by <id-or-uid> [options]",
104
+ ],
105
+ "revoke-completion": [
106
+ "Revoke an activity completion link",
107
+ "--entry <id-or-uid> --by <id-or-uid> [options]",
108
+ ],
109
+ import: [
110
+ "Import a JSON or JSONL ledger",
111
+ "<file> [--json] | --file <path> [--json]",
112
+ ],
113
+ current: [
114
+ "Show the latest status of each project",
115
+ "[--project <name>] [--json]",
116
+ ],
117
+ projects: ["List or search projects", "[--query <text>] [--json]"],
118
+ list: ["Alias for projects", "[--query <text>] [--json]"],
119
+ "set-project": ["Update project metadata", "--project <name> [options]"],
120
+ history: [
121
+ "Show status history, newest first",
122
+ "[--project <name>] [options]",
123
+ ],
124
+ at: [
125
+ "Show a project's status at a time",
126
+ "--project <name> --at <ISO-timestamp> [--json]",
127
+ ],
128
+ export: [
129
+ "Export a portable ledger",
130
+ "[--project <name>] [--format json|jsonl]",
131
+ ],
132
+ serve: [
133
+ "Start the local web dashboard",
134
+ "[--port <number>] [--host <address>] [--no-open] [--json]",
135
+ ],
136
+ };
137
+ function help(action) {
138
+ if (action) {
139
+ const [description, usage] = commandHelp[action];
140
+ const options = [...allowedFlags.get(action)].map((key) => ` --${key}${booleanFlags.has(key) ? "" : " <value>"}${repeats.has(key) ? " (repeatable)" : ""}`);
141
+ return `Usage: pmgr ${action} ${usage}\n\n${description}\n\nOptions:\n${options.join("\n")}\n -h, --help Show this help\n`;
142
+ }
143
+ return `Usage: pmgr <command> [options]
144
+ pmgr status <command> [options]
145
+
146
+ Local-first, append-only project status ledger.
147
+
148
+ Commands:
149
+ ${Object.entries(commandHelp)
150
+ .map(([name, [description]]) => ` ${name.padEnd(20)}${description}`)
151
+ .join("\n")}
152
+ help [command] Show general or command help
153
+ version Show the installed package version
154
+
155
+ Options:
156
+ -h, --help Show help (also supported after a command)
157
+ -v, -V, --version Show the installed package version
158
+
159
+ Environment:
160
+ PMGR_DB_PATH SQLite path (default: ~/.local/share/project-mgr/project-mgr.sqlite)
161
+
162
+ Examples:
163
+ pmgr current --json
164
+ pmgr add --project demo --status active --summary "Work started"
165
+ pmgr help history
166
+ `;
167
+ }
86
168
  function validateInvocation(command, flags) {
87
169
  const statusCommand = command[0] === "status";
88
170
  const action = command[statusCommand ? 1 : 0];
@@ -182,6 +264,26 @@ function imported(file) {
182
264
  }
183
265
  export function run(argv, write = process.stdout.write.bind(process.stdout)) {
184
266
  const { command, flags } = parse(argv);
267
+ if (command[0] === "help") {
268
+ command.shift();
269
+ flags.help = true;
270
+ }
271
+ if (argv.length === 0 || flags.help === true) {
272
+ delete flags.help;
273
+ const action = command.length || Object.keys(flags).length
274
+ ? validateInvocation(command, flags)
275
+ : undefined;
276
+ write(help(action));
277
+ return;
278
+ }
279
+ if (flags.version === true || command[0] === "version") {
280
+ if (Object.keys(flags).some((key) => key !== "version") ||
281
+ (command.length > 0 && (command.length !== 1 || command[0] !== "version")))
282
+ throw new ValidationError("usage: pmgr --version (or: pmgr version)");
283
+ const metadata = JSON.parse(readFileSync(new URL("../package.json", import.meta.url), "utf8"));
284
+ write(`${metadata.version}\n`);
285
+ return;
286
+ }
185
287
  const action = validateInvocation(command, flags);
186
288
  const db = openLedger();
187
289
  const json = flags.json === true;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "project-mgr",
3
- "version": "0.3.1",
3
+ "version": "0.3.2",
4
4
  "description": "Local-first append-only project status ledger",
5
5
  "type": "module",
6
6
  "bin": {
@@ -7,7 +7,7 @@ description: Manage project status with the local-first project-mgr CLI. Use whe
7
7
 
8
8
  ## CLI selection
9
9
 
10
- Prefer an installed `pmgr`: locate it with `command -v pmgr` and check the installed package metadata/documentation for the required version and capabilities. The current CLI does not implement `--help` or `--version`; do not use those flags as health checks. In a source checkout, use `pnpm pmgr` only when the local dependencies are already installed and the package manager is available without downloading it.
10
+ Prefer an installed `pmgr`: locate it with `command -v pmgr` and check the installed package metadata/documentation for the required version and capabilities. This source revision supports `-h` / `--help`, `help [command]`, and `-v` / `-V` / `--version` / `version` without opening the database. Older installed releases may not support these flags; inspect their package metadata instead. In a source checkout, use `pnpm pmgr` only when the local dependencies are already installed and the package manager is available without downloading it.
11
11
 
12
12
  Do not automatically install or upgrade dependencies, or fall back to `npx` / `npm exec`. If no usable CLI is available, report the missing executable, dependency, or capability and the setup needed. Perform installation or upgrades only when the user authorizes that setup.
13
13