@neonwatty/limner 0.1.5 → 0.1.7
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/README.md +27 -1
- package/dist/commands/compare-image-reference.d.ts +3 -0
- package/dist/commands/compare-image-reference.js +16 -1
- package/dist/commands/compare-image-reference.js.map +1 -1
- package/dist/commands/compare-output.d.ts +2 -0
- package/dist/commands/compare-output.js +20 -0
- package/dist/commands/compare-output.js.map +1 -0
- package/dist/commands/compare.d.ts +3 -0
- package/dist/commands/compare.js +10 -19
- package/dist/commands/compare.js.map +1 -1
- package/dist/commands/ledger.d.ts +4 -1
- package/dist/commands/loop-actions.d.ts +22 -0
- package/dist/commands/loop-actions.js +54 -0
- package/dist/commands/loop-actions.js.map +1 -0
- package/dist/commands/loop-cli.js +96 -2
- package/dist/commands/loop-cli.js.map +1 -1
- package/dist/commands/loop-comparison-adapters.d.ts +3 -0
- package/dist/commands/loop-comparison-adapters.js +15 -1
- package/dist/commands/loop-comparison-adapters.js.map +1 -1
- package/dist/commands/loop-task.d.ts +17 -0
- package/dist/commands/loop-task.js +95 -0
- package/dist/commands/loop-task.js.map +1 -0
- package/dist/commands/loop.d.ts +3 -1
- package/dist/commands/loop.js +31 -14
- package/dist/commands/loop.js.map +1 -1
- package/dist/core/agent-comparison-pack.d.ts +13 -0
- package/dist/core/agent-comparison-pack.js +27 -21
- package/dist/core/agent-comparison-pack.js.map +1 -1
- package/dist/core/agent-comparison-response.d.ts +19 -0
- package/dist/core/agent-comparison-response.js +34 -0
- package/dist/core/agent-comparison-response.js.map +1 -0
- package/dist/core/agent-task-brief.d.ts +30 -0
- package/dist/core/agent-task-brief.js +158 -0
- package/dist/core/agent-task-brief.js.map +1 -0
- package/dist/core/comparison-artifacts.d.ts +12 -0
- package/dist/core/comparison-artifacts.js +50 -0
- package/dist/core/comparison-artifacts.js.map +1 -0
- package/dist/core/current-artifacts.d.ts +14 -0
- package/dist/core/current-artifacts.js +16 -0
- package/dist/core/current-artifacts.js.map +1 -0
- package/dist/core/ledger-agent-responses.d.ts +21 -0
- package/dist/core/ledger-agent-responses.js +13 -0
- package/dist/core/ledger-agent-responses.js.map +1 -0
- package/dist/core/ledger-db.js +28 -0
- package/dist/core/ledger-db.js.map +1 -1
- package/dist/core/ledger-events.js +46 -7
- package/dist/core/ledger-events.js.map +1 -1
- package/dist/core/ledger-markdown.d.ts +23 -4
- package/dist/core/ledger-markdown.js +133 -4
- package/dist/core/ledger-markdown.js.map +1 -1
- package/dist/core/ledger-queries.d.ts +5 -1
- package/dist/core/ledger-queries.js +14 -4
- package/dist/core/ledger-queries.js.map +1 -1
- package/dist/core/ledger-store.d.ts +11 -3
- package/dist/core/ledger-store.js +4 -0
- package/dist/core/ledger-store.js.map +1 -1
- package/dist/core/loop-rerun-command.d.ts +4 -0
- package/dist/core/loop-rerun-command.js +36 -0
- package/dist/core/loop-rerun-command.js.map +1 -0
- package/dist/core/runtime-context.d.ts +1 -0
- package/dist/core/runtime-context.js +18 -0
- package/dist/core/runtime-context.js.map +1 -0
- package/dist/schemas/ledger.d.ts +33 -0
- package/dist/schemas/ledger.js +13 -0
- package/dist/schemas/ledger.js.map +1 -1
- package/docs/agent-workflow.md +31 -1
- package/docs/superpowers/plans/2026-06-13-agent-response-sqlite.md +70 -0
- package/docs/superpowers/plans/2026-06-13-loop-action-ledger.md +257 -0
- package/package.json +1 -1
- package/skills/limner/SKILL.md +15 -4
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
# Loop Action Ledger Implementation Plan
|
|
2
|
+
|
|
3
|
+
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
|
|
4
|
+
|
|
5
|
+
**Goal:** Add first-class action logging so each Limner comparison can be followed by an explicit subagent handoff, polish action, skip, or completion record.
|
|
6
|
+
|
|
7
|
+
**Architecture:** Reuse `ledger_events` for v1. Action events store `actionId`, source comparison `runId`, executor, status, summary, files, and commit in `inputs_summary`; edited files are also artifact refs. `loop task` becomes the bridge from validated comparison evidence to an agent or subagent action.
|
|
8
|
+
|
|
9
|
+
**Tech Stack:** TypeScript, Commander, Zod, better-sqlite3, Vitest, Markdown docs, bundled Codex skill instructions.
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## File Structure
|
|
14
|
+
|
|
15
|
+
- Modify `src/schemas/ledger.ts`: action kind/status/executor schemas and 255-character summary validation.
|
|
16
|
+
- Modify `src/core/ledger-events.ts`: validate action event summaries.
|
|
17
|
+
- Modify `src/commands/loop.ts`: `recordLoopAction`, enriched `getLoopTask`, action event context.
|
|
18
|
+
- Modify `src/commands/loop-cli.ts`: `loop action start|complete|skip`, plus `loop task --executor`.
|
|
19
|
+
- Modify `src/core/agent-task-brief.ts`: source run ID, desired executor, action logging commands.
|
|
20
|
+
- Modify `src/core/ledger-markdown.ts`: action history section.
|
|
21
|
+
- Tests: `src/commands/loop.test.ts`, `src/core/agent-task-brief.test.ts`, `src/core/ledger-store.test.ts`, `src/commands/ledger.test.ts`.
|
|
22
|
+
- Docs: `README.md`, `docs/agent-workflow.md`, `skills/limner/SKILL.md`.
|
|
23
|
+
|
|
24
|
+
## Event Contract
|
|
25
|
+
|
|
26
|
+
Event types: `loop.action.started`, `loop.action.completed`, `loop.action.skipped`, `loop.action.failed`. `inputs_summary` shape:
|
|
27
|
+
|
|
28
|
+
```json
|
|
29
|
+
{
|
|
30
|
+
"actionId": "act_0123456789abcdef",
|
|
31
|
+
"kind": "polish",
|
|
32
|
+
"executor": "subagent",
|
|
33
|
+
"fromRunId": "2026-06-13T020201866Z-rkm2tn",
|
|
34
|
+
"summary": "Resize and reposition dashboard preview",
|
|
35
|
+
"files": ["targets/homepage-desktop/reference/styles.css"],
|
|
36
|
+
"commit": "abc1234"
|
|
37
|
+
}
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Task 1: Add Ledger Action Types
|
|
41
|
+
|
|
42
|
+
**Files:** `src/schemas/ledger.ts`, `src/core/ledger-events.ts`, `src/core/ledger-store.test.ts`
|
|
43
|
+
|
|
44
|
+
- [ ] **Step 1: Write the failing validation test**
|
|
45
|
+
|
|
46
|
+
Add to `src/core/ledger-store.test.ts`:
|
|
47
|
+
|
|
48
|
+
```ts
|
|
49
|
+
it('rejects overlong action summaries', () => {
|
|
50
|
+
const store = createLedgerStore(db);
|
|
51
|
+
const trajectory = store.startTrajectory(createInput());
|
|
52
|
+
expect(() => store.appendEvent({
|
|
53
|
+
trajectoryId: trajectory.trajectoryId,
|
|
54
|
+
iterationId: trajectory.activeIterationId ?? undefined,
|
|
55
|
+
eventType: 'loop.action.started',
|
|
56
|
+
actor: 'agent',
|
|
57
|
+
inputsSummary: JSON.stringify({ summary: 'x'.repeat(256) }),
|
|
58
|
+
})).toThrow(/255/);
|
|
59
|
+
});
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
- [ ] **Step 2: Run the failing test**
|
|
63
|
+
|
|
64
|
+
Run: `npm test -- src/core/ledger-store.test.ts`
|
|
65
|
+
|
|
66
|
+
Expected: FAIL because action summaries are not validated yet.
|
|
67
|
+
|
|
68
|
+
- [ ] **Step 3: Add schemas, validation, and verify**
|
|
69
|
+
|
|
70
|
+
Add to `src/schemas/ledger.ts`:
|
|
71
|
+
|
|
72
|
+
```ts
|
|
73
|
+
export const ledgerActionKindSchema = z.enum(['polish', 'handoff', 'manual-edit', 'verification', 'no-op']);
|
|
74
|
+
export const ledgerActionStatusSchema = z.enum(['started', 'completed', 'skipped', 'failed']);
|
|
75
|
+
export const ledgerActionExecutorSchema = z.enum(['subagent', 'agent', 'user', 'cli']);
|
|
76
|
+
export const ledgerActionSummarySchema = z.string().min(1).max(255);
|
|
77
|
+
export type LedgerActionKind = z.infer<typeof ledgerActionKindSchema>;
|
|
78
|
+
export type LedgerActionStatus = z.infer<typeof ledgerActionStatusSchema>;
|
|
79
|
+
export type LedgerActionExecutor = z.infer<typeof ledgerActionExecutorSchema>;
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
In `src/core/ledger-events.ts`, if `eventType` starts with `loop.action.`, parse `inputsSummary`, require a string `summary`, and validate it with `ledgerActionSummarySchema`.
|
|
83
|
+
|
|
84
|
+
Run: `npm test -- src/core/ledger-store.test.ts`
|
|
85
|
+
|
|
86
|
+
Expected: PASS.
|
|
87
|
+
|
|
88
|
+
## Task 2: Add Core Action Recording
|
|
89
|
+
|
|
90
|
+
**Files:** `src/commands/loop.ts`, `src/commands/loop.test.ts`
|
|
91
|
+
|
|
92
|
+
- [ ] **Step 1: Write failing tests**
|
|
93
|
+
|
|
94
|
+
Import `recordLoopAction` and add cases for `started`, `completed`, and `skipped`:
|
|
95
|
+
|
|
96
|
+
```ts
|
|
97
|
+
const action = recordLoopAction({
|
|
98
|
+
ledgerEnv,
|
|
99
|
+
trajectoryId: started.trajectoryId,
|
|
100
|
+
status: 'started',
|
|
101
|
+
kind: 'polish',
|
|
102
|
+
executor: 'subagent',
|
|
103
|
+
fromRunId: 'run_123',
|
|
104
|
+
summary: 'Resize dashboard preview',
|
|
105
|
+
});
|
|
106
|
+
expect(action.actionId).toMatch(/^act_/);
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
Assert exported events contain `loop.action.started`, `loop.action.completed`, and `loop.action.skipped`, and that parsed `inputsSummary` includes `actionId`, `fromRunId`, `executor`, `summary`, `files`, and `commit` when supplied.
|
|
110
|
+
|
|
111
|
+
- [ ] **Step 2: Run the failing test**
|
|
112
|
+
|
|
113
|
+
Run: `npm test -- src/commands/loop.test.ts`
|
|
114
|
+
|
|
115
|
+
Expected: FAIL because `recordLoopAction` does not exist.
|
|
116
|
+
|
|
117
|
+
- [ ] **Step 3: Implement `recordLoopAction` and verify**
|
|
118
|
+
|
|
119
|
+
In `src/commands/loop.ts`, add `LoopActionInput` with `status`, `kind`, `executor`, `summary`, optional `actionId`, `fromRunId`, `files`, `commit`, and the existing trajectory selector fields. Use `createLedgerId('act')` when no action ID is supplied. Append event type `loop.action.${status}`, actor `agent` for `subagent` or `agent`, actor `user` for `user`, and actor `cli` for `cli`. Return `{ actionId }`.
|
|
120
|
+
|
|
121
|
+
Run: `npm test -- src/commands/loop.test.ts`
|
|
122
|
+
|
|
123
|
+
Expected: PASS.
|
|
124
|
+
|
|
125
|
+
## Task 3: Add CLI Commands
|
|
126
|
+
|
|
127
|
+
**Files:** `src/commands/loop-cli.ts`, `src/commands/loop.test.ts`
|
|
128
|
+
|
|
129
|
+
- [ ] **Step 1: Add command normalization coverage**
|
|
130
|
+
|
|
131
|
+
Add a test that passes files as `['src/app/page.tsx', 'src/app/globals.css']` to `recordLoopAction` and asserts the exported action event stores both files and creates `edited-file` artifact refs.
|
|
132
|
+
|
|
133
|
+
- [ ] **Step 2: Implement `loop action`**
|
|
134
|
+
|
|
135
|
+
Add Commander subcommands:
|
|
136
|
+
|
|
137
|
+
```bash
|
|
138
|
+
limner loop action start --trajectory <id> --from-run <run-id> --kind polish --executor subagent --summary "Resize dashboard preview"
|
|
139
|
+
limner loop action complete --trajectory <id> --action <action-id> --summary "Adjusted preview sizing" --files "src/app/page.tsx,src/app/globals.css" --commit abc1234
|
|
140
|
+
limner loop action skip --trajectory <id> --from-run <run-id> --summary "Smoke test only; no polish intended"
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
Each command prints `Action: <action-id>`.
|
|
144
|
+
|
|
145
|
+
- [ ] **Step 3: Verify CLI and tests**
|
|
146
|
+
|
|
147
|
+
Run: `npm run dev -- loop action start --help`
|
|
148
|
+
|
|
149
|
+
Expected: help lists `--trajectory`, `--from-run`, `--kind`, `--executor`, and `--summary`.
|
|
150
|
+
|
|
151
|
+
Run: `npm test -- src/commands/loop.test.ts`
|
|
152
|
+
|
|
153
|
+
Expected: PASS.
|
|
154
|
+
|
|
155
|
+
## Task 4: Make Task Briefs Subagent-Ready
|
|
156
|
+
|
|
157
|
+
**Files:**
|
|
158
|
+
- Modify: `src/core/agent-task-brief.ts`
|
|
159
|
+
- Modify: `src/commands/loop.ts`
|
|
160
|
+
- Modify: `src/commands/loop-cli.ts`
|
|
161
|
+
- Test: `src/core/agent-task-brief.test.ts`
|
|
162
|
+
- Test: `src/commands/loop.test.ts`
|
|
163
|
+
|
|
164
|
+
- [ ] **Step 1: Write failing assertions**
|
|
165
|
+
|
|
166
|
+
Update tests to expect JSON fields `sourceRunId`, `desiredExecutor`, `actionStartCommand`, and `actionCompleteCommandExample`. Expect Markdown to include `## Action Logging`, `limner loop action start`, `limner loop action complete`, and `limner loop action skip`.
|
|
167
|
+
|
|
168
|
+
- [ ] **Step 2: Enrich task lookup and command**
|
|
169
|
+
|
|
170
|
+
Change `latestValidatedComparison` to return `{ summaryPath, inputsSummary, runId }`. Add `--executor <executor>` to `loop task`, default `subagent`. When appending `loop.task.viewed`, include `inputsSummary: JSON.stringify({ sourceRunId, desiredExecutor })`.
|
|
171
|
+
|
|
172
|
+
- [ ] **Step 3: Update task output and verify**
|
|
173
|
+
|
|
174
|
+
Add action commands to `buildAgentTaskBrief` JSON and Markdown. The start command must include `--trajectory`, `--from-run`, `--kind polish`, `--executor`, and `--summary`. The complete command example must include `--trajectory`, `--action <action-id>`, `--summary`, and `--files`.
|
|
175
|
+
|
|
176
|
+
Run: `npm test -- src/core/agent-task-brief.test.ts src/commands/loop.test.ts`
|
|
177
|
+
|
|
178
|
+
Expected: PASS.
|
|
179
|
+
|
|
180
|
+
## Task 5: Show Actions in Ledger Exports
|
|
181
|
+
|
|
182
|
+
**Files:**
|
|
183
|
+
- Modify: `src/core/ledger-markdown.ts`
|
|
184
|
+
- Test: `src/commands/ledger.test.ts`
|
|
185
|
+
|
|
186
|
+
- [ ] **Step 1: Write failing Markdown export test**
|
|
187
|
+
|
|
188
|
+
Create a fixture with one `loop.action.completed` event. Assert the markdown export contains:
|
|
189
|
+
|
|
190
|
+
```md
|
|
191
|
+
## Action History
|
|
192
|
+
- act_
|
|
193
|
+
- status: completed
|
|
194
|
+
- executor: subagent
|
|
195
|
+
- from run: run_123
|
|
196
|
+
- summary: Resize dashboard preview
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
- [ ] **Step 2: Implement action formatting and verify**
|
|
200
|
+
|
|
201
|
+
Parse `loop.action.*` events from `exported.events`, read `inputsSummary`, and render `## Action History` before artifact sections. If no actions exist, render `- None recorded`.
|
|
202
|
+
|
|
203
|
+
Run: `npm test -- src/commands/ledger.test.ts`
|
|
204
|
+
|
|
205
|
+
Expected: PASS.
|
|
206
|
+
|
|
207
|
+
## Task 6: Document the Agent Workflow
|
|
208
|
+
|
|
209
|
+
**Files:**
|
|
210
|
+
- Modify: `README.md`
|
|
211
|
+
- Modify: `docs/agent-workflow.md`
|
|
212
|
+
- Modify: `skills/limner/SKILL.md`
|
|
213
|
+
|
|
214
|
+
- [ ] **Step 1: Document the loop**
|
|
215
|
+
|
|
216
|
+
Document:
|
|
217
|
+
|
|
218
|
+
```text
|
|
219
|
+
loop compare -> loop task --executor subagent -> loop action start -> edit -> loop action complete -> loop compare
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
Also document `loop action skip` for comparison-only smoke runs.
|
|
223
|
+
|
|
224
|
+
- [ ] **Step 2: Update skill instructions and verify**
|
|
225
|
+
|
|
226
|
+
In `skills/limner/SKILL.md`, instruct agents to prefer `limner loop task --executor subagent`, record `loop action start` before edits, record `loop action complete` after edits, record `loop action skip` when no edit is intended, and keep `--summary` under 255 characters.
|
|
227
|
+
|
|
228
|
+
Run: `rg "loop action|--executor subagent|Action Logging" README.md docs/agent-workflow.md skills/limner/SKILL.md`
|
|
229
|
+
|
|
230
|
+
Expected: each file has at least one matching workflow reference.
|
|
231
|
+
|
|
232
|
+
## Task 7: Final Verification
|
|
233
|
+
|
|
234
|
+
**Files:**
|
|
235
|
+
- All files above
|
|
236
|
+
|
|
237
|
+
- [ ] **Step 1: Run the aggregate gate**
|
|
238
|
+
|
|
239
|
+
Run: `npm run check`
|
|
240
|
+
|
|
241
|
+
Expected: lint, typecheck, Vitest, build, Knip, and file-size guard all pass.
|
|
242
|
+
|
|
243
|
+
- [ ] **Step 2: Run a local smoke flow**
|
|
244
|
+
|
|
245
|
+
Run:
|
|
246
|
+
|
|
247
|
+
```bash
|
|
248
|
+
npm run dev -- loop action start --trajectory <existing-test-trajectory> --from-run <validated-run-id> --kind polish --executor subagent --summary "Smoke action start"
|
|
249
|
+
npm run dev -- loop action skip --trajectory <existing-test-trajectory> --from-run <validated-run-id> --summary "Smoke test only"
|
|
250
|
+
npm run dev -- ledger export <existing-test-trajectory> --format markdown
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
Expected: export contains `## Action History` with both action records.
|
|
254
|
+
|
|
255
|
+
- [ ] **Step 3: PR handoff notes**
|
|
256
|
+
|
|
257
|
+
Include the top risks: wrong trajectory, executor intent recorded but external orchestrator did not use a subagent, and action completed without follow-up comparison. Include commands run, smoke trajectory ID, generated ledger excerpt, and the residual risk that Limner records action claims but cannot independently prove who edited files.
|
package/package.json
CHANGED
package/skills/limner/SKILL.md
CHANGED
|
@@ -19,11 +19,22 @@ Use `limner loop` for Ralph Loop-style polishing across one or more trajectories
|
|
|
19
19
|
2. Compare with `limner loop compare --trajectory <trajectory-id>`.
|
|
20
20
|
3. Read the generated comparison prompt and response target.
|
|
21
21
|
4. Write or validate the agent response.
|
|
22
|
-
5.
|
|
23
|
-
6.
|
|
24
|
-
7.
|
|
22
|
+
5. After validation, prefer `limner loop task --trajectory <trajectory-id> --executor subagent`.
|
|
23
|
+
6. Record `limner loop action start --trajectory <trajectory-id> --from-run <run-id> --kind polish --executor subagent --summary "<short edit intent>"` before edits.
|
|
24
|
+
7. Make one scoped edit from the task brief.
|
|
25
|
+
8. Record `limner loop action complete --trajectory <trajectory-id> --action <action-id> --executor subagent --summary "<what changed>" --files "<paths>"` after edits, then rerun `limner loop compare --trajectory <trajectory-id>`.
|
|
26
|
+
9. For comparison-only smoke runs with no intended edit, record `limner loop action skip --trajectory <trajectory-id> --from-run <run-id> --summary "Comparison smoke only; no edit intended"`.
|
|
27
|
+
10. Check state with `limner loop status --trajectory <trajectory-id>`.
|
|
28
|
+
11. Move to the next scoped fix with `limner loop next --trajectory <trajectory-id>`.
|
|
29
|
+
12. Close with `limner loop close --trajectory <trajectory-id>`.
|
|
25
30
|
|
|
26
|
-
Every meaningful loop interaction writes a ledger event. Use `--feedback "<short note>"` for a 255-character `agentFeedback` note about improving the current process. Use `limner ledger export <trajectory-id> --format markdown` to hand a compact trajectory history to another agent.
|
|
31
|
+
The intended edit loop is `loop compare -> loop task --executor subagent -> loop action start -> edit -> loop action complete -> loop compare`. Every meaningful loop interaction writes a ledger event. Agent responses are stored in local SQLite with the full JSON body, hash, validation status, and freshness, so cached reuse is visible. Keep every action `--summary` under 255 characters. Use `--feedback "<short note>"` for a 255-character `agentFeedback` note about improving the current process. Use `limner ledger export <trajectory-id> --format markdown` to hand a compact trajectory history to another agent.
|
|
32
|
+
|
|
33
|
+
Use `limner loop task --trajectory <trajectory-id> --executor subagent --format json` when another tool needs machine-readable task data.
|
|
34
|
+
|
|
35
|
+
Limner records executor intent and action claims; it cannot prove an external orchestrator actually used a subagent.
|
|
36
|
+
|
|
37
|
+
Agents can discover the current command surface with `limner --help`, `limner loop --help`, `limner loop task --help`, and `limner ledger --help`.
|
|
27
38
|
|
|
28
39
|
## Image To Reference
|
|
29
40
|
|