@tablation/crew 0.37.0 → 0.38.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 CHANGED
@@ -36,13 +36,19 @@ prompt set (the three-lane dev/design/QA policy this repo ships with — see
36
36
  A fifth persona, **pair**, rides `crew agents sync` alongside these four but
37
37
  is not polled: it is the identity a live, interactive session (an IDE
38
38
  conversation, not a scheduled run) uses when it touches the tracker. It has
39
- no Crew-table seat, is never assigned a ticket by the poll loop, and its
40
- brief (`prompts/default/personas/lane-pair.md`) is not prefixed with
41
- `common.md` — none of the polling loop's shared policy describes it. `crew
39
+ no Crew-table seat and is never assigned a ticket by the poll loop. `crew
42
40
  agents prompt pair` prints its current persona text (a workspace admin's
43
41
  live edit if there is one, else the local default) for something like a
44
42
  `SessionStart` hook to feed into a session at start.
45
43
 
44
+ `common.md` — the building lanes' shared policy (worktrees, one stateless
45
+ invocation per cycle, the dev/design/QA hand-off) — is prefixed to the
46
+ **dev**, **design** and **qa** briefs only. **triage** and **pair** are
47
+ self-contained (`SELF_CONTAINED_ROLES` in `src/config.ts`): neither cuts a
48
+ worktree, builds or hands anything to QA, so the policy would only
49
+ misdescribe them. The prompts carry rules, not history; the incidents behind
50
+ each rule are kept in [`docs/prompt-rationale.md`](docs/prompt-rationale.md).
51
+
46
52
  Alongside personas, a prompt set can also ship **skills** —
47
53
  `prompts/<promptSet>/skills/*.md`, each one YAML frontmatter (`name`,
48
54
  `description`) plus a markdown prompt body. A skill isn't a seat: it's not
@@ -55,7 +61,14 @@ diverged sync narrowed to skills alone, for when you've only touched
55
61
  `skills/`. Example use — a Pair session invoked via an Epic's
56
62
  `grill_link` looks up the `Grill-Me` skill through the Tablation MCP tool
57
63
  `agent_skills_controller_get_skill` and follows it. `prompts/default/skills/
58
- grill-me.md` is the shipped example.
64
+ grill-me.md` is one shipped example; the rest are the building lanes'
65
+ situational procedures (`Worktree Setup`, `Running the Suite`, `Question and
66
+ Investigation Tickets`, `Filing a Ticket`, `Ticket Attachments`, `Workspace
67
+ Change Authorization`, `Design Pass`), which `common.md` names at the step
68
+ that needs each one — every run keeps the rule and the minimum inline and
69
+ fetches the full procedure only when it applies, so a dev run that never
70
+ files a ticket never pays for the filing procedure. `test/prompts.test.ts`
71
+ checks that every skill a persona names ships in the same preset.
59
72
 
60
73
  One role runs per cycle, whichever holds the most urgent actionable ticket
61
74
  (`src/priority.ts` decides, and the same module sorts the digest that agent is
@@ -100,10 +113,12 @@ edit its prose, and point `promptSet` at the copy (`~/my-crew-policy` or a
100
113
  relative path) — no fork of this repo required. A prompt set is a complete,
101
114
  self-contained fork of `personas/common.md` + one `personas/lane-<role>.md`
102
115
  per seat, plus whatever `skills/*.md` it wants, not a diff against another
103
- one; each persona file is read as plain prose concatenated ahead of the
104
- per-run roster/environment/queue sections
116
+ one; each persona file is read as plain prose (common.md ahead of a building
117
+ lane's brief, a self-contained brief alone) and concatenated after the
118
+ per-run roster/environment sections and before the queue digest
105
119
  (`src/agent.ts`'s `assemblePrompt`), so there's no templating layer to
106
- learn. `prompts/dev-qa/` is a worked example of trimming a lane out of
120
+ learn. Keep the prose generic: `test/prompts.test.ts` fails a preset that
121
+ names a path, a command, an id, a ticket reference or a date. `prompts/dev-qa/` is a worked example of trimming a lane out of
107
122
  `default` cleanly, including the unused `lane-design.md` stub every
108
123
  preset still needs today — see the next paragraph for why.
109
124
 
package/dist/cli.js CHANGED
@@ -1806,6 +1806,7 @@ var DEFAULT_BASE_URL = "https://app.tablation.com";
1806
1806
  var DEFAULT_MAX_THINKING_TOKENS = 4096;
1807
1807
  var DEFAULT_REPOS_BASE_PATH = "~/Crew";
1808
1808
  var ROLE_NAMES = ["dev", "design", "qa", "triage", "pair"];
1809
+ var SELF_CONTAINED_ROLES = /* @__PURE__ */ new Set(["pair", "triage"]);
1809
1810
  var ROLE_LABEL = {
1810
1811
  dev: "Dev",
1811
1812
  design: "Design",
@@ -7011,7 +7012,8 @@ function planAgentRun(o) {
7011
7012
  throw new AgentError(`no brief at ${briefPath} \u2014 refusing to run an unscoped session`);
7012
7013
  }
7013
7014
  const commonPath = join10(o.route.promptsDir, "personas", "common.md");
7014
- if (!existsSync9(commonPath)) throw new AgentError(`no shared policy at ${commonPath}`);
7015
+ const usesCommon = !SELF_CONTAINED_ROLES.has(o.role);
7016
+ if (usesCommon && !existsSync9(commonPath)) throw new AgentError(`no shared policy at ${commonPath}`);
7015
7017
  const now = o.now ?? (() => Date.now());
7016
7018
  const routeLabel = routeSlug(o.route.route);
7017
7019
  const digestPath2 = join10(o.stateDir, `digest-${routeLabel}-${o.role}.md`);
@@ -7021,7 +7023,7 @@ function planAgentRun(o) {
7021
7023
  ageSeconds = Math.floor((now() - statSync5(digestPath2).mtimeMs) / 1e3);
7022
7024
  if (ageSeconds <= DIGEST_MAX_AGE_SECONDS) digest = readFileSync8(digestPath2, "utf8");
7023
7025
  }
7024
- const common = readFileSync8(commonPath, "utf8");
7026
+ const common = usesCommon ? readFileSync8(commonPath, "utf8") : "";
7025
7027
  const brief = readFileSync8(briefPath, "utf8");
7026
7028
  const effectiveCommon = o.divergedPrompt ? "" : common;
7027
7029
  const effectiveBrief = o.divergedPrompt ?? brief;
@@ -9385,7 +9387,7 @@ var AgentsSyncError = class extends Error {
9385
9387
  function personaDefaultPrompt(promptsDir, role) {
9386
9388
  const briefPath = join15(promptsDir, "personas", `lane-${role}.md`);
9387
9389
  if (!existsSync15(briefPath)) throw new AgentsSyncError(`no brief at ${briefPath}`);
9388
- if (role === "pair") return readFileSync10(briefPath, "utf8");
9390
+ if (SELF_CONTAINED_ROLES.has(role)) return readFileSync10(briefPath, "utf8");
9389
9391
  const commonPath = join15(promptsDir, "personas", "common.md");
9390
9392
  if (!existsSync15(commonPath)) throw new AgentsSyncError(`no shared policy at ${commonPath}`);
9391
9393
  return `${readFileSync10(commonPath, "utf8")}${readFileSync10(briefPath, "utf8")}`;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tablation/crew",
3
- "version": "0.37.0",
3
+ "version": "0.38.0",
4
4
  "description": "A standing team of headless agents that picks work off a Tablation board, does it on a machine you control, and reports back.",
5
5
  "type": "module",
6
6
  "license": "MIT",