@teammates/cli 0.3.4 → 0.4.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 +1 -1
- package/dist/adapter.d.ts +14 -1
- package/dist/adapter.js +131 -125
- package/dist/adapter.test.js +75 -0
- package/dist/adapters/cli-proxy.js +12 -11
- package/dist/adapters/copilot.js +11 -11
- package/dist/adapters/echo.test.js +1 -0
- package/dist/banner.d.ts +6 -1
- package/dist/banner.js +18 -3
- package/dist/cli-args.js +0 -1
- package/dist/cli.js +671 -270
- package/dist/console/startup.d.ts +2 -1
- package/dist/console/startup.js +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/orchestrator.d.ts +2 -0
- package/dist/orchestrator.js +15 -12
- package/dist/orchestrator.test.js +2 -1
- package/dist/registry.js +7 -0
- package/dist/registry.test.js +1 -0
- package/dist/types.d.ts +10 -0
- package/package.json +3 -3
|
@@ -8,7 +8,8 @@
|
|
|
8
8
|
export declare function buildTitle(word: string): [string, string];
|
|
9
9
|
export interface StartupInfo {
|
|
10
10
|
version: string;
|
|
11
|
-
|
|
11
|
+
/** Display name shown in the banner (user alias or adapter name). */
|
|
12
|
+
displayName: string;
|
|
12
13
|
teammateCount: number;
|
|
13
14
|
cwd: string;
|
|
14
15
|
recallInstalled: boolean;
|
package/dist/console/startup.js
CHANGED
|
@@ -80,7 +80,7 @@ export async function playStartup(info) {
|
|
|
80
80
|
const tmWidth = tmTop.length; // "▀█▀ █▀▄▀█" = 9 chars
|
|
81
81
|
const gap = " ";
|
|
82
82
|
// Build info lines to sit to the right of TM
|
|
83
|
-
const rightLine1 = chalk.white(info.
|
|
83
|
+
const rightLine1 = chalk.white(info.displayName) +
|
|
84
84
|
chalk.gray(` · ${info.teammateCount} teammate${info.teammateCount === 1 ? "" : "s"}`) +
|
|
85
85
|
chalk.gray(` · v${info.version}`);
|
|
86
86
|
const rightLine2 = chalk.gray(info.cwd);
|
package/dist/index.d.ts
CHANGED
|
@@ -9,4 +9,4 @@ export { findTeammatesDir, PKG_VERSION, parseCliArgs } from "./cli-args.js";
|
|
|
9
9
|
export { Orchestrator, type OrchestratorConfig, type TeammateStatus, } from "./orchestrator.js";
|
|
10
10
|
export { Registry } from "./registry.js";
|
|
11
11
|
export { tp } from "./theme.js";
|
|
12
|
-
export type { DailyLog, HandoffEnvelope, OrchestratorEvent, OwnershipRules, QueueEntry, SandboxLevel, SlashCommand, TaskAssignment, TaskResult, TeammateConfig, } from "./types.js";
|
|
12
|
+
export type { DailyLog, HandoffEnvelope, OrchestratorEvent, OwnershipRules, PresenceState, QueueEntry, SandboxLevel, SlashCommand, TaskAssignment, TaskResult, TeammateConfig, TeammateType, } from "./types.js";
|
package/dist/orchestrator.d.ts
CHANGED
|
@@ -19,6 +19,8 @@ export interface OrchestratorConfig {
|
|
|
19
19
|
}
|
|
20
20
|
export interface TeammateStatus {
|
|
21
21
|
state: "idle" | "working";
|
|
22
|
+
/** Presence for display: online (green), offline (red), reachable (yellow) */
|
|
23
|
+
presence: import("./types.js").PresenceState;
|
|
22
24
|
lastSummary?: string;
|
|
23
25
|
lastChangedFiles?: string[];
|
|
24
26
|
lastTimestamp?: Date;
|
package/dist/orchestrator.js
CHANGED
|
@@ -20,7 +20,10 @@ export class Orchestrator {
|
|
|
20
20
|
async init() {
|
|
21
21
|
await this.registry.loadAll();
|
|
22
22
|
for (const name of this.registry.list()) {
|
|
23
|
-
this.
|
|
23
|
+
const config = this.registry.get(name);
|
|
24
|
+
// AI teammates are always online; humans start as offline
|
|
25
|
+
const presence = config?.type === "human" ? "offline" : "online";
|
|
26
|
+
this.statuses.set(name, { state: "idle", presence });
|
|
24
27
|
}
|
|
25
28
|
}
|
|
26
29
|
/** Get status for a teammate */
|
|
@@ -59,7 +62,8 @@ export class Orchestrator {
|
|
|
59
62
|
};
|
|
60
63
|
}
|
|
61
64
|
this.onEvent({ type: "task_assigned", assignment });
|
|
62
|
-
this.statuses.
|
|
65
|
+
const prevPresence = this.statuses.get(assignment.teammate)?.presence ?? "online";
|
|
66
|
+
this.statuses.set(assignment.teammate, { state: "working", presence: prevPresence });
|
|
63
67
|
// Get or create session
|
|
64
68
|
let sessionId = this.sessions.get(assignment.teammate);
|
|
65
69
|
if (!sessionId) {
|
|
@@ -74,9 +78,11 @@ export class Orchestrator {
|
|
|
74
78
|
// Execute
|
|
75
79
|
const result = await this.adapter.executeTask(sessionId, teammate, prompt);
|
|
76
80
|
this.onEvent({ type: "task_completed", result });
|
|
77
|
-
// Update status
|
|
81
|
+
// Update status (preserve presence)
|
|
82
|
+
const postPresence = this.statuses.get(assignment.teammate)?.presence ?? "online";
|
|
78
83
|
this.statuses.set(assignment.teammate, {
|
|
79
84
|
state: "idle",
|
|
85
|
+
presence: postPresence,
|
|
80
86
|
lastSummary: result.summary,
|
|
81
87
|
lastChangedFiles: result.changedFiles,
|
|
82
88
|
lastTimestamp: new Date(),
|
|
@@ -128,7 +134,7 @@ export class Orchestrator {
|
|
|
128
134
|
}
|
|
129
135
|
}
|
|
130
136
|
// Require a meaningful match — weak/ambiguous scores fall through
|
|
131
|
-
// so the caller can default to the
|
|
137
|
+
// so the caller can default to the user's agent
|
|
132
138
|
if (bestScore < 2)
|
|
133
139
|
return null;
|
|
134
140
|
return bestMatch;
|
|
@@ -144,12 +150,6 @@ export class Orchestrator {
|
|
|
144
150
|
for (const [name, config] of this.registry.all()) {
|
|
145
151
|
roster.push({ name, role: config.role, ownership: config.ownership });
|
|
146
152
|
}
|
|
147
|
-
// Include the base agent as an option
|
|
148
|
-
roster.push({
|
|
149
|
-
name: this.adapter.name,
|
|
150
|
-
role: "General-purpose coding agent",
|
|
151
|
-
ownership: { primary: [], secondary: [] },
|
|
152
|
-
});
|
|
153
153
|
return this.adapter.routeTask(task, roster);
|
|
154
154
|
}
|
|
155
155
|
/**
|
|
@@ -162,7 +162,9 @@ export class Orchestrator {
|
|
|
162
162
|
const added = [];
|
|
163
163
|
for (const name of this.registry.list()) {
|
|
164
164
|
if (!before.has(name)) {
|
|
165
|
-
this.
|
|
165
|
+
const config = this.registry.get(name);
|
|
166
|
+
const presence = config?.type === "human" ? "offline" : "online";
|
|
167
|
+
this.statuses.set(name, { state: "idle", presence });
|
|
166
168
|
added.push(name);
|
|
167
169
|
}
|
|
168
170
|
}
|
|
@@ -177,7 +179,8 @@ export class Orchestrator {
|
|
|
177
179
|
}
|
|
178
180
|
this.sessions.clear();
|
|
179
181
|
for (const name of this.registry.list()) {
|
|
180
|
-
this.statuses.
|
|
182
|
+
const prevPresence = this.statuses.get(name)?.presence ?? "online";
|
|
183
|
+
this.statuses.set(name, { state: "idle", presence: prevPresence });
|
|
181
184
|
}
|
|
182
185
|
}
|
|
183
186
|
/** Destroy all sessions */
|
|
@@ -3,6 +3,7 @@ import { Orchestrator } from "./orchestrator.js";
|
|
|
3
3
|
function makeTeammate(name, role = "Test role.", primary = []) {
|
|
4
4
|
return {
|
|
5
5
|
name,
|
|
6
|
+
type: "ai",
|
|
6
7
|
role,
|
|
7
8
|
soul: `# ${name}\n\n${role}`,
|
|
8
9
|
wisdom: "",
|
|
@@ -45,7 +46,7 @@ function createOrchestrator(teammates, adapter, onEvent) {
|
|
|
45
46
|
}
|
|
46
47
|
// Initialize statuses
|
|
47
48
|
for (const t of teammates) {
|
|
48
|
-
orch.getAllStatuses().set(t.name, { state: "idle" });
|
|
49
|
+
orch.getAllStatuses().set(t.name, { state: "idle", presence: "online" });
|
|
49
50
|
}
|
|
50
51
|
return { orch, adapter: mockAdapter };
|
|
51
52
|
}
|
package/dist/registry.js
CHANGED
|
@@ -46,8 +46,10 @@ export class Registry {
|
|
|
46
46
|
const ownership = parseOwnership(soul);
|
|
47
47
|
const role = parseRole(soul);
|
|
48
48
|
const routingKeywords = parseRoutingKeywords(soul);
|
|
49
|
+
const type = parseType(soul);
|
|
49
50
|
const config = {
|
|
50
51
|
name,
|
|
52
|
+
type,
|
|
51
53
|
role,
|
|
52
54
|
soul,
|
|
53
55
|
wisdom,
|
|
@@ -183,6 +185,11 @@ function parseRoutingKeywords(soul) {
|
|
|
183
185
|
return [];
|
|
184
186
|
return extractPatterns(routingMatch[0]);
|
|
185
187
|
}
|
|
188
|
+
/** Parse type (human or ai) from SOUL.md — looks for **Type:** human */
|
|
189
|
+
function parseType(soul) {
|
|
190
|
+
const match = soul.match(/\*\*Type:\*\*\s*(human|ai)/i);
|
|
191
|
+
return match && match[1].toLowerCase() === "human" ? "human" : "ai";
|
|
192
|
+
}
|
|
186
193
|
/** Extract file patterns (backtick-wrapped) from a markdown section */
|
|
187
194
|
function extractPatterns(section) {
|
|
188
195
|
const patterns = [];
|
package/dist/registry.test.js
CHANGED
package/dist/types.d.ts
CHANGED
|
@@ -3,10 +3,16 @@
|
|
|
3
3
|
*/
|
|
4
4
|
/** Sandbox level controlling what a teammate can do */
|
|
5
5
|
export type SandboxLevel = "read-only" | "workspace-write" | "danger-full-access";
|
|
6
|
+
/** Whether this teammate is a human avatar or an AI agent */
|
|
7
|
+
export type TeammateType = "human" | "ai";
|
|
8
|
+
/** Presence state for /status display */
|
|
9
|
+
export type PresenceState = "online" | "offline" | "reachable";
|
|
6
10
|
/** A teammate's loaded configuration */
|
|
7
11
|
export interface TeammateConfig {
|
|
8
12
|
/** Teammate name (folder name under .teammates/) */
|
|
9
13
|
name: string;
|
|
14
|
+
/** Whether this is a human avatar or AI teammate */
|
|
15
|
+
type: TeammateType;
|
|
10
16
|
/** Role description from SOUL.md */
|
|
11
17
|
role: string;
|
|
12
18
|
/** Full SOUL.md content */
|
|
@@ -124,6 +130,10 @@ export type QueueEntry = {
|
|
|
124
130
|
type: "debug";
|
|
125
131
|
teammate: string;
|
|
126
132
|
task: string;
|
|
133
|
+
} | {
|
|
134
|
+
type: "summarize";
|
|
135
|
+
teammate: string;
|
|
136
|
+
task: string;
|
|
127
137
|
};
|
|
128
138
|
/** A registered slash command. */
|
|
129
139
|
export interface SlashCommand {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@teammates/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.1",
|
|
4
4
|
"description": "Agent-agnostic CLI for teammates. Routes tasks, manages handoffs, and plugs into any coding agent backend.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -33,8 +33,8 @@
|
|
|
33
33
|
"license": "MIT",
|
|
34
34
|
"dependencies": {
|
|
35
35
|
"@github/copilot-sdk": "^0.1.32",
|
|
36
|
-
"@teammates/consolonia": "0.
|
|
37
|
-
"@teammates/recall": "0.
|
|
36
|
+
"@teammates/consolonia": "0.4.0",
|
|
37
|
+
"@teammates/recall": "0.4.0",
|
|
38
38
|
"chalk": "^5.6.2",
|
|
39
39
|
"ora": "^9.3.0"
|
|
40
40
|
},
|