artshelf 0.4.1 → 0.6.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.
@@ -138,18 +138,24 @@ artshelf get &lt;id&gt; --all --json</code></pre>
138
138
  <section>
139
139
  <h2>Storage</h2>
140
140
  <p>
141
- Inside a git repo, Artshelf defaults to `.shelf/ledger.jsonl`. Outside a repo, it
142
- defaults to `~/.shelf/ledger.jsonl`. Pass `--ledger &lt;path&gt;` for tests, demos,
141
+ Inside a git repo, Artshelf defaults to `.artshelf/ledger.jsonl`. Outside a repo, it
142
+ defaults to `~/.artshelf/ledger.jsonl`. Pass `--ledger &lt;path&gt;` for tests, demos,
143
143
  and controlled smoke runs.
144
144
  </p>
145
145
  <p>
146
- Artshelf also keeps a user-level registry at `~/.shelf/ledgers.json`. Override it
146
+ Artshelf also keeps a user-level registry at `~/.artshelf/ledgers.json`. Override it
147
147
  with <code>--registry &lt;path&gt;</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
- <pre><code>artshelf ledgers add --ledger &lt;repo&gt;/.shelf/ledger.jsonl --name &lt;project&gt; --scope repo
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 &lt;repo&gt;/.artshelf/ledger.jsonl --name &lt;project&gt; --scope repo
153
159
  artshelf review --all --json
154
160
  artshelf status --all --json
155
161
  artshelf cleanup --dry-run --all --json
@@ -0,0 +1,315 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://calvinnwq.github.io/artshelf/schemas/artshelf-review-report.schema.json",
4
+ "title": "ArtshelfReviewReport",
5
+ "description": "Machine-readable decision packet for rendering an Artshelf review report.",
6
+ "type": "object",
7
+ "additionalProperties": false,
8
+ "required": [
9
+ "schemaVersion",
10
+ "scope",
11
+ "decisionSummary",
12
+ "decisionGroups",
13
+ "summary",
14
+ "recommendation",
15
+ "items",
16
+ "alternatives",
17
+ "safety",
18
+ "verification"
19
+ ],
20
+ "properties": {
21
+ "schemaVersion": {
22
+ "type": "integer",
23
+ "const": 1
24
+ },
25
+ "scope": {
26
+ "type": "object",
27
+ "additionalProperties": false,
28
+ "required": ["registryPath", "ledgerCount", "health", "registryHealth"],
29
+ "properties": {
30
+ "registryPath": { "type": "string" },
31
+ "ledgerCount": { "type": "integer", "minimum": 0 },
32
+ "health": { "type": "string", "enum": ["ok", "attention"] },
33
+ "registryHealth": { "type": "string", "enum": ["ok", "attention"] },
34
+ "affectedLedgers": {
35
+ "type": "array",
36
+ "items": {
37
+ "type": "object",
38
+ "additionalProperties": false,
39
+ "required": ["ledgerPath"],
40
+ "properties": {
41
+ "name": { "type": "string" },
42
+ "ledgerPath": { "type": "string" },
43
+ "validationStatus": {
44
+ "type": "string",
45
+ "enum": ["ok", "missing", "invalid"]
46
+ }
47
+ }
48
+ }
49
+ }
50
+ }
51
+ },
52
+ "plans": {
53
+ "type": "array",
54
+ "items": { "$ref": "#/$defs/plan" },
55
+ "default": []
56
+ },
57
+ "decisionSummary": {
58
+ "type": "object",
59
+ "additionalProperties": false,
60
+ "required": ["readyForApproval", "needsReviewFirst", "blocked"],
61
+ "properties": {
62
+ "readyForApproval": { "type": "integer", "minimum": 0 },
63
+ "needsReviewFirst": { "type": "integer", "minimum": 0 },
64
+ "blocked": { "type": "integer", "minimum": 0 }
65
+ }
66
+ },
67
+ "decisionGroups": {
68
+ "type": "object",
69
+ "additionalProperties": false,
70
+ "required": ["readyForApproval", "needsReviewFirst", "blocked"],
71
+ "properties": {
72
+ "readyForApproval": {
73
+ "type": "array",
74
+ "items": { "$ref": "#/$defs/approvalDecision" }
75
+ },
76
+ "needsReviewFirst": {
77
+ "type": "array",
78
+ "items": { "$ref": "#/$defs/nonApprovalDecision" }
79
+ },
80
+ "blocked": {
81
+ "type": "array",
82
+ "items": { "$ref": "#/$defs/nonApprovalDecision" }
83
+ }
84
+ }
85
+ },
86
+ "summary": {
87
+ "type": "object",
88
+ "additionalProperties": false,
89
+ "required": [
90
+ "executable",
91
+ "skipped",
92
+ "refused",
93
+ "manualReview",
94
+ "missingPath",
95
+ "trashed"
96
+ ],
97
+ "properties": {
98
+ "executable": { "type": "integer", "minimum": 0 },
99
+ "skipped": { "type": "integer", "minimum": 0 },
100
+ "refused": { "type": "integer", "minimum": 0 },
101
+ "manualReview": { "type": "integer", "minimum": 0 },
102
+ "missingPath": { "type": "integer", "minimum": 0 },
103
+ "trashed": { "type": "integer", "minimum": 0 }
104
+ }
105
+ },
106
+ "recommendation": { "type": "string", "minLength": 1 },
107
+ "items": {
108
+ "type": "array",
109
+ "items": { "$ref": "#/$defs/item" }
110
+ },
111
+ "alternatives": {
112
+ "type": "array",
113
+ "minItems": 1,
114
+ "items": { "type": "string", "minLength": 1 }
115
+ },
116
+ "safety": {
117
+ "type": "object",
118
+ "additionalProperties": false,
119
+ "required": [
120
+ "dryRunOnly",
121
+ "executeAllRefused",
122
+ "noExecuteRan",
123
+ "noResolveRan",
124
+ "noDeleteRan"
125
+ ],
126
+ "properties": {
127
+ "dryRunOnly": { "type": "boolean" },
128
+ "executeAllRefused": { "type": "boolean" },
129
+ "noExecuteRan": { "type": "boolean" },
130
+ "noResolveRan": { "type": "boolean" },
131
+ "noDeleteRan": { "type": "boolean" }
132
+ }
133
+ },
134
+ "verification": {
135
+ "type": "object",
136
+ "additionalProperties": false,
137
+ "required": ["command", "successCondition"],
138
+ "properties": {
139
+ "command": { "type": "string", "minLength": 1 },
140
+ "successCondition": { "type": "string", "minLength": 1 }
141
+ }
142
+ }
143
+ },
144
+ "$defs": {
145
+ "plan": {
146
+ "type": "object",
147
+ "additionalProperties": false,
148
+ "required": ["type", "ledgerPath", "planId", "approvalTarget"],
149
+ "properties": {
150
+ "type": { "type": "string", "enum": ["cleanup", "trash-purge"] },
151
+ "ledgerPath": { "type": "string" },
152
+ "planId": { "type": "string" },
153
+ "planPath": { "type": ["string", "null"] },
154
+ "approvalTarget": { "type": "string" }
155
+ },
156
+ "allOf": [
157
+ {
158
+ "if": {
159
+ "properties": { "type": { "const": "cleanup" } },
160
+ "required": ["type"]
161
+ },
162
+ "then": {
163
+ "properties": {
164
+ "approvalTarget": {
165
+ "pattern": "^approve artshelf cleanup ledger .+ plan .+$"
166
+ }
167
+ }
168
+ }
169
+ },
170
+ {
171
+ "if": {
172
+ "properties": { "type": { "const": "trash-purge" } },
173
+ "required": ["type"]
174
+ },
175
+ "then": {
176
+ "properties": {
177
+ "approvalTarget": {
178
+ "pattern": "^approve artshelf trash purge ledger .+ plan .+$"
179
+ }
180
+ }
181
+ }
182
+ }
183
+ ]
184
+ },
185
+ "item": {
186
+ "type": "object",
187
+ "additionalProperties": false,
188
+ "required": [
189
+ "classification",
190
+ "proposedAction",
191
+ "dueStatus",
192
+ "reason",
193
+ "note"
194
+ ],
195
+ "properties": {
196
+ "id": { "type": "string" },
197
+ "path": { "type": "string" },
198
+ "classification": {
199
+ "type": "string",
200
+ "enum": [
201
+ "trash-safe",
202
+ "needs-human-review",
203
+ "resolve-candidate",
204
+ "registry-problem"
205
+ ]
206
+ },
207
+ "proposedAction": { "type": "string", "minLength": 1 },
208
+ "dueStatus": {
209
+ "type": "string",
210
+ "enum": ["kept", "due", "manual-review", "missing-path", "trashed"]
211
+ },
212
+ "reason": { "type": "string", "minLength": 1 },
213
+ "note": { "type": "string", "minLength": 1 }
214
+ },
215
+ "anyOf": [
216
+ { "required": ["id"] },
217
+ { "required": ["path"] }
218
+ ]
219
+ },
220
+ "decision": {
221
+ "type": "object",
222
+ "additionalProperties": false,
223
+ "required": ["label", "actionType", "reason", "nextStep"],
224
+ "properties": {
225
+ "label": { "type": "string", "minLength": 1 },
226
+ "itemIds": {
227
+ "type": "array",
228
+ "items": { "type": "string", "minLength": 1 },
229
+ "default": []
230
+ },
231
+ "actionType": {
232
+ "type": "string",
233
+ "enum": [
234
+ "cleanup",
235
+ "trash-purge",
236
+ "resolve-missing",
237
+ "inspect",
238
+ "fix-registry",
239
+ "keep-or-snooze",
240
+ "change-retention"
241
+ ]
242
+ },
243
+ "approvalTarget": { "type": ["string", "null"] },
244
+ "reason": { "type": "string", "minLength": 1 },
245
+ "nextStep": { "type": "string", "minLength": 1 }
246
+ }
247
+ },
248
+ "approvalDecision": {
249
+ "allOf": [
250
+ { "$ref": "#/$defs/decision" },
251
+ {
252
+ "required": ["approvalTarget"],
253
+ "properties": {
254
+ "actionType": {
255
+ "enum": ["cleanup", "trash-purge", "resolve-missing"]
256
+ },
257
+ "approvalTarget": { "type": "string", "minLength": 1 }
258
+ }
259
+ },
260
+ {
261
+ "if": {
262
+ "properties": { "actionType": { "const": "cleanup" } },
263
+ "required": ["actionType"]
264
+ },
265
+ "then": {
266
+ "properties": {
267
+ "approvalTarget": {
268
+ "pattern": "^approve artshelf cleanup ledger .+ plan .+$"
269
+ }
270
+ }
271
+ }
272
+ },
273
+ {
274
+ "if": {
275
+ "properties": { "actionType": { "const": "trash-purge" } },
276
+ "required": ["actionType"]
277
+ },
278
+ "then": {
279
+ "properties": {
280
+ "approvalTarget": {
281
+ "pattern": "^approve artshelf trash purge ledger .+ plan .+$"
282
+ }
283
+ }
284
+ }
285
+ },
286
+ {
287
+ "if": {
288
+ "properties": { "actionType": { "const": "resolve-missing" } },
289
+ "required": ["actionType"]
290
+ },
291
+ "then": {
292
+ "properties": {
293
+ "approvalTarget": {
294
+ "pattern": "^approve artshelf resolve missing ledger .+ ids .+$"
295
+ }
296
+ }
297
+ }
298
+ }
299
+ ]
300
+ },
301
+ "nonApprovalDecision": {
302
+ "allOf": [
303
+ { "$ref": "#/$defs/decision" },
304
+ {
305
+ "properties": {
306
+ "actionType": {
307
+ "enum": ["inspect", "fix-registry", "keep-or-snooze", "change-retention"]
308
+ },
309
+ "approvalTarget": { "type": "null" }
310
+ }
311
+ }
312
+ ]
313
+ }
314
+ }
315
+ }
@@ -0,0 +1,116 @@
1
+ {
2
+ "schemaVersion": 1,
3
+ "scope": {
4
+ "registryPath": "~/.artshelf/ledgers.json",
5
+ "ledgerCount": 3,
6
+ "health": "attention",
7
+ "registryHealth": "ok",
8
+ "affectedLedgers": [
9
+ {
10
+ "name": "example-project",
11
+ "ledgerPath": "/path/to/example-project/.artshelf/ledger.jsonl",
12
+ "validationStatus": "ok"
13
+ }
14
+ ]
15
+ },
16
+ "plans": [
17
+ {
18
+ "type": "cleanup",
19
+ "ledgerPath": "/path/to/example-project/.artshelf/ledger.jsonl",
20
+ "planId": "plan_20260606_120000_ab12",
21
+ "planPath": "/path/to/example-project/.artshelf/plans/plan_20260606_120000_ab12.json",
22
+ "approvalTarget": "approve artshelf cleanup ledger /path/to/example-project/.artshelf/ledger.jsonl plan plan_20260606_120000_ab12"
23
+ }
24
+ ],
25
+ "summary": {
26
+ "executable": 1,
27
+ "skipped": 2,
28
+ "refused": 0,
29
+ "manualReview": 1,
30
+ "missingPath": 1,
31
+ "trashed": 0
32
+ },
33
+ "decisionSummary": {
34
+ "readyForApproval": 2,
35
+ "needsReviewFirst": 1,
36
+ "blocked": 0
37
+ },
38
+ "decisionGroups": {
39
+ "readyForApproval": [
40
+ {
41
+ "label": "Clean up temp debug output",
42
+ "itemIds": ["shf_20260606_120000_ab12"],
43
+ "actionType": "cleanup",
44
+ "approvalTarget": "approve artshelf cleanup ledger /path/to/example-project/.artshelf/ledger.jsonl plan plan_20260606_120000_ab12",
45
+ "reason": "Disposable temp artifact has a reviewed cleanup plan.",
46
+ "nextStep": "Approve the exact cleanup plan to move the artifact into Artshelf trash."
47
+ },
48
+ {
49
+ "label": "Resolve missing report record",
50
+ "itemIds": ["shf_20260606_120500_cd34"],
51
+ "actionType": "resolve-missing",
52
+ "approvalTarget": "approve artshelf resolve missing ledger /path/to/example-project/.artshelf/ledger.jsonl ids shf_20260606_120500_cd34",
53
+ "reason": "The report path is already missing.",
54
+ "nextStep": "Approve the ledger-only resolve command after confirming the report is no longer needed."
55
+ }
56
+ ],
57
+ "needsReviewFirst": [
58
+ {
59
+ "label": "Inspect lifecycle smoke report",
60
+ "itemIds": ["shf_20260606_121000_ef56"],
61
+ "actionType": "inspect",
62
+ "approvalTarget": null,
63
+ "reason": "cleanup=review means the artifact should be inspected before closing.",
64
+ "nextStep": "Inspect the path, then choose keep, change retention, resolve, or clean up later."
65
+ }
66
+ ],
67
+ "blocked": []
68
+ },
69
+ "recommendation": "Approve the reviewed cleanup plan for the disposable temp directory, then resolve the missing record after confirming it is no longer needed.",
70
+ "items": [
71
+ {
72
+ "id": "shf_20260606_120000_ab12",
73
+ "path": "/tmp/example-debug-output",
74
+ "classification": "trash-safe",
75
+ "proposedAction": "execute reviewed cleanup plan",
76
+ "dueStatus": "due",
77
+ "reason": "temporary debug output retained for 3 days",
78
+ "note": "The path exists, cleanup=trash, and the dry-run plan moves it into Artshelf trash."
79
+ },
80
+ {
81
+ "id": "shf_20260606_120500_cd34",
82
+ "path": "/tmp/missing-report.json",
83
+ "classification": "resolve-candidate",
84
+ "proposedAction": "resolve ledger-only after confirmation",
85
+ "dueStatus": "missing-path",
86
+ "reason": "report path is already missing",
87
+ "note": "Resolution updates only the ledger and does not move or delete files."
88
+ },
89
+ {
90
+ "id": "shf_20260606_121000_ef56",
91
+ "path": "/tmp/lifecycle-smoke-report.json",
92
+ "classification": "needs-human-review",
93
+ "proposedAction": "inspect before choosing cleanup or retention",
94
+ "dueStatus": "manual-review",
95
+ "reason": "cleanup=review artifact retained for manual inspection",
96
+ "note": "No approval target is shown until the review decision is known."
97
+ }
98
+ ],
99
+ "alternatives": [
100
+ "keep the artifact and change retention",
101
+ "inspect the path before approving cleanup",
102
+ "regenerate the plan after edits",
103
+ "resolve missing records ledger-only"
104
+ ],
105
+ "safety": {
106
+ "dryRunOnly": true,
107
+ "executeAllRefused": true,
108
+ "noExecuteRan": true,
109
+ "noResolveRan": true,
110
+ "noDeleteRan": true
111
+ },
112
+ "verification": {
113
+ "command": "artshelf review --all --json",
114
+ "successCondition": "no due, manual-review, missing-path, executable, or refused entries remain unless explicitly reported"
115
+ }
116
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "artshelf",
3
- "version": "0.4.1",
3
+ "version": "0.6.0",
4
4
  "description": "Tiny CLI for accountable temporary artifact retention.",
5
5
  "type": "module",
6
6
  "author": "Calvin",
@@ -28,6 +28,8 @@
28
28
  "files": [
29
29
  "dist/src",
30
30
  "docs",
31
+ "schemas",
32
+ "examples",
31
33
  "skills",
32
34
  "CHANGELOG.md",
33
35
  "LICENSE",