@markjaquith/agency 1.11.0 → 2.0.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.
- package/README.md +302 -113
- package/cli.ts +123 -415
- package/index.ts +1 -1
- package/package.json +12 -17
- package/skills/agency/SKILL.md +258 -0
- package/src/cli.test.ts +290 -0
- package/src/commands/description.test.ts +103 -0
- package/src/commands/epic.test.ts +103 -0
- package/src/commands/epic.ts +101 -0
- package/src/commands/init.test.ts +42 -290
- package/src/commands/init.ts +15 -123
- package/src/commands/phase.ts +120 -0
- package/src/commands/pr.test.ts +19 -170
- package/src/commands/pr.ts +23 -179
- package/src/commands/repo.test.ts +80 -0
- package/src/commands/repo.ts +83 -0
- package/src/commands/status.test.ts +35 -477
- package/src/commands/status.ts +24 -213
- package/src/commands/task-phase.test.ts +206 -0
- package/src/commands/task.ts +83 -1285
- package/src/commands/validate.test.ts +91 -0
- package/src/commands/validate.ts +50 -0
- package/src/commands/work.test.ts +172 -419
- package/src/commands/work.ts +47 -166
- package/src/services/EpicService.test.ts +71 -0
- package/src/services/EpicService.ts +135 -0
- package/src/services/FileSystemService.ts +61 -92
- package/src/services/PhaseService.ts +323 -0
- package/src/services/PullRequestService.test.ts +386 -0
- package/src/services/PullRequestService.ts +143 -0
- package/src/services/RepositoryService.test.ts +106 -0
- package/src/services/RepositoryService.ts +159 -0
- package/src/services/TaskPhaseService.test.ts +217 -0
- package/src/services/TaskService.ts +192 -0
- package/src/services/WorkbaseService.test.ts +446 -0
- package/src/services/WorkbaseService.ts +493 -0
- package/src/services/WorktreeService.test.ts +599 -0
- package/src/services/WorktreeService.ts +357 -0
- package/src/test-utils.ts +41 -438
- package/src/types.ts +1 -215
- package/src/utils/command.ts +1 -5
- package/src/utils/effect.test.ts +24 -0
- package/src/utils/effect.ts +3 -273
- package/src/utils/process.test.ts +0 -15
- package/src/utils/process.ts +1 -60
- package/src/workbase/frontmatter.test.ts +50 -0
- package/src/workbase/frontmatter.ts +77 -0
- package/src/workbase/repository-reference.test.ts +25 -0
- package/src/workbase/repository-reference.ts +18 -0
- package/src/workbase/schemas.test.ts +146 -0
- package/src/workbase/schemas.ts +78 -0
- package/src/workbase/worktree-command.test.ts +61 -0
- package/src/workbase/worktree-command.ts +52 -0
- package/src/commands/base.test.ts +0 -198
- package/src/commands/base.ts +0 -198
- package/src/commands/clean.test.ts +0 -299
- package/src/commands/clean.ts +0 -274
- package/src/commands/completions.test.ts +0 -51
- package/src/commands/completions.ts +0 -308
- package/src/commands/emit.integration.test.ts +0 -549
- package/src/commands/emit.test.ts +0 -576
- package/src/commands/emit.ts +0 -700
- package/src/commands/emitted.test.ts +0 -226
- package/src/commands/emitted.ts +0 -57
- package/src/commands/loop.test.ts +0 -621
- package/src/commands/loop.ts +0 -406
- package/src/commands/merge.integration.test.ts +0 -195
- package/src/commands/merge.test.ts +0 -246
- package/src/commands/merge.ts +0 -244
- package/src/commands/pull.test.ts +0 -395
- package/src/commands/pull.ts +0 -205
- package/src/commands/push.test.ts +0 -518
- package/src/commands/push.ts +0 -434
- package/src/commands/rebase.test.ts +0 -521
- package/src/commands/rebase.ts +0 -232
- package/src/commands/save.test.ts +0 -247
- package/src/commands/save.ts +0 -162
- package/src/commands/source.test.ts +0 -195
- package/src/commands/source.ts +0 -72
- package/src/commands/switch.test.ts +0 -194
- package/src/commands/switch.ts +0 -84
- package/src/commands/task-branching.test.ts +0 -633
- package/src/commands/task-continue.test.ts +0 -311
- package/src/commands/task-edit.test.ts +0 -235
- package/src/commands/task-main.test.ts +0 -1066
- package/src/commands/task-squash.test.ts +0 -266
- package/src/commands/tasks.test.ts +0 -391
- package/src/commands/tasks.ts +0 -161
- package/src/commands/template-delete.test.ts +0 -178
- package/src/commands/template-delete.ts +0 -98
- package/src/commands/template-list.test.ts +0 -135
- package/src/commands/template-list.ts +0 -87
- package/src/commands/template-view.test.ts +0 -158
- package/src/commands/template-view.ts +0 -86
- package/src/commands/template.test.ts +0 -32
- package/src/commands/template.ts +0 -96
- package/src/commands/use.test.ts +0 -87
- package/src/commands/use.ts +0 -97
- package/src/constants.ts +0 -10
- package/src/errors.ts +0 -17
- package/src/schemas.ts +0 -33
- package/src/services/AgencyMetadataService.ts +0 -311
- package/src/services/ClaudeService.test.ts +0 -184
- package/src/services/ClaudeService.ts +0 -91
- package/src/services/ConfigService.ts +0 -115
- package/src/services/FilterRepoService.ts +0 -164
- package/src/services/FormatterService.test.ts +0 -432
- package/src/services/FormatterService.ts +0 -219
- package/src/services/GitService.ts +0 -1183
- package/src/services/MockFilterRepoService.ts +0 -140
- package/src/services/OpencodeService.ts +0 -263
- package/src/services/PromptService.ts +0 -183
- package/src/services/TemplateService.ts +0 -81
- package/src/types/native-exec.d.ts +0 -8
- package/src/utils/colors.ts +0 -178
- package/src/utils/git-path.ts +0 -6
- package/src/utils/glob.test.ts +0 -161
- package/src/utils/glob.ts +0 -78
- package/src/utils/paths.ts +0 -51
- package/src/utils/pr-branch.test.ts +0 -376
- package/src/utils/pr-branch.ts +0 -508
- package/src/utils/spinner.test.ts +0 -45
- package/src/utils/spinner.ts +0 -96
- package/src/utils/task-parser.test.ts +0 -172
- package/src/utils/task-parser.ts +0 -93
- package/templates/AGENCY.md +0 -22
- package/templates/AGENTS.md +0 -11
- package/templates/CLAUDE.md +0 -3
- package/templates/TASK.md +0 -5
- package/templates/opencode.json +0 -4
|
@@ -1,219 +0,0 @@
|
|
|
1
|
-
import { Effect } from "effect"
|
|
2
|
-
import { resolve } from "path"
|
|
3
|
-
import { FileSystemService } from "./FileSystemService"
|
|
4
|
-
|
|
5
|
-
type PackageJson = {
|
|
6
|
-
dependencies?: Record<string, string>
|
|
7
|
-
devDependencies?: Record<string, string>
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
type PackageManager = "bun" | "yarn" | "pnpm" | "npm"
|
|
11
|
-
|
|
12
|
-
type Formatter = "prettier" | "oxfmt"
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* Service for detecting and running code formatters on agency-created files.
|
|
16
|
-
*
|
|
17
|
-
* When agency creates files (markdown, json), pre-commit or pre-push hooks
|
|
18
|
-
* in the target project may fail if those files aren't formatted according
|
|
19
|
-
* to the project's formatter settings. This service detects the project's
|
|
20
|
-
* formatter (prettier or oxfmt) and package manager, then runs the formatter
|
|
21
|
-
* on the specified files. Failures are silently ignored.
|
|
22
|
-
*/
|
|
23
|
-
export class FormatterService extends Effect.Service<FormatterService>()(
|
|
24
|
-
"FormatterService",
|
|
25
|
-
{
|
|
26
|
-
sync: () => ({
|
|
27
|
-
/**
|
|
28
|
-
* Detect which package manager the project uses by checking for lock files.
|
|
29
|
-
* Falls back to npm if no lock file is found but package.json exists.
|
|
30
|
-
* Returns null if no package.json exists.
|
|
31
|
-
*/
|
|
32
|
-
detectPackageManager: (gitRoot: string) =>
|
|
33
|
-
Effect.gen(function* () {
|
|
34
|
-
const fs = yield* FileSystemService
|
|
35
|
-
|
|
36
|
-
// Check for package.json first - if it doesn't exist, no package manager
|
|
37
|
-
const hasPackageJson = yield* fs.exists(
|
|
38
|
-
resolve(gitRoot, "package.json"),
|
|
39
|
-
)
|
|
40
|
-
if (!hasPackageJson) {
|
|
41
|
-
return null
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
// Check lock files in priority order
|
|
45
|
-
if (yield* fs.exists(resolve(gitRoot, "bun.lockb")))
|
|
46
|
-
return "bun" as PackageManager
|
|
47
|
-
if (yield* fs.exists(resolve(gitRoot, "bun.lock")))
|
|
48
|
-
return "bun" as PackageManager
|
|
49
|
-
if (yield* fs.exists(resolve(gitRoot, "yarn.lock")))
|
|
50
|
-
return "yarn" as PackageManager
|
|
51
|
-
if (yield* fs.exists(resolve(gitRoot, "pnpm-lock.yaml")))
|
|
52
|
-
return "pnpm" as PackageManager
|
|
53
|
-
if (yield* fs.exists(resolve(gitRoot, "package-lock.json")))
|
|
54
|
-
return "npm" as PackageManager
|
|
55
|
-
|
|
56
|
-
// Default to npm if package.json exists but no lock file found
|
|
57
|
-
return "npm" as PackageManager
|
|
58
|
-
}),
|
|
59
|
-
|
|
60
|
-
/**
|
|
61
|
-
* Detect which formatter is available in the project's package.json.
|
|
62
|
-
* Checks both dependencies and devDependencies for prettier and oxfmt.
|
|
63
|
-
* Returns null if neither is found.
|
|
64
|
-
*/
|
|
65
|
-
detectFormatter: (gitRoot: string) =>
|
|
66
|
-
Effect.gen(function* () {
|
|
67
|
-
const fs = yield* FileSystemService
|
|
68
|
-
|
|
69
|
-
const packageJsonPath = resolve(gitRoot, "package.json")
|
|
70
|
-
const exists = yield* fs.exists(packageJsonPath)
|
|
71
|
-
if (!exists) {
|
|
72
|
-
return null
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
const packageJson = yield* fs.readJSON<PackageJson>(packageJsonPath)
|
|
76
|
-
|
|
77
|
-
const allDeps = {
|
|
78
|
-
...packageJson.dependencies,
|
|
79
|
-
...packageJson.devDependencies,
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
// Check for oxfmt first (newer/faster), then prettier
|
|
83
|
-
if ("oxfmt" in allDeps) return "oxfmt" as Formatter
|
|
84
|
-
if ("prettier" in allDeps) return "prettier" as Formatter
|
|
85
|
-
|
|
86
|
-
return null
|
|
87
|
-
}).pipe(Effect.catchAll(() => Effect.succeed(null))),
|
|
88
|
-
|
|
89
|
-
/**
|
|
90
|
-
* Build the command to run a formatter via the detected package manager.
|
|
91
|
-
* Returns the command args array, or null if the formatter/pm combo isn't supported.
|
|
92
|
-
*/
|
|
93
|
-
buildFormatterCommand: (
|
|
94
|
-
formatter: Formatter,
|
|
95
|
-
packageManager: PackageManager,
|
|
96
|
-
files: string[],
|
|
97
|
-
) =>
|
|
98
|
-
Effect.sync(() => {
|
|
99
|
-
if (files.length === 0) return null
|
|
100
|
-
|
|
101
|
-
// Build the runner prefix based on package manager
|
|
102
|
-
const runnerPrefix: string[] = (() => {
|
|
103
|
-
switch (packageManager) {
|
|
104
|
-
case "bun":
|
|
105
|
-
return ["bun", "x"]
|
|
106
|
-
case "yarn":
|
|
107
|
-
return ["yarn", "dlx"]
|
|
108
|
-
case "pnpm":
|
|
109
|
-
return ["pnpm", "exec"]
|
|
110
|
-
case "npm":
|
|
111
|
-
return ["npx"]
|
|
112
|
-
}
|
|
113
|
-
})()
|
|
114
|
-
|
|
115
|
-
// Build the formatter command
|
|
116
|
-
switch (formatter) {
|
|
117
|
-
case "prettier":
|
|
118
|
-
return [...runnerPrefix, "prettier", "--write", ...files]
|
|
119
|
-
case "oxfmt":
|
|
120
|
-
return [...runnerPrefix, "oxfmt", ...files]
|
|
121
|
-
default:
|
|
122
|
-
return null
|
|
123
|
-
}
|
|
124
|
-
}),
|
|
125
|
-
|
|
126
|
-
/**
|
|
127
|
-
* Format the given files using the project's detected formatter.
|
|
128
|
-
* Silently returns if no formatter is detected or if the command fails.
|
|
129
|
-
* This is the main entry point for formatting agency-created files.
|
|
130
|
-
*/
|
|
131
|
-
formatFiles: (
|
|
132
|
-
gitRoot: string,
|
|
133
|
-
files: string[],
|
|
134
|
-
verboseLog: (msg: string) => void,
|
|
135
|
-
) =>
|
|
136
|
-
Effect.gen(function* () {
|
|
137
|
-
const fs = yield* FileSystemService
|
|
138
|
-
|
|
139
|
-
if (files.length === 0) {
|
|
140
|
-
verboseLog("No files to format")
|
|
141
|
-
return
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
// Filter to only .md and .json/.jsonc files (the types agency creates)
|
|
145
|
-
const formattableFiles = files.filter(
|
|
146
|
-
(f) =>
|
|
147
|
-
f.endsWith(".md") || f.endsWith(".json") || f.endsWith(".jsonc"),
|
|
148
|
-
)
|
|
149
|
-
|
|
150
|
-
if (formattableFiles.length === 0) {
|
|
151
|
-
verboseLog("No formattable files (md/json/jsonc) found")
|
|
152
|
-
return
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
// Use yield* on the service methods via self-reference through the service tag
|
|
156
|
-
const formatterService = yield* FormatterService
|
|
157
|
-
|
|
158
|
-
const formatter = yield* formatterService.detectFormatter(gitRoot)
|
|
159
|
-
if (!formatter) {
|
|
160
|
-
verboseLog("No formatter (prettier/oxfmt) detected in package.json")
|
|
161
|
-
return
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
const packageManager =
|
|
165
|
-
yield* formatterService.detectPackageManager(gitRoot)
|
|
166
|
-
if (!packageManager) {
|
|
167
|
-
verboseLog("No package manager detected")
|
|
168
|
-
return
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
verboseLog(
|
|
172
|
-
`Detected formatter: ${formatter}, package manager: ${packageManager}`,
|
|
173
|
-
)
|
|
174
|
-
|
|
175
|
-
// Build absolute paths for the files
|
|
176
|
-
const absolutePaths = formattableFiles.map((f) => resolve(gitRoot, f))
|
|
177
|
-
|
|
178
|
-
const command = yield* formatterService.buildFormatterCommand(
|
|
179
|
-
formatter,
|
|
180
|
-
packageManager,
|
|
181
|
-
absolutePaths,
|
|
182
|
-
)
|
|
183
|
-
if (!command) {
|
|
184
|
-
verboseLog("Could not build formatter command")
|
|
185
|
-
return
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
verboseLog(`Running formatter: ${command.join(" ")}`)
|
|
189
|
-
|
|
190
|
-
// Run the formatter, silently ignoring failures
|
|
191
|
-
yield* fs
|
|
192
|
-
.runCommand(command, {
|
|
193
|
-
cwd: gitRoot,
|
|
194
|
-
captureOutput: true,
|
|
195
|
-
})
|
|
196
|
-
.pipe(
|
|
197
|
-
Effect.catchAll((err) => {
|
|
198
|
-
verboseLog(`Formatter failed (silently ignoring): ${err}`)
|
|
199
|
-
return Effect.void
|
|
200
|
-
}),
|
|
201
|
-
)
|
|
202
|
-
|
|
203
|
-
verboseLog(
|
|
204
|
-
`Formatted ${formattableFiles.length} file(s) with ${formatter}`,
|
|
205
|
-
)
|
|
206
|
-
}).pipe(
|
|
207
|
-
// Catch any unexpected errors silently
|
|
208
|
-
Effect.catchAll((err) => {
|
|
209
|
-
verboseLog(`Formatting failed (silently ignoring): ${err}`)
|
|
210
|
-
return Effect.void
|
|
211
|
-
}),
|
|
212
|
-
Effect.catchAllDefect((defect) => {
|
|
213
|
-
verboseLog(`Formatting defect (silently ignoring): ${defect}`)
|
|
214
|
-
return Effect.void
|
|
215
|
-
}),
|
|
216
|
-
),
|
|
217
|
-
}),
|
|
218
|
-
},
|
|
219
|
-
) {}
|