project-mgr 0.3.0 → 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 +14 -0
- package/README.md +14 -0
- package/dist/cli.js +108 -6
- package/package.json +1 -1
- package/skills/project-mgr/SKILL.md +24 -17
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
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
|
+
|
|
7
|
+
## 0.3.1 - 2026-10-16
|
|
8
|
+
|
|
9
|
+
### Changed
|
|
10
|
+
|
|
11
|
+
- Prefer an installed `pmgr` in the Skill and remove automatic `npx @latest` execution from examples.
|
|
12
|
+
- Require explicit status values and evidence-backed historical backfills without a minimum entry count.
|
|
13
|
+
- Document database permission handling, stable ledger paths, and read-back verification after writes.
|
|
14
|
+
|
|
15
|
+
This release updates Skill guidance only; CLI behavior and storage architecture are unchanged.
|
|
16
|
+
|
|
3
17
|
## 0.3.0 - 2026-10-16
|
|
4
18
|
|
|
5
19
|
### Added
|
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
|
|
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
|
|
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
|
@@ -5,7 +5,11 @@ description: Manage project status with the local-first project-mgr CLI. Use whe
|
|
|
5
5
|
|
|
6
6
|
# project-mgr
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
## CLI selection
|
|
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. 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
|
+
|
|
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.
|
|
9
13
|
|
|
10
14
|
Completion links and version-2 exports require project-mgr 0.3.0 or later. This skill is updated through Git and has no independent release version.
|
|
11
15
|
|
|
@@ -13,9 +17,12 @@ Completion links and version-2 exports require project-mgr 0.3.0 or later. This
|
|
|
13
17
|
|
|
14
18
|
- Read `PMGR_DB_PATH` before operating. If unset, the CLI uses `~/.local/share/project-mgr/project-mgr.sqlite`.
|
|
15
19
|
- For exploratory or test work, set `PMGR_DB_PATH` to a dedicated absolute SQLite path for every command. Do not use `:memory:` when more than one CLI invocation must share data.
|
|
16
|
-
-
|
|
20
|
+
- The database file and its parent directory must be accessible with the permissions SQLite needs for journal files and writes. Even query commands open the ledger and may initialize or migrate it; do not assume they are filesystem-read-only.
|
|
21
|
+
- On a permission or read-only database error, report the command, resolved database path, and error without exposing credentials. Use the environment's approved permission mechanism when available; otherwise report the blocked operation. Do not reinstall the CLI, change permissions, or silently switch to another database to work around the error. Change the ledger location only when the user requests it.
|
|
22
|
+
- Query before writing. `add` appends a snapshot; it does not edit the previous one. Read back the affected state after writing and report success only when verified. If a write's outcome is uncertain, query before retrying to avoid duplicates.
|
|
17
23
|
- Set `--source agent` for agent-authored updates. Use `--external-ref` only when a stable idempotency key is available.
|
|
18
|
-
-
|
|
24
|
+
- Explicitly pass `--status` on every `add`, and include `status` in every agent-authored import entry. The CLI defaults to `completed`; do not rely on that default. Choose the status from the evidence and inspect the current snapshot when unclear. Completing one activity does not necessarily complete the project; use `active` when project work continues. If the status remains uncertain, clarify before writing.
|
|
25
|
+
- If the project is not yet in the ledger database, initialize its metadata with `set-project`. Backfill only milestones supported by verifiable Git commits, dated documents, or historical records, and include the evidence reference in `--progress`. Use historical `--at` timestamps only when supported by that evidence; a commit timestamp proves a commit, not a deployment. There is no required number of entries. Never invent milestones or dates; when evidence is unavailable, skip backfill and append only the current known status.
|
|
19
26
|
|
|
20
27
|
## Metadata vs. status entries
|
|
21
28
|
|
|
@@ -32,32 +39,32 @@ Prefer `--json` for data that must be interpreted or reported programmatically.
|
|
|
32
39
|
|
|
33
40
|
```bash
|
|
34
41
|
# Set, update, or clear project metadata (description, notes, display name).
|
|
35
|
-
|
|
36
|
-
|
|
42
|
+
pmgr set-project --project my-project --description "Project summary" --notes "Internal notes" --json
|
|
43
|
+
pmgr set-project --project my-project --clear-description --clear-notes --json
|
|
37
44
|
|
|
38
45
|
# List all projects or fuzzy search across project names, descriptions, notes, status summaries, and tags.
|
|
39
|
-
|
|
40
|
-
|
|
46
|
+
pmgr projects --json
|
|
47
|
+
pmgr list --query "keyword" --json
|
|
41
48
|
|
|
42
49
|
# Start the local Web Dashboard & REST API server.
|
|
43
|
-
|
|
50
|
+
pmgr serve --port 3000 --no-open --json
|
|
44
51
|
|
|
45
|
-
#
|
|
46
|
-
|
|
52
|
+
# Record a completed milestone while the project remains active.
|
|
53
|
+
pmgr add --project my-project --status active --summary "Implemented the CLI" \
|
|
47
54
|
--progress "Tests pass" --next "Publish the package" --source agent --json
|
|
48
55
|
|
|
49
56
|
# Query current state, history, or state at a time.
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
57
|
+
pmgr current --project my-project --json
|
|
58
|
+
pmgr history --project my-project --limit 20 --json
|
|
59
|
+
pmgr history --limit 20 --json
|
|
60
|
+
pmgr at --project my-project --at 2026-08-03T12:00:00+08:00 --json
|
|
54
61
|
|
|
55
62
|
# Import validated JSON/JSONL, or export portable records.
|
|
56
|
-
|
|
57
|
-
|
|
63
|
+
pmgr import statuses.jsonl --json
|
|
64
|
+
pmgr export --project my-project --format jsonl > statuses.jsonl
|
|
58
65
|
```
|
|
59
66
|
|
|
60
|
-
Use `PMGR_DB_PATH=/absolute/path/test.sqlite
|
|
67
|
+
Use `PMGR_DB_PATH=/absolute/path/test.sqlite pmgr ...` to isolate a manual test database. Import validates and writes the entire batch within one transaction; export output can be imported directly.
|
|
61
68
|
|
|
62
69
|
## Complete predecessor activities
|
|
63
70
|
|