compound-workflow 1.8.0 → 1.9.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 +62 -68
- package/package.json +2 -8
- package/scripts/check-pack-readme.mjs +1 -16
- package/scripts/check-workflow-contracts.mjs +34 -44
- package/scripts/install-cli.mjs +273 -555
- package/src/AGENTS.md +59 -192
- package/src/{.agents/agents → agents}/research/best-practices-researcher.md +2 -2
- package/src/{.agents/commands → commands}/assess.md +4 -4
- package/src/commands/install.md +43 -0
- package/src/{.agents/commands → commands}/metrics.md +1 -1
- package/src/{.agents/commands → commands}/test-browser.md +8 -8
- package/src/commands/workflow-agents.md +101 -0
- package/src/{.agents/commands → commands}/workflow-brainstorm.md +5 -5
- package/src/{.agents/commands → commands}/workflow-compound.md +1 -1
- package/src/{.agents/commands → commands}/workflow-plan.md +62 -85
- package/src/commands/workflow-work.md +839 -0
- package/src/{.agents/references → references}/README.md +1 -1
- package/src/{.agents/skills → skills}/capture-skill/SKILL.md +1 -1
- package/src/{.agents/skills → skills}/compound-docs/SKILL.md +6 -6
- package/src/{.agents/skills → skills}/compound-docs/references/yaml-schema.md +2 -2
- package/src/skills/setup-agents/SKILL.md +247 -0
- package/src/skills/standards/SKILL.md +79 -0
- package/src/skills/standards/references/architecture.md +228 -0
- package/src/skills/standards/references/code-quality.md +192 -0
- package/src/skills/standards/references/presentation.md +515 -0
- package/src/skills/standards/references/services.md +172 -0
- package/src/skills/standards/references/state-management.md +936 -0
- package/.claude-plugin/plugin.json +0 -7
- package/.cursor-plugin/plugin.json +0 -20
- package/.cursor-plugin/registration.json +0 -5
- package/scripts/check-version-parity.mjs +0 -36
- package/scripts/generate-platform-artifacts.mjs +0 -230
- package/src/.agents/commands/install.md +0 -51
- package/src/.agents/commands/workflow-work.md +0 -690
- package/src/.agents/registry.json +0 -48
- package/src/.agents/scripts/self-check.mjs +0 -227
- package/src/.agents/scripts/sync-opencode.mjs +0 -362
- package/src/.agents/skills/presentation-composability/SKILL.md +0 -72
- package/src/.agents/skills/react-ddd-mvc-frontend/SKILL.md +0 -51
- package/src/.agents/skills/react-ddd-mvc-frontend/references/feature-structure.md +0 -25
- package/src/.agents/skills/react-ddd-mvc-frontend/references/implementation-principles.md +0 -21
- package/src/.agents/skills/react-ddd-mvc-frontend/references/responsibility-gates.md +0 -41
- package/src/.agents/skills/react-ddd-mvc-frontend/references/source-map.md +0 -11
- package/src/.agents/skills/standards/SKILL.md +0 -747
- package/src/.agents/skills/xstate-actor-orchestration/SKILL.md +0 -197
- package/src/.agents/skills/xstate-actor-orchestration/agents/openai.yaml +0 -4
- package/src/.agents/skills/xstate-actor-orchestration/assets/statecharts/.gitkeep +0 -0
- package/src/.agents/skills/xstate-actor-orchestration/references/actor-system-patterns.md +0 -71
- package/src/.agents/skills/xstate-actor-orchestration/references/event-contracts.md +0 -73
- package/src/.agents/skills/xstate-actor-orchestration/references/functional-domain-patterns.md +0 -53
- package/src/.agents/skills/xstate-actor-orchestration/references/machine-structure-and-tags.md +0 -36
- package/src/.agents/skills/xstate-actor-orchestration/references/react-container-pattern.md +0 -45
- package/src/.agents/skills/xstate-actor-orchestration/references/reliability-observability.md +0 -39
- package/src/.agents/skills/xstate-actor-orchestration/references/skill-validation.md +0 -33
- package/src/.agents/skills/xstate-actor-orchestration/references/source-map.md +0 -44
- package/src/.agents/skills/xstate-actor-orchestration/references/statechart-review-and-signoff.md +0 -59
- package/src/.agents/skills/xstate-actor-orchestration/references/testing-strategy.md +0 -35
- package/src/.agents/skills/xstate-actor-orchestration/scripts/create-statechart-artifact.sh +0 -71
- package/src/.agents/skills/xstate-actor-orchestration/scripts/validate-skill.sh +0 -138
- package/src/generated/opencode.managed.json +0 -115
- /package/src/{.agents/agents → agents}/research/framework-docs-researcher.md +0 -0
- /package/src/{.agents/agents → agents}/research/git-history-analyzer.md +0 -0
- /package/src/{.agents/agents → agents}/research/learnings-researcher.md +0 -0
- /package/src/{.agents/agents → agents}/research/repo-research-analyst.md +0 -0
- /package/src/{.agents/agents → agents}/review/agent-native-reviewer.md +0 -0
- /package/src/{.agents/agents → agents}/review/planning-technical-reviewer.md +0 -0
- /package/src/{.agents/agents → agents}/workflow/bug-reproduction-validator.md +0 -0
- /package/src/{.agents/agents → agents}/workflow/lint.md +0 -0
- /package/src/{.agents/agents → agents}/workflow/spec-flow-analyzer.md +0 -0
- /package/src/{.agents/commands → commands}/workflow-review.md +0 -0
- /package/src/{.agents/commands → commands}/workflow-tech-review.md +0 -0
- /package/src/{.agents/commands → commands}/workflow-triage.md +0 -0
- /package/src/{.agents/references → references}/standards/README.md +0 -0
- /package/src/{.agents/skills → skills}/agent-browser/SKILL.md +0 -0
- /package/src/{.agents/skills → skills}/audit-traceability/SKILL.md +0 -0
- /package/src/{.agents/skills → skills}/brainstorming/SKILL.md +0 -0
- /package/src/{.agents/skills → skills}/compound-docs/assets/critical-pattern-template.md +0 -0
- /package/src/{.agents/skills → skills}/compound-docs/assets/resolution-template.md +0 -0
- /package/src/{.agents/skills → skills}/compound-docs/schema.project.yaml +0 -0
- /package/src/{.agents/skills → skills}/compound-docs/schema.yaml +0 -0
- /package/src/{.agents/skills → skills}/data-foundations/SKILL.md +0 -0
- /package/src/{.agents/skills → skills}/document-review/SKILL.md +0 -0
- /package/src/{.agents/skills → skills}/file-todos/SKILL.md +0 -0
- /package/src/{.agents/skills → skills}/file-todos/assets/todo-template.md +0 -0
- /package/src/{.agents/skills → skills}/financial-workflow-integrity/SKILL.md +0 -0
- /package/src/{.agents/skills → skills}/git-worktree/SKILL.md +0 -0
- /package/src/{.agents/skills → skills}/pii-protection-prisma/SKILL.md +0 -0
- /package/src/{.agents/skills → skills}/process-metrics/SKILL.md +0 -0
- /package/src/{.agents/skills → skills}/process-metrics/assets/daily-template.md +0 -0
- /package/src/{.agents/skills → skills}/process-metrics/assets/monthly-template.md +0 -0
- /package/src/{.agents/skills → skills}/process-metrics/assets/weekly-template.md +0 -0
- /package/src/{.agents/skills → skills}/technical-review/SKILL.md +0 -0
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
# Services Reference
|
|
2
|
+
|
|
3
|
+
Services own all IO and side effects. Nothing outside `infrastructure/services/` performs IO — no `fetch`, no `localStorage`, no async calls. Controllers call services; they never perform IO directly.
|
|
4
|
+
|
|
5
|
+
The service layer is implemented using **Effect Layers** — typed, composable units that declare their dependencies and provide an implementation.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Service Structure
|
|
10
|
+
|
|
11
|
+
Each service file has three exports:
|
|
12
|
+
|
|
13
|
+
1. **The service tag** — the interface, defined using `Context.Tag`
|
|
14
|
+
2. **The live Layer** — the implementation, defined using `Layer.succeed`
|
|
15
|
+
3. **The Effect programs** the controller will run
|
|
16
|
+
|
|
17
|
+
```typescript
|
|
18
|
+
// PlaylistService.ts
|
|
19
|
+
import { Context, Effect, Layer } from "effect";
|
|
20
|
+
|
|
21
|
+
// 1. Service tag — defines the interface
|
|
22
|
+
export class PlaylistService extends Context.Tag("PlaylistService")<
|
|
23
|
+
PlaylistService,
|
|
24
|
+
{
|
|
25
|
+
readonly fetchPlaylists: (folderId: string) => Effect.Effect<Playlist[], ApiError>;
|
|
26
|
+
readonly savePlaylist: (playlist: Playlist) => Effect.Effect<void, ApiError>;
|
|
27
|
+
}
|
|
28
|
+
>() {}
|
|
29
|
+
|
|
30
|
+
// 2. Live Layer — provides the implementation
|
|
31
|
+
export const PlaylistServiceLive = Layer.succeed(PlaylistService, {
|
|
32
|
+
fetchPlaylists: (folderId) =>
|
|
33
|
+
Effect.tryPromise({
|
|
34
|
+
try: () => api.get(`/folders/${folderId}/playlists`),
|
|
35
|
+
catch: (e) => new ApiError({ cause: e }),
|
|
36
|
+
}),
|
|
37
|
+
savePlaylist: (playlist) =>
|
|
38
|
+
Effect.tryPromise({
|
|
39
|
+
try: () => api.post("/playlists", playlist),
|
|
40
|
+
catch: (e) => new ApiError({ cause: e }),
|
|
41
|
+
}),
|
|
42
|
+
});
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
47
|
+
## Feature Layer Composition
|
|
48
|
+
|
|
49
|
+
Each feature composes its service Layers into a single export from `infrastructure/services/index.ts`:
|
|
50
|
+
|
|
51
|
+
```typescript
|
|
52
|
+
// infrastructure/services/index.ts
|
|
53
|
+
import { Layer } from "effect";
|
|
54
|
+
import { PlaylistServiceLive } from "./PlaylistService";
|
|
55
|
+
import { FolderServiceLive } from "./FolderService";
|
|
56
|
+
|
|
57
|
+
export const FeatureServicesLive = Layer.mergeAll(
|
|
58
|
+
PlaylistServiceLive,
|
|
59
|
+
FolderServiceLive,
|
|
60
|
+
);
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
|
|
65
|
+
## App Runtime Composition
|
|
66
|
+
|
|
67
|
+
All feature layers are composed once at the app level in `src/effects.ts`. This is the only place the runtime is constructed.
|
|
68
|
+
|
|
69
|
+
```typescript
|
|
70
|
+
// src/effects.ts
|
|
71
|
+
import { ManagedRuntime, Layer } from "effect";
|
|
72
|
+
import { FeatureServicesLive } from "src/features/{feature}/infrastructure/services";
|
|
73
|
+
import { OtherFeatureServicesLive } from "src/features/other/infrastructure/services";
|
|
74
|
+
|
|
75
|
+
const AppLayer = Layer.mergeAll(
|
|
76
|
+
FeatureServicesLive,
|
|
77
|
+
OtherFeatureServicesLive,
|
|
78
|
+
);
|
|
79
|
+
|
|
80
|
+
export const AppRuntime = ManagedRuntime.make(AppLayer);
|
|
81
|
+
export type AppServices = Layer.Layer.Success<typeof AppLayer>;
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
The runtime is then injected into the root controller via XState v5 `input` — see `references/state-management.md` for the injection pattern.
|
|
85
|
+
|
|
86
|
+
---
|
|
87
|
+
|
|
88
|
+
## File Structure
|
|
89
|
+
|
|
90
|
+
```
|
|
91
|
+
src/
|
|
92
|
+
├── effects.ts # App runtime — composed once here, never elsewhere
|
|
93
|
+
└── features/{feature}/
|
|
94
|
+
└── infrastructure/
|
|
95
|
+
└── services/
|
|
96
|
+
├── PlaylistService.ts # Service tag + live Layer
|
|
97
|
+
├── FolderService.ts # Service tag + live Layer
|
|
98
|
+
└── index.ts # Feature layer composition
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
---
|
|
102
|
+
|
|
103
|
+
## Rules
|
|
104
|
+
|
|
105
|
+
- Services own all IO — no `fetch`, `localStorage`, or async calls outside `infrastructure/services/`
|
|
106
|
+
- Return `Effect` types, never raw `Promise`
|
|
107
|
+
- One service per concern — `PlaylistService.ts` vs `FolderService.ts`
|
|
108
|
+
- Feature layers composed in `services/index.ts`
|
|
109
|
+
- App runtime composed in `src/effects.ts` only — never inside a feature or machine
|
|
110
|
+
|
|
111
|
+
---
|
|
112
|
+
|
|
113
|
+
## Quick Check — Common Violations
|
|
114
|
+
|
|
115
|
+
**IO performed directly in a controller:**
|
|
116
|
+
```typescript
|
|
117
|
+
// ❌ Controller doing IO
|
|
118
|
+
actions: assign({
|
|
119
|
+
playlists: async () => {
|
|
120
|
+
const res = await fetch("/api/playlists");
|
|
121
|
+
return res.json();
|
|
122
|
+
},
|
|
123
|
+
})
|
|
124
|
+
|
|
125
|
+
// ✅ Controller calls the service via the injected runtime
|
|
126
|
+
invoke: {
|
|
127
|
+
src: "fetchPlaylists",
|
|
128
|
+
input: ({ context }) => ({
|
|
129
|
+
runtime: context.runtime,
|
|
130
|
+
folderId: context.activeFolderId,
|
|
131
|
+
}),
|
|
132
|
+
}
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
**Raw Promise returned from a service:**
|
|
136
|
+
```typescript
|
|
137
|
+
// ❌ Returns a Promise — loses typed errors and composability
|
|
138
|
+
export const PlaylistServiceLive = Layer.succeed(PlaylistService, {
|
|
139
|
+
fetchPlaylists: async (folderId) => api.get(`/folders/${folderId}/playlists`),
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
// ✅ Returns an Effect — typed errors, composable
|
|
143
|
+
export const PlaylistServiceLive = Layer.succeed(PlaylistService, {
|
|
144
|
+
fetchPlaylists: (folderId) =>
|
|
145
|
+
Effect.tryPromise({
|
|
146
|
+
try: () => api.get(`/folders/${folderId}/playlists`),
|
|
147
|
+
catch: (e) => new ApiError({ cause: e }),
|
|
148
|
+
}),
|
|
149
|
+
});
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
**Runtime constructed inside a machine:**
|
|
153
|
+
```typescript
|
|
154
|
+
// ❌ Machine owns the runtime — never do this
|
|
155
|
+
context: {
|
|
156
|
+
runtime: ManagedRuntime.make(AppLayer),
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
// ✅ Runtime injected from outside via input
|
|
160
|
+
context: ({ input }) => ({
|
|
161
|
+
runtime: input.runtime,
|
|
162
|
+
})
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
**Feature services bypassing their index:**
|
|
166
|
+
```typescript
|
|
167
|
+
// ❌ App runtime imports individual services directly
|
|
168
|
+
import { PlaylistServiceLive } from "src/features/{feature}/infrastructure/services/PlaylistService";
|
|
169
|
+
|
|
170
|
+
// ✅ App runtime imports the composed feature layer
|
|
171
|
+
import { FeatureServicesLive } from "src/features/{feature}/infrastructure/services";
|
|
172
|
+
```
|