@boopkit/cli 0.8.0 → 0.8.1
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 +8 -6
- package/dist/capability-catalog.json +10 -3
- package/dist/capability-versions.json +11 -10
- package/dist/cli.js +0 -0
- package/dist/commands/add.js +35 -7
- package/dist/commands/adopt.js +1 -1
- package/dist/commands/loop-merge.d.ts +11 -0
- package/dist/commands/loop-merge.js +135 -14
- package/dist/commands/loop.js +1 -1
- package/dist/commands/migrate-skill-edits.js +2 -2
- package/dist/commands/status.d.ts +10 -0
- package/dist/commands/status.js +27 -2
- package/dist/commands/update.js +157 -21
- package/dist/lib/capability.js +4 -1
- package/dist/lib/execute.js +19 -2
- package/dist/lib/install-layout.d.ts +5 -0
- package/dist/lib/install-layout.js +8 -0
- package/dist/lib/manifest.d.ts +1 -1
- package/dist/lib/moves.d.ts +88 -0
- package/dist/lib/moves.js +381 -0
- package/dist/lib/original-text.d.ts +2 -0
- package/dist/lib/original-text.js +15 -7
- package/dist/lib/preflight.d.ts +14 -1
- package/dist/lib/preflight.js +53 -17
- package/dist/lib/project.d.ts +17 -0
- package/dist/lib/project.js +26 -0
- package/dist/lib/scaffold.d.ts +12 -1
- package/dist/lib/scaffold.js +43 -4
- package/dist/lib/update.d.ts +36 -2
- package/dist/lib/update.js +82 -4
- package/docs/init.md +22 -0
- package/docs/loop.md +11 -3
- package/docs/skills.md +17 -13
- package/package.json +1 -1
- package/profiles/base/profile.md +13 -10
- package/profiles/development/profile.md +10 -8
- package/profiles/web-app/profile.md +6 -4
- package/profiles/web-app/reference/message-queue-patterns.ref.md +8 -13
- package/src/templates/kernel/tests/app.test.ts.hbs +17 -0
|
@@ -9,6 +9,7 @@ defaultCapabilities:
|
|
|
9
9
|
- database
|
|
10
10
|
# Development
|
|
11
11
|
- coding
|
|
12
|
+
- typescript
|
|
12
13
|
- testing
|
|
13
14
|
- project-mgmt
|
|
14
15
|
- product-design
|
|
@@ -86,11 +87,12 @@ The `web-app` profile ships all of the following capabilities by default:
|
|
|
86
87
|
- **services** — Service layer scaffolding, auto-discovery, and design skills
|
|
87
88
|
- **database** — PostgreSQL with Prisma ORM, migrations, and seeding
|
|
88
89
|
|
|
89
|
-
**Development capabilities** —
|
|
90
|
+
**Development capabilities** — skill bundles that guide agent behavior, and the toolchain they assume:
|
|
90
91
|
- **coding** — Development conventions and code style skills
|
|
91
|
-
- **
|
|
92
|
-
- **
|
|
93
|
-
- **
|
|
92
|
+
- **typescript** — The TypeScript toolchain: Jest with ts-jest, `tsconfig.test.json`, and the `test` and `typecheck` scripts
|
|
93
|
+
- **testing** — Testing principles and the TDD-Lite workflow skills
|
|
94
|
+
- **project-mgmt** — Beads issue tracking, planning, issue sweeps and stray disposition
|
|
95
|
+
- **product-design** — Feature requirements, design thinking and knowledge backfill skills
|
|
94
96
|
- **skills** — Skill authoring and maintenance
|
|
95
97
|
|
|
96
98
|
**Demo:**
|
|
@@ -26,28 +26,23 @@ await MessageQueueService.publish('batch-ready', [message1, message2]);
|
|
|
26
26
|
- **Error recovery**: If `publish()` catches an error (e.g., channel closed), it resets connection state and returns `false` — the next call will reconnect
|
|
27
27
|
- **Shutdown**: The publish connection is tracked and closed by `close()` alongside the listener connection
|
|
28
28
|
|
|
29
|
-
### Publishing to a queue that does not exist
|
|
29
|
+
### Publishing to a queue that does not exist yet
|
|
30
30
|
|
|
31
|
-
`publish()`
|
|
32
|
-
|
|
33
|
-
so a publish to a name that no consumer has ever listened on returns `true` and the message is lost.
|
|
31
|
+
`publish()` declares the queue's topology (main, `.retry` and `.failed` queues and their exchanges) before its first publish to it on a connection, exactly as `listen()` does,
|
|
32
|
+
so a message published before the consumer has ever run is kept until the consumer attaches.
|
|
34
33
|
|
|
35
|
-
|
|
36
|
-
when the
|
|
37
|
-
|
|
34
|
+
- Each queue is declared once per publish connection; concurrent first publishes share the declaration, and a queue a consumer in the same process already declared with the same arguments is not declared again
|
|
35
|
+
- The declaration runs on a short-lived channel, so a refused one (`PRECONDITION_FAILED`, when the arguments differ from the existing queue's) fails that publish alone: it is logged with the queue's name and `publish()` returns `false`
|
|
36
|
+
- Pass the consumer's `queueArguments` in the third argument whenever the consumer declares any:
|
|
38
37
|
|
|
39
38
|
```typescript
|
|
40
|
-
const queued = await MessageQueueService.publish('batch-ready', message, { targetPrefix,
|
|
39
|
+
const queued = await MessageQueueService.publish('batch-ready', message, { targetPrefix, queueArguments: BATCH_QUEUE_ARGUMENTS });
|
|
41
40
|
if (!queued) {
|
|
42
41
|
// Not queued anywhere: record or report it.
|
|
43
42
|
}
|
|
44
43
|
```
|
|
45
44
|
|
|
46
|
-
-
|
|
47
|
-
- `publish()` then logs `publish to "<queue>" was returned by the broker: no queue has that name` and returns `false`
|
|
48
|
-
- The connection state is **not** reset in this case — the connection is healthy, and the next `publish()` reuses it
|
|
49
|
-
- A queue that exists but has no consumer running still takes the message; the option reports a missing queue, not a missing worker
|
|
50
|
-
- Without the option, `publish()` is unchanged
|
|
45
|
+
- `{ mandatory: true }` still makes the broker return a message no queue took; after the declaration that means a real fault, such as a queue deleted by hand, and `publish()` returns `false` without resetting the connection
|
|
51
46
|
|
|
52
47
|
### Why persistent (not per-call)
|
|
53
48
|
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import app from '../src/app';
|
|
2
|
+
|
|
3
|
+
describe('app', () => {
|
|
4
|
+
it('exports a valid Express application', () => {
|
|
5
|
+
expect(app).toBeDefined();
|
|
6
|
+
expect(typeof app.get).toBe('function');
|
|
7
|
+
expect(typeof app.post).toBe('function');
|
|
8
|
+
expect(typeof app.use).toBe('function');
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
it('has JSON and URL-encoded body parsing enabled', () => {
|
|
12
|
+
const stack = (app as any).router?.stack ?? (app as any)._router?.stack ?? [];
|
|
13
|
+
const layerNames = stack.map((layer: any) => layer.name);
|
|
14
|
+
expect(layerNames).toContain('jsonParser');
|
|
15
|
+
expect(layerNames).toContain('urlencodedParser');
|
|
16
|
+
});
|
|
17
|
+
});
|