@teammates/cli 0.5.0 → 0.5.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/dist/adapter.d.ts +8 -0
- package/dist/adapter.js +146 -108
- package/dist/adapter.test.js +29 -16
- package/dist/adapters/cli-proxy.js +59 -2
- package/dist/adapters/copilot.js +14 -2
- package/dist/adapters/echo.js +3 -1
- package/dist/banner.js +5 -1
- package/dist/cli-args.js +23 -23
- package/dist/cli-args.test.d.ts +1 -0
- package/dist/cli-args.test.js +125 -0
- package/dist/cli.js +301 -163
- package/dist/compact.d.ts +23 -0
- package/dist/compact.js +181 -11
- package/dist/compact.test.js +323 -7
- package/dist/index.d.ts +2 -1
- package/dist/index.js +2 -1
- package/dist/onboard.js +165 -165
- package/dist/orchestrator.js +7 -1
- package/dist/personas.test.d.ts +1 -0
- package/dist/personas.test.js +88 -0
- package/dist/registry.test.js +23 -23
- package/dist/theme.test.d.ts +1 -0
- package/dist/theme.test.js +113 -0
- package/dist/types.d.ts +7 -0
- package/package.json +3 -3
- package/personas/architect.md +4 -0
- package/personas/backend.md +4 -0
- package/personas/data-engineer.md +4 -0
- package/personas/designer.md +4 -0
- package/personas/devops.md +4 -0
- package/personas/frontend.md +4 -0
- package/personas/ml-ai.md +4 -0
- package/personas/mobile.md +4 -0
- package/personas/performance.md +4 -0
- package/personas/pm.md +4 -0
- package/personas/prompt-engineer.md +122 -0
- package/personas/qa.md +4 -0
- package/personas/security.md +4 -0
- package/personas/sre.md +4 -0
- package/personas/swe.md +4 -0
- package/personas/tech-writer.md +4 -0
package/dist/cli-args.js
CHANGED
|
@@ -97,28 +97,28 @@ export async function resolveAdapter(name, opts = {}) {
|
|
|
97
97
|
}
|
|
98
98
|
// ─── Usage ───────────────────────────────────────────────────────────
|
|
99
99
|
export function printUsage() {
|
|
100
|
-
console.log(`
|
|
101
|
-
${chalk.bold("@teammates/cli")} — Agent-agnostic teammate orchestrator
|
|
102
|
-
|
|
103
|
-
${chalk.bold("Usage:")}
|
|
104
|
-
teammates <agent> Launch session with an agent
|
|
105
|
-
teammates codex Use OpenAI Codex
|
|
106
|
-
teammates aider Use Aider
|
|
107
|
-
|
|
108
|
-
${chalk.bold("Options:")}
|
|
109
|
-
--model <model> Override the agent model
|
|
110
|
-
--dir <path> Override .teammates/ location
|
|
111
|
-
|
|
112
|
-
${chalk.bold("Agents:")}
|
|
113
|
-
claude Claude Code CLI (requires 'claude' on PATH)
|
|
114
|
-
codex OpenAI Codex CLI (requires 'codex' on PATH)
|
|
115
|
-
aider Aider CLI (requires 'aider' on PATH)
|
|
116
|
-
echo Test adapter — echoes prompts (no external agent)
|
|
117
|
-
|
|
118
|
-
${chalk.bold("In-session:")}
|
|
119
|
-
@teammate <task> Assign directly via @mention
|
|
120
|
-
<text> Auto-route to the best teammate
|
|
121
|
-
/status Session overview
|
|
122
|
-
/help All commands
|
|
100
|
+
console.log(`
|
|
101
|
+
${chalk.bold("@teammates/cli")} — Agent-agnostic teammate orchestrator
|
|
102
|
+
|
|
103
|
+
${chalk.bold("Usage:")}
|
|
104
|
+
teammates <agent> Launch session with an agent
|
|
105
|
+
teammates codex Use OpenAI Codex
|
|
106
|
+
teammates aider Use Aider
|
|
107
|
+
|
|
108
|
+
${chalk.bold("Options:")}
|
|
109
|
+
--model <model> Override the agent model
|
|
110
|
+
--dir <path> Override .teammates/ location
|
|
111
|
+
|
|
112
|
+
${chalk.bold("Agents:")}
|
|
113
|
+
claude Claude Code CLI (requires 'claude' on PATH)
|
|
114
|
+
codex OpenAI Codex CLI (requires 'codex' on PATH)
|
|
115
|
+
aider Aider CLI (requires 'aider' on PATH)
|
|
116
|
+
echo Test adapter — echoes prompts (no external agent)
|
|
117
|
+
|
|
118
|
+
${chalk.bold("In-session:")}
|
|
119
|
+
@teammate <task> Assign directly via @mention
|
|
120
|
+
<text> Auto-route to the best teammate
|
|
121
|
+
/status Session overview
|
|
122
|
+
/help All commands
|
|
123
123
|
`.trim());
|
|
124
124
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import { mkdir, rm } from "node:fs/promises";
|
|
2
|
+
import { tmpdir } from "node:os";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
|
5
|
+
import { findTeammatesDir, PKG_VERSION, parseCliArgs, printUsage, } from "./cli-args.js";
|
|
6
|
+
describe("parseCliArgs", () => {
|
|
7
|
+
it("returns defaults with no arguments", () => {
|
|
8
|
+
const result = parseCliArgs([]);
|
|
9
|
+
expect(result).toEqual({
|
|
10
|
+
showHelp: false,
|
|
11
|
+
modelOverride: undefined,
|
|
12
|
+
dirOverride: undefined,
|
|
13
|
+
adapterName: "echo",
|
|
14
|
+
agentPassthrough: [],
|
|
15
|
+
});
|
|
16
|
+
});
|
|
17
|
+
it("parses --help flag", () => {
|
|
18
|
+
const result = parseCliArgs(["--help"]);
|
|
19
|
+
expect(result.showHelp).toBe(true);
|
|
20
|
+
});
|
|
21
|
+
it("parses --model option with value", () => {
|
|
22
|
+
const result = parseCliArgs(["--model", "gpt-4"]);
|
|
23
|
+
expect(result.modelOverride).toBe("gpt-4");
|
|
24
|
+
});
|
|
25
|
+
it("parses --dir option with value", () => {
|
|
26
|
+
const result = parseCliArgs(["--dir", "/custom/path"]);
|
|
27
|
+
expect(result.dirOverride).toBe("/custom/path");
|
|
28
|
+
});
|
|
29
|
+
it("extracts adapter name as first positional argument", () => {
|
|
30
|
+
const result = parseCliArgs(["claude"]);
|
|
31
|
+
expect(result.adapterName).toBe("claude");
|
|
32
|
+
});
|
|
33
|
+
it("passes remaining args as agentPassthrough", () => {
|
|
34
|
+
const result = parseCliArgs(["claude", "--verbose", "--debug"]);
|
|
35
|
+
expect(result.adapterName).toBe("claude");
|
|
36
|
+
expect(result.agentPassthrough).toEqual(["--verbose", "--debug"]);
|
|
37
|
+
});
|
|
38
|
+
it("handles all options together", () => {
|
|
39
|
+
const result = parseCliArgs([
|
|
40
|
+
"--help",
|
|
41
|
+
"--model",
|
|
42
|
+
"sonnet",
|
|
43
|
+
"--dir",
|
|
44
|
+
"/tmp/tm",
|
|
45
|
+
"codex",
|
|
46
|
+
"--extra",
|
|
47
|
+
]);
|
|
48
|
+
expect(result.showHelp).toBe(true);
|
|
49
|
+
expect(result.modelOverride).toBe("sonnet");
|
|
50
|
+
expect(result.dirOverride).toBe("/tmp/tm");
|
|
51
|
+
expect(result.adapterName).toBe("codex");
|
|
52
|
+
expect(result.agentPassthrough).toEqual(["--extra"]);
|
|
53
|
+
});
|
|
54
|
+
it("does not consume --model when no value follows", () => {
|
|
55
|
+
const result = parseCliArgs(["--model"]);
|
|
56
|
+
// getOption finds --model but no value after it, so it's left in args
|
|
57
|
+
// args.shift() then picks it up as the adapter name
|
|
58
|
+
expect(result.modelOverride).toBeUndefined();
|
|
59
|
+
expect(result.adapterName).toBe("--model");
|
|
60
|
+
});
|
|
61
|
+
it("does not treat --help value as an option value", () => {
|
|
62
|
+
const result = parseCliArgs(["--help", "claude"]);
|
|
63
|
+
expect(result.showHelp).toBe(true);
|
|
64
|
+
expect(result.adapterName).toBe("claude");
|
|
65
|
+
});
|
|
66
|
+
});
|
|
67
|
+
// ── PKG_VERSION ────────────────────────────────────────────────────
|
|
68
|
+
describe("PKG_VERSION", () => {
|
|
69
|
+
it("is a valid semver-like string", () => {
|
|
70
|
+
expect(PKG_VERSION).toMatch(/^\d+\.\d+\.\d+/);
|
|
71
|
+
});
|
|
72
|
+
});
|
|
73
|
+
// ── findTeammatesDir ───────────────────────────────────────────────
|
|
74
|
+
describe("findTeammatesDir", () => {
|
|
75
|
+
let testDir;
|
|
76
|
+
beforeEach(async () => {
|
|
77
|
+
testDir = join(tmpdir(), `cli-args-test-${Date.now()}-${Math.random().toString(36).slice(2)}`);
|
|
78
|
+
await mkdir(testDir, { recursive: true });
|
|
79
|
+
});
|
|
80
|
+
afterEach(async () => {
|
|
81
|
+
await rm(testDir, { recursive: true, force: true });
|
|
82
|
+
});
|
|
83
|
+
it("returns dirOverride when provided", async () => {
|
|
84
|
+
const result = await findTeammatesDir("/some/custom/dir");
|
|
85
|
+
expect(result).toContain("some");
|
|
86
|
+
});
|
|
87
|
+
it("returns .teammates dir when it exists under cwd", async () => {
|
|
88
|
+
const tmDir = join(testDir, ".teammates");
|
|
89
|
+
await mkdir(tmDir, { recursive: true });
|
|
90
|
+
// Mock process.cwd to return our test dir
|
|
91
|
+
const origCwd = process.cwd;
|
|
92
|
+
process.cwd = () => testDir;
|
|
93
|
+
try {
|
|
94
|
+
const result = await findTeammatesDir(undefined);
|
|
95
|
+
expect(result).toBe(tmDir);
|
|
96
|
+
}
|
|
97
|
+
finally {
|
|
98
|
+
process.cwd = origCwd;
|
|
99
|
+
}
|
|
100
|
+
});
|
|
101
|
+
it("returns null when no .teammates dir exists", async () => {
|
|
102
|
+
const origCwd = process.cwd;
|
|
103
|
+
process.cwd = () => testDir;
|
|
104
|
+
try {
|
|
105
|
+
const result = await findTeammatesDir(undefined);
|
|
106
|
+
expect(result).toBeNull();
|
|
107
|
+
}
|
|
108
|
+
finally {
|
|
109
|
+
process.cwd = origCwd;
|
|
110
|
+
}
|
|
111
|
+
});
|
|
112
|
+
});
|
|
113
|
+
// ── printUsage ────────────────────────────────────────────────────
|
|
114
|
+
describe("printUsage", () => {
|
|
115
|
+
it("prints usage text to console", () => {
|
|
116
|
+
const spy = vi.spyOn(console, "log").mockImplementation(() => { });
|
|
117
|
+
printUsage();
|
|
118
|
+
expect(spy).toHaveBeenCalled();
|
|
119
|
+
const output = spy.mock.calls[0][0];
|
|
120
|
+
expect(output).toContain("teammates");
|
|
121
|
+
expect(output).toContain("--model");
|
|
122
|
+
expect(output).toContain("--dir");
|
|
123
|
+
spy.mockRestore();
|
|
124
|
+
});
|
|
125
|
+
});
|