ac-teams 0.0.8 → 0.0.10

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/docs/usage.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Use ac-teams
2
2
 
3
- ac-teams provides three tools without prescribing a workflow. Your Pi session is a main session; the agents it launches are members. The first main session opens coordination state on the first team request. See [main sessions](#main-sessions-share-one-team) for adding more.
3
+ ac-teams provides three tools with lightweight guidance for tracking delegated work. Your Pi session is a main session; the agents it launches are members. The first main session opens coordination state on the first team request. See [main sessions](#main-sessions-share-one-team) for adding more.
4
4
 
5
5
  | Tool | Actions | Main rule |
6
6
  | --- | --- | --- |
@@ -68,12 +68,27 @@ Hiding a display does not stop agents, change tasks, or disable `/teams`. With t
68
68
 
69
69
  ## Give members bounded assignments
70
70
 
71
- Example `team_agent` arguments:
71
+ Before delegating a deliverable, create or reuse a shared task and include its ID in the member's brief. Track independently owned outcomes, not every agent, tool call, or procedural step. For example:
72
+
73
+ - A fix and an independently owned test assignment need separate tasks.
74
+ - A diagnosis others need for follow-up needs a task, even if the investigation is read-only.
75
+ - A quick lookup, clarification, or brief second opinion can skip a task unless its result needs coordination or follow-up.
76
+ - Running tests as part of a fix usually belongs to the fix's existing task.
77
+
78
+ Review the current task list and relevant details first. Reuse an existing task when it covers the assignment. If none does, create one with acceptance criteria. Example `team_task` arguments:
79
+
80
+ ```json
81
+ {"action":"create","label":"Parser review","title":"Review parser errors and malformed input","description":"Read-only review of src/parser.ts. Acceptance: report concrete malformed-input failures with reproduction steps, or report that none were found."}
82
+ ```
83
+
84
+ Put the returned task UUID in the brief in place of `<task-id>`. Example `team_agent` arguments:
72
85
 
73
86
  ```json
74
- {"action":"launch","name":"parser-review","brief":"Review src/parser.ts. Read only; do not delegate or edit. Send findings to root through team_message."}
87
+ {"action":"launch","name":"parser-review","brief":"Task <task-id>: claim and start it, then review src/parser.ts. Read only; do not delegate or edit. Send findings to root through team_message. Complete the task after checking its acceptance criteria, or report blockers."}
75
88
  ```
76
89
 
90
+ These are prompt guidelines, not launch requirements. ac-teams neither creates tasks automatically nor blocks launches without tasks.
91
+
77
92
  Every launch needs a unique descriptive `name`: one or two lowercase words, hyphenated if two, at most 40 characters. For example, `parser-review` or `research`. `main`, `root`, and names matching an existing member's ID are reserved. Names remain stable across stop/resume; IDs remain the API references.
78
93
 
79
94
  `cwd` defaults to the requesting member's directory. `model` (`provider/model`) and `thinking` default to that member's current selection. An explicit override wins. Native Pi selects the model; provider/account rejections remain visible in member status and notify the parent. There is no automatic model retry.
@@ -86,11 +101,7 @@ Children can delegate through the same coordinator, subject to depth and capacit
86
101
 
87
102
  ## Track progress separately from ownership
88
103
 
89
- Example `team_task` arguments:
90
-
91
- ```json
92
- {"action":"create","label":"Parser review","title":"Review parser errors and malformed input","description":"Check malformed input and report concrete failures; no edits."}
93
- ```
104
+ Task owners claim and start their work, then complete it after checking acceptance criteria or report blockers. Claiming reserves a task; starting also requires its dependencies to be done.
94
105
 
95
106
  Each task has a stable team-local `number` and a 1–3-word `label` (at most 60 characters). The graph and list show `#3 Parser review`; details retain the full title, description, and UUID.
96
107
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ac-teams",
3
- "version": "0.0.8",
3
+ "version": "0.0.10",
4
4
  "description": "Small, persistent teams for Pi",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -20,7 +20,7 @@ import { launchMain, mainEnv, teamEntryType, handoverPrompt, type MainLaunch, ty
20
20
  import { canControl, isDescendant, isLive, isMain, memberName, taskName, type AgentArgs, type Member, type MessageArgs, type TaskArgs, type TeamState, type UserAction, type Message, type ContextUsage } from "./types.ts";
21
21
 
22
22
  export const taskRequestGuidance = [
23
- "Treat user task requests as proposals to assess, not commands to create tasks.",
23
+ "Assess user task requests against the agreed scope and existing work before changing shared tasks.",
24
24
  "Review the agreed scope and current task list (page as needed); read relevant descriptions, acceptance criteria, statuses, owners, and dependencies.",
25
25
  "If an existing task already covers the request, cite its number/name and explain why; do not add a duplicate.",
26
26
  "If a coherent extension is the smallest complete solution, update the existing task only when its state and ownership allow it; otherwise coordinate with its owner.",
package/src/index.ts CHANGED
@@ -274,25 +274,34 @@ export default function teams(pi: ExtensionAPI) {
274
274
  });
275
275
  function output(data: unknown) { return { content: [{ type: "text" as const, text: JSON.stringify(data) }], details: data }; }
276
276
  const guidance = "Team launches use real long-lived Pi sessions. Idle members count against the shared ceiling. Use stable member/task IDs; query status and history instead of acknowledging notifications. Limits cover only ac-teams, not other launchers or shell commands.";
277
+ const taskTrackingGuidance = "Before delegating a deliverable through team_agent, create or reuse a team_task and include its ID in the member's brief. Track independently owned outcomes, not tool calls or procedural steps; do not create one task per teammate by default. Skip tasks for quick lookups, clarification, and brief second opinions unless results need coordination or follow-up. Task owners claim and start their work, then complete it after checking acceptance criteria or report blockers.";
277
278
  pi.registerTool({
278
- name: "team_agent", label: "Team agent", description: "Launch/resume Pi members, list/status, stop owned subtrees, change root limits, and explicitly clean stopped worktrees.",
279
- promptGuidelines: [guidance, "Delegation needs the user's authorization. Give each new member a unique descriptive name (one or two lowercase words, hyphenated if two), plus a bounded brief. Names remain stable on resume. Avoid concurrent writers in the same cwd. Worktrees are opt-in."],
279
+ name: "team_agent", label: "Team agent", description: "Launch/resume Pi members, list/status, stop owned subtrees, change root limits, and explicitly clean stopped worktrees. Create or reuse team_task entries for delegated deliverables; quick lookups need no task unless results need coordination or follow-up.",
280
+ promptGuidelines: [guidance, taskTrackingGuidance, "Delegation needs the user's authorization. Give each new member a unique descriptive name (one or two lowercase words, hyphenated if two), plus a bounded brief. Names remain stable on resume. Avoid concurrent writers in the same cwd. Worktrees are opt-in."],
280
281
  parameters: AgentSchema,
281
282
  ...teamToolRenderers("team_agent"),
282
283
  async execute(_id, args, _signal, _update, ctx) { return output(await handle("agent", args, ctx)); },
283
284
  });
284
285
  pi.registerTool({
285
- name: "team_task", label: "Team task", description: "Manage shared tasks: create/list/read/edit, claim a reservation, start work, complete, release ownership, or explicitly reopen. Progress is todo/in_progress/done; blockedBy is derived from unfinished dependencies. Mutations support revision checks.",
286
- promptGuidelines: [taskRequestGuidance, "Give every task a concise 1–3-word label, alongside its full title and acceptance criteria. Stable team-local numbers are assigned automatically; use UUIDs for API references. Interim and final goals are ordinary tasks. Add dependencies only for real prerequisites, never merely to connect the diagram.", "Claim reserves a to-do task even if blocked; start requires ownership and all dependencies done. Complete requires in-progress work and acceptance=true after checking the criteria. Release clears ownership, returns in-progress work to todo, and leaves done work done. Reopen is explicit and cannot invalidate active or done dependents."],
286
+ name: "team_task", label: "Team task", description: "Track delegated deliverables, not every agent or action. Create or reuse tasks before delegation; quick lookups need no task unless results need coordination or follow-up. Manage shared tasks: create/list/read/edit, claim a reservation, start work, complete, release ownership, or explicitly reopen. Progress is todo/in_progress/done; blockedBy is derived from unfinished dependencies. Mutations support revision checks.",
287
+ promptGuidelines: [taskTrackingGuidance, taskRequestGuidance, "Give every task a concise 1–3-word label, alongside its full title and acceptance criteria. Stable team-local numbers are assigned automatically; use UUIDs for API references. Interim and final goals are ordinary tasks. Add dependencies only for real prerequisites, never merely to connect the diagram.", "Claim reserves a to-do task even if blocked; start requires ownership and all dependencies done. Complete requires in-progress work and acceptance=true after checking the criteria. Release clears ownership, returns in-progress work to todo, and leaves done work done. Reopen is explicit and cannot invalidate active or done dependents."],
287
288
  parameters: TaskSchema,
288
289
  ...teamToolRenderers("team_task"),
289
290
  async execute(_id, args, _signal, _update, ctx) { return output(await handle("task", args, ctx)); },
290
291
  });
291
292
  pi.registerTool({
292
- name: "team_message", label: "Team message", description: "Send a persistent direct/team message or read cursor-paged history. New messages queue a compact follow-up notification for each recipient.",
293
+ name: "team_message", label: "Team message", description: "Send a persistent direct/team message or read cursor-paged history. Send returns a receipt; history and search return full messages. New messages queue a compact follow-up notification for each recipient.",
294
+ promptGuidelines: ["Do not poll team_message history while waiting for replies; notifications trigger a follow-up turn. On notification, read team_message history after your last read cursor and advance it through the returned messages. An empty result means no newer messages, not that a teammate has finished."],
293
295
  parameters: MessageSchema,
294
296
  ...teamToolRenderers("team_message"),
295
- async execute(_id, args, _signal, _update, ctx) { return output(await handle("message", args, ctx)); },
297
+ async execute(_id, args, _signal, _update, ctx) {
298
+ const result = await handle("message", args, ctx);
299
+ if (args.action === "send") {
300
+ const { seq, id, recipients } = result as Message;
301
+ return output({ seq, id, recipients });
302
+ }
303
+ return output(result);
304
+ },
296
305
  });
297
306
  async function close() {
298
307
  exiting = true;