artshelf 0.4.0 → 0.5.0
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 +16 -0
- package/README.md +9 -4
- package/SPEC.md +11 -7
- package/dist/src/cli.js +10 -2
- package/dist/src/ledger.js +2 -2
- package/dist/src/registry.js +5 -5
- package/docs/agent-usage.html +8 -2
- package/docs/agent-usage.md +6 -2
- package/docs/quickstart.html +2 -2
- package/docs/reference.html +10 -4
- package/package.json +1 -1
- package/skills/artshelf/SKILL.md +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -52,6 +52,22 @@
|
|
|
52
52
|
- Tightened the portable agent skill description so the completion-gate trigger
|
|
53
53
|
is visible before final responses, status updates, handoffs, and done reports.
|
|
54
54
|
|
|
55
|
+
## [0.5.0](https://github.com/calvinnwq/artshelf/compare/artshelf-v0.4.1...artshelf-v0.5.0) (2026-06-05)
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
### Features
|
|
59
|
+
|
|
60
|
+
* default storage to .artshelf paths ([95ef94e](https://github.com/calvinnwq/artshelf/commit/95ef94edef5862c45e5526a27c4adf0bf40306ca))
|
|
61
|
+
* default storage to .artshelf paths ([0da2cda](https://github.com/calvinnwq/artshelf/commit/0da2cda19ff56f78f203840ed71c2379f533750b))
|
|
62
|
+
|
|
63
|
+
## [0.4.1](https://github.com/calvinnwq/artshelf/compare/artshelf-v0.4.0...artshelf-v0.4.1) (2026-06-05)
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
### Bug Fixes
|
|
67
|
+
|
|
68
|
+
* read CLI version from package metadata ([dafffe9](https://github.com/calvinnwq/artshelf/commit/dafffe9c6d1f1d4aba0062ae64b15f8a919b5b62))
|
|
69
|
+
* read CLI version from package metadata ([72dcc9d](https://github.com/calvinnwq/artshelf/commit/72dcc9d03d34f3c688a05a1d767931d82587d88a))
|
|
70
|
+
|
|
55
71
|
## [0.4.0](https://github.com/calvinnwq/artshelf/compare/artshelf-v0.3.0...artshelf-v0.4.0) (2026-06-05)
|
|
56
72
|
|
|
57
73
|
|
package/README.md
CHANGED
|
@@ -116,8 +116,8 @@ This adds a separate approval boundary between quarantine and destructive deleti
|
|
|
116
116
|
|
|
117
117
|
## Explicit Ledgers
|
|
118
118
|
|
|
119
|
-
By default, Artshelf writes repo-local `.
|
|
120
|
-
`~/.
|
|
119
|
+
By default, Artshelf writes repo-local `.artshelf/ledger.jsonl` inside a git repo and
|
|
120
|
+
`~/.artshelf/ledger.jsonl` outside one. Use `--ledger <path>` and an isolated
|
|
121
121
|
`--registry <path>` for tests, demos, and unusual workflows:
|
|
122
122
|
|
|
123
123
|
```bash
|
|
@@ -126,16 +126,21 @@ artshelf list --ledger /tmp/artshelf-ledger.jsonl
|
|
|
126
126
|
```
|
|
127
127
|
|
|
128
128
|
Artshelf also keeps a small global registry of known ledgers at
|
|
129
|
-
`~/.
|
|
129
|
+
`~/.artshelf/ledgers.json`. Override it with `--registry <path>` or
|
|
130
130
|
`ARTSHELF_REGISTRY`; renamed installs still honor legacy `SHELF_REGISTRY` when
|
|
131
131
|
`ARTSHELF_REGISTRY` is unset. `put` registers its ledger automatically, and you
|
|
132
132
|
can register an existing ledger explicitly:
|
|
133
133
|
|
|
134
134
|
```bash
|
|
135
135
|
artshelf ledgers list
|
|
136
|
-
artshelf ledgers add --ledger /path/to/repo/.
|
|
136
|
+
artshelf ledgers add --ledger /path/to/repo/.artshelf/ledger.jsonl --name my-repo
|
|
137
137
|
```
|
|
138
138
|
|
|
139
|
+
Renamed installs before `0.5.0` used `.shelf` storage paths. Migrate by copying
|
|
140
|
+
each ledger directory to `.artshelf`, rewriting registry paths to the copied
|
|
141
|
+
ledgers, validating with `artshelf ledgers list --json`, and keeping the old
|
|
142
|
+
`.shelf` directories until rollback is no longer needed.
|
|
143
|
+
|
|
139
144
|
`artshelf ledgers list` validates each registered ledger by default — reporting
|
|
140
145
|
ok/missing/invalid status with entry counts, and exiting non-zero when the
|
|
141
146
|
registry or any ledger is broken — so it doubles as a stale-entry check. Add
|
package/SPEC.md
CHANGED
|
@@ -428,8 +428,8 @@ Rules:
|
|
|
428
428
|
|
|
429
429
|
V1 supports two scopes:
|
|
430
430
|
|
|
431
|
-
- repo-local: `.
|
|
432
|
-
- user-global: `~/.
|
|
431
|
+
- repo-local: `.artshelf/ledger.jsonl`
|
|
432
|
+
- user-global: `~/.artshelf/ledger.jsonl`
|
|
433
433
|
|
|
434
434
|
Default behavior:
|
|
435
435
|
|
|
@@ -439,10 +439,14 @@ Default behavior:
|
|
|
439
439
|
|
|
440
440
|
V1 also supports a user-level registry of known ledgers:
|
|
441
441
|
|
|
442
|
-
- registry: `~/.
|
|
442
|
+
- registry: `~/.artshelf/ledgers.json`
|
|
443
443
|
- `--registry <path>` overrides the registry path. Without it,
|
|
444
444
|
`ARTSHELF_REGISTRY` is read first, then legacy `SHELF_REGISTRY`, then the
|
|
445
445
|
default registry path.
|
|
446
|
+
- Legacy `.shelf` ledgers are not deleted or moved automatically. Migration is
|
|
447
|
+
copy-first: copy ledger directories to `.artshelf`, rewrite registry entries,
|
|
448
|
+
validate the new registry, and retain the old `.shelf` directories for
|
|
449
|
+
rollback until the new paths are proven quiet.
|
|
446
450
|
- Retention and due calculations use wall-clock time by default. `ARTSHELF_NOW`
|
|
447
451
|
overrides it for tests and controlled runs; legacy `SHELF_NOW` is read only
|
|
448
452
|
when `ARTSHELF_NOW` is unset.
|
|
@@ -462,7 +466,7 @@ V1 also supports a user-level registry of known ledgers:
|
|
|
462
466
|
"ledgers": [
|
|
463
467
|
{
|
|
464
468
|
"name": "my-repo",
|
|
465
|
-
"path": "/absolute/path/to/repo/.
|
|
469
|
+
"path": "/absolute/path/to/repo/.artshelf/ledger.jsonl",
|
|
466
470
|
"scope": "repo",
|
|
467
471
|
"createdAt": "2026-06-01T05:42:00Z",
|
|
468
472
|
"updatedAt": "2026-06-01T05:42:00Z"
|
|
@@ -506,9 +510,9 @@ Handled records may include cleanup outcome fields:
|
|
|
506
510
|
```json
|
|
507
511
|
{
|
|
508
512
|
"cleanupPlanId": "plan_20260601_154200_cd34",
|
|
509
|
-
"receiptPath": "/absolute/path/.
|
|
513
|
+
"receiptPath": "/absolute/path/.artshelf/receipts/plan_20260601_154200_cd34.json",
|
|
510
514
|
"cleanedAt": "2026-06-01T05:45:00Z",
|
|
511
|
-
"targetPath": "/absolute/path/.
|
|
515
|
+
"targetPath": "/absolute/path/.artshelf/trash/plan_20260601_154200_cd34/shf_20260601_154200_ab12-artifact",
|
|
512
516
|
"cleanupReason": "delete is disabled in v1"
|
|
513
517
|
}
|
|
514
518
|
```
|
|
@@ -531,7 +535,7 @@ the purge provenance:
|
|
|
531
535
|
"resolutionReason": "trash purge completed",
|
|
532
536
|
"purgedAt": "2026-06-01T06:10:00Z",
|
|
533
537
|
"purgePlanId": "purge_20260601_061000_ef56",
|
|
534
|
-
"purgeReceiptPath": "/absolute/path/.
|
|
538
|
+
"purgeReceiptPath": "/absolute/path/.artshelf/purge-receipts/purge_20260601_061000_ef56.json"
|
|
535
539
|
}
|
|
536
540
|
```
|
|
537
541
|
|
package/dist/src/cli.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { existsSync } from "node:fs";
|
|
2
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
3
3
|
import { appendPreparedRecord, createCleanupPlan, createTrashPurgePlan, dueEntries, executeCleanupPlan, executeTrashPurgePlan, filterRecordsByStatus, findRecords, getRecord, listTrashedRecords, normalizeLedgerPath, prepareRecord, previewCleanupPlan, readLedger, resolveRecord, validateLedger } from "./ledger.js";
|
|
4
4
|
import { listRegisteredLedgers, normalizeRegistryPath, registerLedger } from "./registry.js";
|
|
5
|
-
const VERSION =
|
|
5
|
+
const VERSION = readPackageVersion();
|
|
6
6
|
const BOOLEAN_FLAGS = new Set(["all", "json", "manual-review", "dry-run", "execute", "help", "version", "plain"]);
|
|
7
7
|
const VALUE_FLAGS = new Set([
|
|
8
8
|
"cleanup",
|
|
@@ -21,6 +21,14 @@ const VALUE_FLAGS = new Set([
|
|
|
21
21
|
"status",
|
|
22
22
|
"ttl"
|
|
23
23
|
]);
|
|
24
|
+
function readPackageVersion() {
|
|
25
|
+
const packageJsonPath = decodeURIComponent(new URL("../../package.json", import.meta.url).pathname);
|
|
26
|
+
const packageJson = JSON.parse(readFileSync(packageJsonPath, "utf8"));
|
|
27
|
+
if (typeof packageJson.version !== "string") {
|
|
28
|
+
throw new Error("package.json version must be a string");
|
|
29
|
+
}
|
|
30
|
+
return packageJson.version;
|
|
31
|
+
}
|
|
24
32
|
function main(argv) {
|
|
25
33
|
try {
|
|
26
34
|
const parsed = parseArgs(argv);
|
package/dist/src/ledger.js
CHANGED
|
@@ -18,8 +18,8 @@ const RESOLVE_STATUSES = new Set(["resolved"]);
|
|
|
18
18
|
export function defaultLedgerPath(cwd = process.cwd()) {
|
|
19
19
|
const repoRoot = findGitRoot(cwd);
|
|
20
20
|
if (repoRoot)
|
|
21
|
-
return join(repoRoot, ".
|
|
22
|
-
return join(homedir(), ".
|
|
21
|
+
return join(repoRoot, ".artshelf", "ledger.jsonl");
|
|
22
|
+
return join(homedir(), ".artshelf", "ledger.jsonl");
|
|
23
23
|
}
|
|
24
24
|
export function normalizeLedgerPath(path) {
|
|
25
25
|
return resolve(path ?? defaultLedgerPath());
|
package/dist/src/registry.js
CHANGED
|
@@ -3,7 +3,7 @@ import { homedir } from "node:os";
|
|
|
3
3
|
import { basename, dirname, join, resolve } from "node:path";
|
|
4
4
|
import { now, toIso } from "./time.js";
|
|
5
5
|
export function defaultRegistryPath() {
|
|
6
|
-
return process.env.ARTSHELF_REGISTRY ?? process.env.SHELF_REGISTRY ?? join(homedir(), ".
|
|
6
|
+
return process.env.ARTSHELF_REGISTRY ?? process.env.SHELF_REGISTRY ?? join(homedir(), ".artshelf", "ledgers.json");
|
|
7
7
|
}
|
|
8
8
|
export function normalizeRegistryPath(path) {
|
|
9
9
|
return resolve(path ?? defaultRegistryPath());
|
|
@@ -116,17 +116,17 @@ function normalizeName(name) {
|
|
|
116
116
|
}
|
|
117
117
|
function inferLedgerName(ledgerPath) {
|
|
118
118
|
const normalized = resolve(ledgerPath);
|
|
119
|
-
if (normalized === join(homedir(), ".
|
|
119
|
+
if (normalized === join(homedir(), ".artshelf", "ledger.jsonl"))
|
|
120
120
|
return "global";
|
|
121
|
-
if (basename(dirname(normalized)) === ".
|
|
121
|
+
if (basename(dirname(normalized)) === ".artshelf")
|
|
122
122
|
return basename(dirname(dirname(normalized))) || "repo";
|
|
123
123
|
return basename(dirname(normalized)) || "ledger";
|
|
124
124
|
}
|
|
125
125
|
function inferLedgerScope(ledgerPath) {
|
|
126
126
|
const normalized = resolve(ledgerPath);
|
|
127
|
-
if (normalized.startsWith(join(homedir(), ".
|
|
127
|
+
if (normalized.startsWith(join(homedir(), ".artshelf")))
|
|
128
128
|
return "user";
|
|
129
|
-
if (basename(dirname(normalized)) === ".
|
|
129
|
+
if (basename(dirname(normalized)) === ".artshelf")
|
|
130
130
|
return "repo";
|
|
131
131
|
return "other";
|
|
132
132
|
}
|
package/docs/agent-usage.html
CHANGED
|
@@ -143,16 +143,22 @@ artshelf get <id> --json</code></pre>
|
|
|
143
143
|
<section>
|
|
144
144
|
<h2>Ledger Registry</h2>
|
|
145
145
|
<p>
|
|
146
|
-
Artshelf keeps a user-level registry at `~/.
|
|
146
|
+
Artshelf keeps a user-level registry at `~/.artshelf/ledgers.json` so one CLI can
|
|
147
147
|
review all known ledgers without moving project records into one global file.
|
|
148
148
|
<code>put</code> registers the ledger it writes to.
|
|
149
149
|
</p>
|
|
150
|
-
<pre><code>artshelf ledgers add --ledger <repo>/.
|
|
150
|
+
<pre><code>artshelf ledgers add --ledger <repo>/.artshelf/ledger.jsonl --name <project> --scope repo
|
|
151
151
|
artshelf ledgers list --json
|
|
152
152
|
artshelf review --all --json
|
|
153
153
|
artshelf status --all --json
|
|
154
154
|
artshelf find --all --owner <agent-or-runtime> --json
|
|
155
155
|
artshelf trash list --all --json</code></pre>
|
|
156
|
+
<p>
|
|
157
|
+
Renamed installs before <code>0.5.0</code> used <code>.shelf</code> paths. For migration,
|
|
158
|
+
copy the old ledger directories into <code>.artshelf</code>, rewrite registry entries,
|
|
159
|
+
validate the new registry, and keep the <code>.shelf</code> copies until rollback is no
|
|
160
|
+
longer needed.
|
|
161
|
+
</p>
|
|
156
162
|
<p>
|
|
157
163
|
<code>artshelf ledgers list --json</code> validates each registered ledger and reports
|
|
158
164
|
ok/missing/invalid status with entry and warning/error counts, so agents can detect
|
package/docs/agent-usage.md
CHANGED
|
@@ -110,16 +110,20 @@ returns no entries, call `put` and record the new id.
|
|
|
110
110
|
|
|
111
111
|
## Ledger Registry
|
|
112
112
|
|
|
113
|
-
Artshelf keeps a user-level registry at `~/.
|
|
113
|
+
Artshelf keeps a user-level registry at `~/.artshelf/ledgers.json` so one CLI can
|
|
114
114
|
review all known ledgers without moving project records into one global file.
|
|
115
115
|
`put` registers the ledger it writes to. Register existing ledgers explicitly
|
|
116
116
|
when adopting Artshelf for an existing project:
|
|
117
117
|
|
|
118
118
|
```bash
|
|
119
|
-
artshelf ledgers add --ledger <repo>/.
|
|
119
|
+
artshelf ledgers add --ledger <repo>/.artshelf/ledger.jsonl --name <project> --scope repo
|
|
120
120
|
artshelf ledgers list --json
|
|
121
121
|
```
|
|
122
122
|
|
|
123
|
+
Renamed installs before `0.5.0` used `.shelf` paths. For migration, copy the old
|
|
124
|
+
ledger directories into `.artshelf`, rewrite registry entries, validate the new
|
|
125
|
+
registry, and keep the `.shelf` copies until rollback is no longer needed.
|
|
126
|
+
|
|
123
127
|
`artshelf ledgers list --json` validates each registered ledger and reports
|
|
124
128
|
ok/missing/invalid status with entry and warning/error counts, so agents can
|
|
125
129
|
detect stale registry entries without a separate validate pass. Add `--plain`
|
package/docs/quickstart.html
CHANGED
|
@@ -94,7 +94,7 @@ artshelf validate --ledger /tmp/artshelf-ledger.jsonl --json
|
|
|
94
94
|
artshelf due --ledger /tmp/artshelf-ledger.jsonl --json
|
|
95
95
|
artshelf cleanup --dry-run --ledger /tmp/artshelf-ledger.jsonl --json</code></pre>
|
|
96
96
|
<p>
|
|
97
|
-
Dry-run writes a plan under the ledger's `.
|
|
97
|
+
Dry-run writes a plan under the ledger's `.artshelf` directory only when
|
|
98
98
|
cleanup entries exist. If there is nothing to clean up, it reports
|
|
99
99
|
<code>not-created</code> and writes no plan file. Review any generated
|
|
100
100
|
plan id before an execute step.
|
|
@@ -119,7 +119,7 @@ artshelf cleanup --dry-run --ledger /tmp/artshelf-ledger.jsonl --json</code></pr
|
|
|
119
119
|
<h2>4. Purge old trashed records explicitly</h2>
|
|
120
120
|
<p>
|
|
121
121
|
After cleanup execution, trashed files are quarantined under the ledger's
|
|
122
|
-
<code>.
|
|
122
|
+
<code>.artshelf/trash</code> folder. Before physical deletion, run an explicit
|
|
123
123
|
reviewed trash purge plan:
|
|
124
124
|
</p>
|
|
125
125
|
<pre><code>artshelf trash list --ledger /tmp/artshelf-ledger.jsonl
|
package/docs/reference.html
CHANGED
|
@@ -138,18 +138,24 @@ artshelf get <id> --all --json</code></pre>
|
|
|
138
138
|
<section>
|
|
139
139
|
<h2>Storage</h2>
|
|
140
140
|
<p>
|
|
141
|
-
Inside a git repo, Artshelf defaults to `.
|
|
142
|
-
defaults to `~/.
|
|
141
|
+
Inside a git repo, Artshelf defaults to `.artshelf/ledger.jsonl`. Outside a repo, it
|
|
142
|
+
defaults to `~/.artshelf/ledger.jsonl`. Pass `--ledger <path>` for tests, demos,
|
|
143
143
|
and controlled smoke runs.
|
|
144
144
|
</p>
|
|
145
145
|
<p>
|
|
146
|
-
Artshelf also keeps a user-level registry at `~/.
|
|
146
|
+
Artshelf also keeps a user-level registry at `~/.artshelf/ledgers.json`. Override it
|
|
147
147
|
with <code>--registry <path></code> or <code>ARTSHELF_REGISTRY</code>; legacy
|
|
148
148
|
<code>SHELF_REGISTRY</code> is used only when <code>ARTSHELF_REGISTRY</code> is unset.
|
|
149
149
|
The registry is a discovery index for supported `--all` review, status, cleanup
|
|
150
150
|
dry-run, and trash-list commands; project records stay in their own repo-local ledgers.
|
|
151
151
|
</p>
|
|
152
|
-
<
|
|
152
|
+
<p>
|
|
153
|
+
Renamed installs before <code>0.5.0</code> used <code>.shelf</code> paths. Copy those
|
|
154
|
+
ledgers into <code>.artshelf</code>, rewrite registry paths, validate with
|
|
155
|
+
<code>artshelf ledgers list --json</code>, and keep the old directories until rollback
|
|
156
|
+
is no longer needed.
|
|
157
|
+
</p>
|
|
158
|
+
<pre><code>artshelf ledgers add --ledger <repo>/.artshelf/ledger.jsonl --name <project> --scope repo
|
|
153
159
|
artshelf review --all --json
|
|
154
160
|
artshelf status --all --json
|
|
155
161
|
artshelf cleanup --dry-run --all --json
|
package/package.json
CHANGED
package/skills/artshelf/SKILL.md
CHANGED
|
@@ -121,7 +121,7 @@ next safe action.
|
|
|
121
121
|
them explicitly:
|
|
122
122
|
|
|
123
123
|
```bash
|
|
124
|
-
artshelf ledgers add --ledger <repo>/.
|
|
124
|
+
artshelf ledgers add --ledger <repo>/.artshelf/ledger.jsonl --name <project> --scope repo --json
|
|
125
125
|
```
|
|
126
126
|
|
|
127
127
|
`--all` is for discovery and review. Do not use it as permission to mutate
|