@apogeelabs/the-agency 0.1.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 +93 -0
- package/bin/cli.js +2 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +20 -0
- package/dist/manifest.d.ts +12 -0
- package/dist/manifest.js +24 -0
- package/dist/sync.d.ts +14 -0
- package/dist/sync.js +97 -0
- package/package.json +45 -0
- package/src/templates/.ai/UnitTestExamples.md +1148 -0
- package/src/templates/.ai/UnitTestGeneration.md +477 -0
- package/src/templates/.ai/workflow.md +59 -0
- package/src/templates/.claude/agents/architect.md +90 -0
- package/src/templates/.claude/agents/dev.md +79 -0
- package/src/templates/.claude/agents/explorer.md +93 -0
- package/src/templates/.claude/agents/pm.md +74 -0
- package/src/templates/.claude/agents/reviewer.md +93 -0
- package/src/templates/.claude/agents/test-hardener.md +121 -0
- package/src/templates/.claude/commands/architect.md +108 -0
- package/src/templates/.claude/commands/build.md +125 -0
- package/src/templates/.claude/commands/pm.md +72 -0
- package/src/templates/.claude/commands/review-pr.md +279 -0
- package/src/templates/.claude/settings.local.json +44 -0
package/README.md
ADDED
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
# @apogeelabs/the-agency
|
|
2
|
+
|
|
3
|
+
Centralized Claude Code agents, commands, and workflows. Install once, sync to any project.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install -D @apogeelabs/the-agency
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Usage
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
# Sync all agents, commands, and AI context files to your project
|
|
15
|
+
npx the-agency sync
|
|
16
|
+
|
|
17
|
+
# Choose which files to sync
|
|
18
|
+
npx the-agency sync --pick
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Files are copied to `.claude/agents/`, `.claude/commands/`, and `.ai/` in the target project. If destination files already exist, you'll be prompted before overwriting.
|
|
22
|
+
|
|
23
|
+
## What's Included
|
|
24
|
+
|
|
25
|
+
### Agents (`.claude/agents/`)
|
|
26
|
+
|
|
27
|
+
Autonomous subagents that run in isolated context windows and communicate through files.
|
|
28
|
+
|
|
29
|
+
| Agent | Purpose |
|
|
30
|
+
| ----------------- | ---------------------------------------------------------- |
|
|
31
|
+
| **architect** | Designs technical approach, produces build plans |
|
|
32
|
+
| **dev** | Implements features from build plans, task by task |
|
|
33
|
+
| **explorer** | Maps and documents unfamiliar codebases (read-only) |
|
|
34
|
+
| **pm** | Produces product briefs from requirements |
|
|
35
|
+
| **reviewer** | Adversarial code review with pass/fail verdict (read-only) |
|
|
36
|
+
| **test-hardener** | Writes edge case tests, tries to break things |
|
|
37
|
+
|
|
38
|
+
### Commands (`.claude/commands/`)
|
|
39
|
+
|
|
40
|
+
Slash commands invoked in Claude Code sessions.
|
|
41
|
+
|
|
42
|
+
| Command | Purpose |
|
|
43
|
+
| ------------ | -------------------------------------------------- |
|
|
44
|
+
| `/architect` | Interactive architecture design session |
|
|
45
|
+
| `/build` | Orchestrates the full dev → review → test pipeline |
|
|
46
|
+
| `/pm` | Interactive product requirements discovery |
|
|
47
|
+
| `/review-pr` | Structured PR review briefing |
|
|
48
|
+
|
|
49
|
+
### AI Context (`.ai/`)
|
|
50
|
+
|
|
51
|
+
Reference material automatically available to Claude Code.
|
|
52
|
+
|
|
53
|
+
| File | Purpose |
|
|
54
|
+
| ------------------------- | ----------------------------------------- |
|
|
55
|
+
| **UnitTestGeneration.md** | TypeScript/Jest unit testing style guide |
|
|
56
|
+
| **UnitTestExamples.md** | Working examples for the test style guide |
|
|
57
|
+
| **workflow.md** | Multi-agent development workflow guide |
|
|
58
|
+
|
|
59
|
+
## The Workflow
|
|
60
|
+
|
|
61
|
+
```
|
|
62
|
+
/pm → docs/briefs/[feature].md → /architect → docs/build-plans/[feature].md → /build
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
- **`/pm`** and **`/architect`** are interactive — back-and-forth conversations that produce documents
|
|
66
|
+
- **`/build`** is autonomous — orchestrates dev, review, and test agents with automatic fix loops
|
|
67
|
+
- Agents communicate only through the filesystem. No shared context. This is intentional.
|
|
68
|
+
|
|
69
|
+
See `.ai/workflow.md` after syncing for the full workflow guide.
|
|
70
|
+
|
|
71
|
+
## Project-Specific Configuration
|
|
72
|
+
|
|
73
|
+
The sync does **not** copy `settings.local.json` or `settings.json` — those are project-specific. See the [Claude Code docs](https://docs.anthropic.com/en/docs/claude-code) for configuring permissions per-project.
|
|
74
|
+
|
|
75
|
+
## Requirements
|
|
76
|
+
|
|
77
|
+
- Node.js >= 22
|
|
78
|
+
- Claude Code
|
|
79
|
+
- GitHub CLI (`gh`) — required for `/review-pr` and PR-related operations
|
|
80
|
+
|
|
81
|
+
## Development
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
pnpm install
|
|
85
|
+
pnpm build # Compile TypeScript → dist/
|
|
86
|
+
pnpm test # Run test suite
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
Versioning is managed with [changesets](https://github.com/changesets/changesets). To propose a version bump:
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
pnpm changeset
|
|
93
|
+
```
|
package/bin/cli.js
ADDED
package/dist/cli.d.ts
ADDED
package/dist/cli.js
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { sync } from "./sync.js";
|
|
2
|
+
const args = process.argv.slice(2);
|
|
3
|
+
const command = args[0];
|
|
4
|
+
if (!command || command === "help" || command === "--help") {
|
|
5
|
+
console.log(`
|
|
6
|
+
Usage: the-agency <command> [options]
|
|
7
|
+
|
|
8
|
+
Commands:
|
|
9
|
+
sync Sync all Claude Code files to the current project
|
|
10
|
+
sync --pick Interactively select which files to sync
|
|
11
|
+
`);
|
|
12
|
+
process.exit(0);
|
|
13
|
+
}
|
|
14
|
+
if (command === "sync") {
|
|
15
|
+
const pick = args.includes("--pick");
|
|
16
|
+
await sync({ pick });
|
|
17
|
+
} else {
|
|
18
|
+
console.error(`Unknown command: ${command}`);
|
|
19
|
+
process.exit(1);
|
|
20
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
interface ManifestItem {
|
|
2
|
+
file: string;
|
|
3
|
+
description: string;
|
|
4
|
+
}
|
|
5
|
+
interface Manifest {
|
|
6
|
+
agents: ManifestItem[];
|
|
7
|
+
commands: ManifestItem[];
|
|
8
|
+
ai: ManifestItem[];
|
|
9
|
+
}
|
|
10
|
+
declare const manifest: Manifest;
|
|
11
|
+
|
|
12
|
+
export { type Manifest, type ManifestItem, manifest };
|
package/dist/manifest.js
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
const manifest = {
|
|
2
|
+
agents: [
|
|
3
|
+
{ file: "architect.md", description: "Designs technical approach, produces build plans" },
|
|
4
|
+
{ file: "dev.md", description: "Implements features from build plans" },
|
|
5
|
+
{ file: "explorer.md", description: "Explores and maps unfamiliar codebases" },
|
|
6
|
+
{ file: "pm.md", description: "Produces product briefs from requirements" },
|
|
7
|
+
{ file: "reviewer.md", description: "Adversarial code review with pass/fail verdict" },
|
|
8
|
+
{ file: "test-hardener.md", description: "Hardens test coverage, finds edge cases" }
|
|
9
|
+
],
|
|
10
|
+
commands: [
|
|
11
|
+
{ file: "architect.md", description: "Interactive architecture design sessions" },
|
|
12
|
+
{ file: "build.md", description: "Build orchestrator pipeline" },
|
|
13
|
+
{ file: "pm.md", description: "Interactive product requirements discovery" },
|
|
14
|
+
{ file: "review-pr.md", description: "Structured PR review briefing" }
|
|
15
|
+
],
|
|
16
|
+
ai: [
|
|
17
|
+
{ file: "UnitTestGeneration.md", description: "TypeScript/Jest unit testing style guide" },
|
|
18
|
+
{ file: "UnitTestExamples.md", description: "Reference examples for the test style guide" },
|
|
19
|
+
{ file: "workflow.md", description: "Multi-agent development workflow guide" }
|
|
20
|
+
]
|
|
21
|
+
};
|
|
22
|
+
export {
|
|
23
|
+
manifest
|
|
24
|
+
};
|
package/dist/sync.d.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { ManifestItem } from './manifest.js';
|
|
2
|
+
|
|
3
|
+
interface SyncFile {
|
|
4
|
+
src: string;
|
|
5
|
+
dest: string;
|
|
6
|
+
label: string;
|
|
7
|
+
}
|
|
8
|
+
declare function getFilesToSync(categories: Record<string, ManifestItem[]>): SyncFile[];
|
|
9
|
+
declare function fileExists(path: string): Promise<boolean>;
|
|
10
|
+
declare function sync({ pick }?: {
|
|
11
|
+
pick?: boolean | undefined;
|
|
12
|
+
}): Promise<void>;
|
|
13
|
+
|
|
14
|
+
export { fileExists, getFilesToSync, sync };
|
package/dist/sync.js
ADDED
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { resolve, dirname, join } from "node:path";
|
|
2
|
+
import { fileURLToPath } from "node:url";
|
|
3
|
+
import { copyFile, mkdir, access } from "node:fs/promises";
|
|
4
|
+
import prompts from "prompts";
|
|
5
|
+
import { manifest } from "./manifest.js";
|
|
6
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
7
|
+
const packageRoot = resolve(__dirname, "..");
|
|
8
|
+
const categoryConfig = {
|
|
9
|
+
agents: { src: "src/templates/.claude/agents", dest: ".claude/agents" },
|
|
10
|
+
commands: { src: "src/templates/.claude/commands", dest: ".claude/commands" },
|
|
11
|
+
ai: { src: "src/templates/.ai", dest: ".ai" }
|
|
12
|
+
};
|
|
13
|
+
function getFilesToSync(categories) {
|
|
14
|
+
const files = [];
|
|
15
|
+
for (const [category, items] of Object.entries(categories)) {
|
|
16
|
+
const config = categoryConfig[category];
|
|
17
|
+
for (const item of items) {
|
|
18
|
+
files.push({
|
|
19
|
+
src: join(packageRoot, config.src, item.file),
|
|
20
|
+
dest: join(process.cwd(), config.dest, item.file),
|
|
21
|
+
label: `${config.dest}/${item.file}`
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
return files;
|
|
26
|
+
}
|
|
27
|
+
async function fileExists(path) {
|
|
28
|
+
try {
|
|
29
|
+
await access(path);
|
|
30
|
+
return true;
|
|
31
|
+
} catch {
|
|
32
|
+
return false;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
async function sync({ pick = false } = {}) {
|
|
36
|
+
let selectedCategories;
|
|
37
|
+
if (pick) {
|
|
38
|
+
const choices = Object.entries(manifest).flatMap(
|
|
39
|
+
([category, items]) => items.map((item) => ({
|
|
40
|
+
title: `${categoryConfig[category].dest}/${item.file}`,
|
|
41
|
+
description: item.description,
|
|
42
|
+
value: { category, item },
|
|
43
|
+
selected: true
|
|
44
|
+
}))
|
|
45
|
+
);
|
|
46
|
+
const { selected } = await prompts({
|
|
47
|
+
type: "multiselect",
|
|
48
|
+
name: "selected",
|
|
49
|
+
message: "Select files to sync",
|
|
50
|
+
choices,
|
|
51
|
+
instructions: false,
|
|
52
|
+
hint: "- Space to toggle, Enter to confirm"
|
|
53
|
+
});
|
|
54
|
+
if (!selected || selected.length === 0) {
|
|
55
|
+
console.log("Nothing selected. Exiting.");
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
selectedCategories = {};
|
|
59
|
+
for (const { category, item } of selected) {
|
|
60
|
+
if (!selectedCategories[category]) selectedCategories[category] = [];
|
|
61
|
+
selectedCategories[category].push(item);
|
|
62
|
+
}
|
|
63
|
+
} else {
|
|
64
|
+
selectedCategories = { ...manifest };
|
|
65
|
+
}
|
|
66
|
+
const files = getFilesToSync(selectedCategories);
|
|
67
|
+
const existing = [];
|
|
68
|
+
for (const f of files) {
|
|
69
|
+
if (await fileExists(f.dest)) {
|
|
70
|
+
existing.push(f.label);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
if (existing.length > 0) {
|
|
74
|
+
const { proceed } = await prompts({
|
|
75
|
+
type: "confirm",
|
|
76
|
+
name: "proceed",
|
|
77
|
+
message: `${existing.length} destination file(s) will be overwritten. Proceed?`,
|
|
78
|
+
initial: true
|
|
79
|
+
});
|
|
80
|
+
if (!proceed) {
|
|
81
|
+
console.log("Sync cancelled.");
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
for (const f of files) {
|
|
86
|
+
await mkdir(dirname(f.dest), { recursive: true });
|
|
87
|
+
await copyFile(f.src, f.dest);
|
|
88
|
+
console.log(` \u2713 ${f.label}`);
|
|
89
|
+
}
|
|
90
|
+
console.log(`
|
|
91
|
+
Synced ${files.length} file(s).`);
|
|
92
|
+
}
|
|
93
|
+
export {
|
|
94
|
+
fileExists,
|
|
95
|
+
getFilesToSync,
|
|
96
|
+
sync
|
|
97
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@apogeelabs/the-agency",
|
|
3
|
+
"version": "0.1.1",
|
|
4
|
+
"description": "Centralized Claude Code agents, commands, and workflows",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"the-agency": "./bin/cli.js"
|
|
8
|
+
},
|
|
9
|
+
"files": [
|
|
10
|
+
"bin/",
|
|
11
|
+
"dist/",
|
|
12
|
+
"src/templates/",
|
|
13
|
+
"!src/templates/.claude/settings*.json"
|
|
14
|
+
],
|
|
15
|
+
"dependencies": {
|
|
16
|
+
"prompts": "^2.4.2"
|
|
17
|
+
},
|
|
18
|
+
"engines": {
|
|
19
|
+
"node": ">=22"
|
|
20
|
+
},
|
|
21
|
+
"license": "UNLICENSED",
|
|
22
|
+
"private": false,
|
|
23
|
+
"devDependencies": {
|
|
24
|
+
"@changesets/cli": "^2.29.8",
|
|
25
|
+
"@types/jest": "^30.0.0",
|
|
26
|
+
"@types/node": "^25.2.3",
|
|
27
|
+
"@types/prompts": "^2.4.9",
|
|
28
|
+
"husky": "^9.1.7",
|
|
29
|
+
"jest": "^30.2.0",
|
|
30
|
+
"lint-staged": "^16.2.7",
|
|
31
|
+
"prettier": "^3.8.1",
|
|
32
|
+
"ts-jest": "^29.4.6",
|
|
33
|
+
"tsup": "^8.5.1",
|
|
34
|
+
"typescript": "^5.9.3"
|
|
35
|
+
},
|
|
36
|
+
"lint-staged": {
|
|
37
|
+
"*.{js,mjs,ts,css,md}": "prettier --write",
|
|
38
|
+
"*.{yml,yaml}": "prettier --write",
|
|
39
|
+
"*.json": "prettier --write"
|
|
40
|
+
},
|
|
41
|
+
"scripts": {
|
|
42
|
+
"build": "tsup",
|
|
43
|
+
"test": "NODE_OPTIONS='--experimental-vm-modules' jest"
|
|
44
|
+
}
|
|
45
|
+
}
|