@massu/core 0.4.0 → 0.4.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/commands/_shared-preamble.md +10 -0
- package/commands/massu-batch.md +327 -0
- package/commands/massu-bearings.md +204 -0
- package/commands/massu-ci-fix.md +148 -0
- package/commands/massu-gap-enhancement-analyzer.md +480 -0
- package/commands/massu-hooks.md +111 -0
- package/commands/massu-incident.md +162 -0
- package/commands/massu-plan-audit.md +64 -0
- package/commands/massu-recap.md +164 -0
- package/commands/massu-scaffold-hook.md +96 -0
- package/commands/massu-scaffold-page.md +108 -0
- package/commands/massu-scaffold-router.md +125 -0
- package/commands/massu-squirrels.md +101 -0
- package/dist/cli.js +0 -1
- package/package.json +2 -2
- package/src/cli.ts +0 -1
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: massu-scaffold-router
|
|
3
|
+
description: "When user wants to create a new tRPC router, API endpoint, or backend procedure — scaffolds router file, registers in root.ts, adds Zod schemas"
|
|
4
|
+
allowed-tools: Bash(*), Read(*), Write(*), Edit(*), Grep(*), Glob(*)
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Scaffold New tRPC Router
|
|
8
|
+
|
|
9
|
+
> **Shared rules apply.** Read `.claude/commands/_shared-preamble.md` before proceeding.
|
|
10
|
+
|
|
11
|
+
Creates a complete tRPC router following all project database and auth patterns.
|
|
12
|
+
|
|
13
|
+
## What Gets Created
|
|
14
|
+
|
|
15
|
+
| File | Purpose |
|
|
16
|
+
|------|---------|
|
|
17
|
+
| `src/server/api/routers/[name].ts` | Router with procedures |
|
|
18
|
+
| Registration in `src/server/api/root.ts` | Import + add to appRouter |
|
|
19
|
+
|
|
20
|
+
## Template
|
|
21
|
+
|
|
22
|
+
```typescript
|
|
23
|
+
import { z } from 'zod';
|
|
24
|
+
import { createTRPCRouter, protectedProcedure } from '@/server/api/trpc';
|
|
25
|
+
|
|
26
|
+
export const myEntityRouter = createTRPCRouter({
|
|
27
|
+
getAll: protectedProcedure
|
|
28
|
+
.query(async ({ ctx }) => {
|
|
29
|
+
const items = await ctx.db.my_table.findMany({
|
|
30
|
+
orderBy: { created_at: 'desc' },
|
|
31
|
+
});
|
|
32
|
+
return items;
|
|
33
|
+
}),
|
|
34
|
+
|
|
35
|
+
getById: protectedProcedure
|
|
36
|
+
.input(z.object({ id: z.string().uuid() }))
|
|
37
|
+
.query(async ({ ctx, input }) => {
|
|
38
|
+
const item = await ctx.db.my_table.findUnique({
|
|
39
|
+
where: { id: input.id },
|
|
40
|
+
});
|
|
41
|
+
if (!item) throw new Error('Not found');
|
|
42
|
+
return item;
|
|
43
|
+
}),
|
|
44
|
+
|
|
45
|
+
create: protectedProcedure
|
|
46
|
+
.input(z.object({
|
|
47
|
+
name: z.string().min(1),
|
|
48
|
+
// Add fields here
|
|
49
|
+
}))
|
|
50
|
+
.mutation(async ({ ctx, input }) => {
|
|
51
|
+
return ctx.db.my_table.create({
|
|
52
|
+
data: {
|
|
53
|
+
...input,
|
|
54
|
+
created_by: ctx.session.user.id,
|
|
55
|
+
},
|
|
56
|
+
});
|
|
57
|
+
}),
|
|
58
|
+
|
|
59
|
+
update: protectedProcedure
|
|
60
|
+
.input(z.object({
|
|
61
|
+
id: z.string().uuid(),
|
|
62
|
+
name: z.string().min(1).optional(),
|
|
63
|
+
}))
|
|
64
|
+
.mutation(async ({ ctx, input }) => {
|
|
65
|
+
const { id, ...data } = input;
|
|
66
|
+
return ctx.db.my_table.update({
|
|
67
|
+
where: { id },
|
|
68
|
+
data,
|
|
69
|
+
});
|
|
70
|
+
}),
|
|
71
|
+
});
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
## 3-Step Query Pattern (for relations)
|
|
75
|
+
|
|
76
|
+
```typescript
|
|
77
|
+
// Step 1: Base query
|
|
78
|
+
const items = await ctx.db.my_table.findMany({ where: { status: 'active' } });
|
|
79
|
+
|
|
80
|
+
// Step 2: Relation query with IN
|
|
81
|
+
const relatedIds = items.map(i => i.related_id).filter(Boolean);
|
|
82
|
+
const related = relatedIds.length > 0
|
|
83
|
+
? await ctx.db.related_table.findMany({ where: { id: { in: relatedIds } } })
|
|
84
|
+
: [];
|
|
85
|
+
|
|
86
|
+
// Step 3: Map combine
|
|
87
|
+
const relatedMap = new Map(related.map(r => [r.id, r]));
|
|
88
|
+
return items.map(item => ({
|
|
89
|
+
...item,
|
|
90
|
+
related: item.related_id ? relatedMap.get(item.related_id) : null,
|
|
91
|
+
}));
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
## Registration in root.ts
|
|
95
|
+
|
|
96
|
+
```typescript
|
|
97
|
+
import { myEntityRouter } from './routers/my-entity';
|
|
98
|
+
|
|
99
|
+
export const appRouter = createTRPCRouter({
|
|
100
|
+
// ... existing routers
|
|
101
|
+
myEntity: myEntityRouter,
|
|
102
|
+
});
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
## Gotchas
|
|
106
|
+
|
|
107
|
+
- **ctx.db NOT ctx.prisma** — hybrid client requires ctx.db
|
|
108
|
+
- **protectedProcedure for ALL mutations** — never publicProcedure
|
|
109
|
+
- **No `include:`** — hybrid DB ignores include statements; use 3-step query
|
|
110
|
+
- **user_profiles NOT users** — `ctx.db.user_profiles` (auth.users not exposed)
|
|
111
|
+
- **BigInt**: convert to `Number()` on return, NEVER use `BigInt()` in INSERT
|
|
112
|
+
- **New tables**: add to `src/lib/db.ts` DatabaseClient BEFORE using in routers
|
|
113
|
+
- **Split-commit**: NEVER add import to root.ts before router file exists
|
|
114
|
+
|
|
115
|
+
## Process
|
|
116
|
+
|
|
117
|
+
1. Ask user: What entity? What operations (CRUD, custom)?
|
|
118
|
+
2. Run VR-SCHEMA-PRE to verify table columns exist
|
|
119
|
+
3. Create router file with proper patterns
|
|
120
|
+
4. Register in root.ts
|
|
121
|
+
5. Run `npx tsc --noEmit` to verify types
|
|
122
|
+
|
|
123
|
+
## START NOW
|
|
124
|
+
|
|
125
|
+
Ask the user what entity/table the router is for and what procedures it needs.
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: massu-squirrels
|
|
3
|
+
description: "When user has a tangential idea mid-task that should be parked — 'squirrel this', 'park this idea', 'remind me later about'"
|
|
4
|
+
allowed-tools: Bash(*), Read(*), Write(*), Edit(*), Grep(*), Glob(*)
|
|
5
|
+
---
|
|
6
|
+
name: massu-squirrels
|
|
7
|
+
|
|
8
|
+
# Massu Squirrels: Idea Parking Lot Manager
|
|
9
|
+
|
|
10
|
+
> **Shared rules apply.** Read `.claude/commands/_shared-preamble.md` before proceeding.
|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
## Purpose
|
|
15
|
+
|
|
16
|
+
Manage `.claude/session-state/squirrels.md` — a parking lot for stray ideas that come up mid-session. These are thoughts worth capturing but not worth derailing the current task for.
|
|
17
|
+
|
|
18
|
+
**This is NOT a backlog.** It's a scratchpad. Ideas here are unvetted, unscoped, and may be irrelevant. The value is in not losing them.
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## ARGUMENTS
|
|
23
|
+
|
|
24
|
+
```
|
|
25
|
+
/massu-squirrels # Show current squirrels list
|
|
26
|
+
/massu-squirrels add [idea] # Park a new idea
|
|
27
|
+
/massu-squirrels review # Review all ideas, grouped by age
|
|
28
|
+
/massu-squirrels promote [N] # Promote idea #N to a plan or task
|
|
29
|
+
/massu-squirrels clean # Remove stale/irrelevant ideas
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
**Arguments from command**: `{{ARGUMENTS}}`
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
## Actions
|
|
37
|
+
|
|
38
|
+
### No argument / `review` — Show current squirrels
|
|
39
|
+
|
|
40
|
+
1. Read `.claude/session-state/squirrels.md`
|
|
41
|
+
2. If empty (no ideas below the divider): say "No parked squirrels." and stop
|
|
42
|
+
3. If ideas exist, display them grouped by age:
|
|
43
|
+
- **Fresh** (today or yesterday)
|
|
44
|
+
- **This week** (2-7 days old)
|
|
45
|
+
- **Aging** (> 7 days — consider promoting or cleaning)
|
|
46
|
+
4. Show count: "N squirrels parked (X fresh, Y aging)"
|
|
47
|
+
|
|
48
|
+
### `add` — Park a new idea
|
|
49
|
+
|
|
50
|
+
1. Determine the idea from `{{ARGUMENTS}}` (everything after "add")
|
|
51
|
+
2. Determine current context from `session-state/CURRENT.md` (what task is active)
|
|
52
|
+
3. Append to `.claude/session-state/squirrels.md`:
|
|
53
|
+
```
|
|
54
|
+
- YYYY-MM-DD: [idea] (context: [current task summary])
|
|
55
|
+
```
|
|
56
|
+
4. Confirm: "Parked: [idea]"
|
|
57
|
+
5. Return to current work — do NOT expand on the idea or start working on it
|
|
58
|
+
|
|
59
|
+
### `promote [N]` — Promote an idea
|
|
60
|
+
|
|
61
|
+
1. Read squirrels.md, number the ideas (1-based, top to bottom)
|
|
62
|
+
2. Display idea #N and ask: "Promote this to a plan, a task, or a session-state item?"
|
|
63
|
+
3. Based on response:
|
|
64
|
+
- **Plan**: Create a plan stub in `.claude/plans/`
|
|
65
|
+
- **Task**: Add to CURRENT.md as an open item
|
|
66
|
+
- **Session-state**: Add to CURRENT.md as context
|
|
67
|
+
4. Remove the idea from squirrels.md
|
|
68
|
+
5. Confirm: "Promoted squirrel #N to [destination]"
|
|
69
|
+
|
|
70
|
+
### `clean` — Clean stale ideas
|
|
71
|
+
|
|
72
|
+
1. Read squirrels.md, display ALL ideas with numbers
|
|
73
|
+
2. Ask user which to remove (by number, or "all aging" for ideas > 7 days old)
|
|
74
|
+
3. Remove selected ideas
|
|
75
|
+
4. Confirm: "Cleaned N squirrels. M remaining."
|
|
76
|
+
|
|
77
|
+
---
|
|
78
|
+
|
|
79
|
+
## Integration Points
|
|
80
|
+
|
|
81
|
+
- `/massu-bearings` reads squirrels.md and surfaces the count + list
|
|
82
|
+
- `/massu-recap` surfaces any squirrels added during the session
|
|
83
|
+
- Squirrels are NOT automatically promoted — they require explicit user action
|
|
84
|
+
- Squirrels are NOT persisted to memory/ — they are ephemeral by design
|
|
85
|
+
|
|
86
|
+
---
|
|
87
|
+
|
|
88
|
+
## Edge Cases
|
|
89
|
+
|
|
90
|
+
- If `squirrels.md` doesn't exist: create it with the standard header format
|
|
91
|
+
- If `CURRENT.md` doesn't exist when adding context: use "no active task" as context
|
|
92
|
+
- If promote target #N doesn't exist: show the list and ask again
|
|
93
|
+
|
|
94
|
+
---
|
|
95
|
+
|
|
96
|
+
## START NOW
|
|
97
|
+
|
|
98
|
+
1. Parse `{{ARGUMENTS}}` to determine action (show/add/review/promote/clean)
|
|
99
|
+
2. Read `.claude/session-state/squirrels.md`
|
|
100
|
+
3. Execute the appropriate action
|
|
101
|
+
4. Return to current work without expanding on the idea
|
package/dist/cli.js
CHANGED
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@massu/core",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.2",
|
|
4
4
|
"type": "module",
|
|
5
|
-
"description": "AI Engineering Governance MCP Server - Session memory, knowledge system, feature registry, code intelligence, rule enforcement, tiered tooling (12 free / 72 total),
|
|
5
|
+
"description": "AI Engineering Governance MCP Server - Session memory, knowledge system, feature registry, code intelligence, rule enforcement, tiered tooling (12 free / 72 total), 43 workflow commands",
|
|
6
6
|
"main": "src/server.ts",
|
|
7
7
|
"bin": {
|
|
8
8
|
"massu": "./dist/cli.js"
|
package/src/cli.ts
CHANGED