chapterhouse 0.3.6 → 0.3.8

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.
@@ -80,7 +80,16 @@ export async function getSquadCoordinatorSystemMessage(projectRoot) {
80
80
  const teamContent = existsSync(teamMdPath)
81
81
  ? readFileSync(teamMdPath, 'utf-8')
82
82
  : '(not found — create .squad/team.md to provide project charter context)';
83
- // 3. Recent decisionslast ~4000 chars
83
+ // 3. Identity fileswhat the team is focused on and what patterns we use
84
+ const nowMdPath = `${projectRoot}/.squad/identity/now.md`;
85
+ const nowContent = existsSync(nowMdPath)
86
+ ? readFileSync(nowMdPath, 'utf-8')
87
+ : '(not found — create .squad/identity/now.md to share current focus)';
88
+ const wisdomMdPath = `${projectRoot}/.squad/identity/wisdom.md`;
89
+ const wisdomContent = existsSync(wisdomMdPath)
90
+ ? readFileSync(wisdomMdPath, 'utf-8')
91
+ : '(not found — create .squad/identity/wisdom.md to capture team patterns)';
92
+ // 4. Recent decisions — last ~4000 chars
84
93
  const decisionsMdPath = `${projectRoot}/.squad/decisions.md`;
85
94
  let decisionsContent = '(no decisions recorded yet)';
86
95
  if (existsSync(decisionsMdPath)) {
@@ -100,6 +109,14 @@ export async function getSquadCoordinatorSystemMessage(projectRoot) {
100
109
  '',
101
110
  teamContent,
102
111
  '',
112
+ '## Team Current Focus (What We\'re Doing Now)',
113
+ '',
114
+ nowContent,
115
+ '',
116
+ '## Team Wisdom (Patterns & Lessons)',
117
+ '',
118
+ wisdomContent,
119
+ '',
103
120
  '## Recent Decisions',
104
121
  '',
105
122
  decisionsContent,
@@ -1,5 +1,6 @@
1
- import { existsSync, readFileSync, readdirSync, statSync } from 'fs';
1
+ import { existsSync } from 'fs';
2
2
  import { join } from 'path';
3
+ import { FSStorageProvider, SquadState, NotFoundError } from '@bradygaster/squad-sdk';
3
4
  import { getDb } from '../store/db.js';
4
5
  // ---------------------------------------------------------------------------
5
6
  // DB schema — created lazily on first use
@@ -101,47 +102,38 @@ export async function resolveProjectSquad(projectPath) {
101
102
  catch {
102
103
  // SDK not available — use manual path resolution
103
104
  }
104
- // Enumerate agents from .squad/agents/
105
- const agentsDir = join(resolvedSquadDir, 'agents');
105
+ // Enumerate agents from .squad/agents/ via SDK AgentsCollection.
106
+ // FSStorageProvider wraps the same fs calls with typed returns and ENOENT safety.
106
107
  const agents = [];
107
- if (existsSync(agentsDir)) {
108
- let entries = [];
109
- try {
110
- entries = readdirSync(agentsDir);
111
- }
112
- catch { /* ignore read errors */ }
113
- for (const entry of entries) {
114
- const agentDir = join(agentsDir, entry);
115
- try {
116
- if (!statSync(agentDir).isDirectory())
117
- continue;
118
- }
119
- catch {
120
- continue;
121
- }
122
- const charterPath = join(agentDir, 'charter.md');
123
- if (!existsSync(charterPath))
124
- continue;
125
- let charterContent = '';
108
+ const stateRoot = resolvedSquadDir.endsWith('/.squad')
109
+ ? resolvedSquadDir.slice(0, -'/.squad'.length)
110
+ : projectPath;
111
+ try {
112
+ const storage = new FSStorageProvider();
113
+ const state = SquadState.fromStorage(storage, stateRoot);
114
+ const agentNames = await state.agents.list();
115
+ for (const name of agentNames) {
116
+ const charterPath = join(resolvedSquadDir, 'agents', name, 'charter.md');
117
+ let charterContent;
126
118
  try {
127
- charterContent = readFileSync(charterPath, 'utf-8');
119
+ charterContent = await state.agents.get(name).charter();
128
120
  }
129
- catch {
121
+ catch (err) {
122
+ if (err instanceof NotFoundError)
123
+ continue; // no charter.md — not a valid agent
130
124
  continue;
131
125
  }
132
- const slug = entry;
133
- const role = extractRoleFromCharter(charterContent);
134
- const description = extractDescriptionFromCharter(charterContent);
135
126
  agents.push({
136
- slug,
137
- mention: `@${slug}`,
138
- role,
139
- description,
127
+ slug: name,
128
+ mention: `@${name}`,
129
+ role: extractRoleFromCharter(charterContent),
130
+ description: extractDescriptionFromCharter(charterContent),
140
131
  charterPath,
141
132
  origin: 'project-squad',
142
133
  });
143
134
  }
144
135
  }
136
+ catch { /* SDK unavailable — agents list stays empty */ }
145
137
  // Load squad config via SDK with fallback to empty config
146
138
  let squadConfig = {};
147
139
  try {
@@ -228,25 +220,21 @@ export async function loadProjectSquad(projectPath) {
228
220
  : undefined,
229
221
  origin: 'project-squad',
230
222
  }));
231
- // Repo wins: re-sync any new agents that appeared since last cache
232
- const repoAgentsDir = join(row.squad_dir, 'agents');
233
- if (existsSync(repoAgentsDir)) {
234
- const repoDirs = readdirSync(repoAgentsDir).filter(e => {
235
- try {
236
- return statSync(join(repoAgentsDir, e)).isDirectory();
237
- }
238
- catch {
239
- return false;
240
- }
241
- });
223
+ // Repo wins: re-sync any new agents that appeared since last cache.
224
+ // Use SDK AgentsCollection.list() so we stay consistent with resolveProjectSquad().
225
+ try {
226
+ const cacheStorage = new FSStorageProvider();
227
+ const cacheState = SquadState.fromStorage(cacheStorage, row.project_root);
228
+ const repoAgentNames = await cacheState.agents.list();
242
229
  const cachedSlugs = new Set(agents.map(a => a.slug));
243
- for (const slug of repoDirs) {
230
+ for (const slug of repoAgentNames) {
244
231
  if (!cachedSlugs.has(slug)) {
245
232
  // New agent in repo not in cache — trigger full reload
246
233
  return resolveProjectSquad(projectPath);
247
234
  }
248
235
  }
249
236
  }
237
+ catch { /* SDK unavailable — skip new-agent check */ }
250
238
  return {
251
239
  projectRoot: row.project_root,
252
240
  squadDir: row.squad_dir,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "chapterhouse",
3
- "version": "0.3.6",
3
+ "version": "0.3.8",
4
4
  "description": "Chapterhouse — a team-level AI assistant for engineering teams, built on the GitHub Copilot SDK. Web UI only.",
5
5
  "bin": {
6
6
  "chapterhouse": "dist/cli.js"