pi-crew 0.9.26 → 0.9.27
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/CHANGELOG.md +87 -0
- package/NOTICE.md +14 -0
- package/assets/crew-vibes.ttf +0 -0
- package/assets/runner-spritesheet.png +0 -0
- package/dist/build-meta.json +255 -40
- package/dist/index.mjs +1564 -241
- package/dist/index.mjs.map +4 -4
- package/docs/perf/optimization-plan-2026-07-verified.md +396 -0
- package/package.json +9 -2
- package/scripts/bench-check.mjs +96 -0
- package/scripts/bench-cold-start.mjs +216 -0
- package/scripts/build-bundle.mjs +84 -0
- package/scripts/build-crew-vibes-font.py +328 -0
- package/scripts/check-all-skills.ts +294 -0
- package/scripts/check-bundle-staleness.mjs +97 -0
- package/scripts/check-conflict-markers.mjs +91 -0
- package/scripts/check-lazy-imports.mjs +28 -0
- package/scripts/install-crew-vibes-font.mjs +91 -0
- package/scripts/postinstall.mjs +47 -0
- package/scripts/profile-startup.mjs +125 -0
- package/scripts/release-smoke.mjs +74 -0
- package/scripts/run-bench.mjs +47 -0
- package/scripts/run-real-chain.ts +41 -0
- package/scripts/test-issue-29-crash.ts +111 -0
- package/scripts/test-issue-29-e2e.ts +183 -0
- package/scripts/test-issue-29-real-runtime.ts +330 -0
- package/scripts/test-issue-29-real-tasks.ts +387 -0
- package/scripts/test-issue-29-team-tool.ts +105 -0
- package/scripts/test-runner.mjs +74 -0
- package/scripts/verify-flicker-fix.ts +109 -0
- package/scripts/verify-skill.ts +550 -0
- package/scripts/watch-bundle.mjs +259 -0
- package/scripts/watchdog-harness.ts +119 -0
- package/src/agents/discover-agents.ts +6 -1
- package/src/config/defaults.ts +6 -0
- package/src/extension/crew-vibes/cat-frames.ts +18 -0
- package/src/extension/crew-vibes/config.ts +195 -0
- package/src/extension/crew-vibes/figures.ts +94 -0
- package/src/extension/crew-vibes/font-detect.ts +58 -0
- package/src/extension/crew-vibes/index.ts +396 -0
- package/src/extension/crew-vibes/provider-usage.ts +330 -0
- package/src/extension/crew-vibes/render.ts +206 -0
- package/src/extension/crew-vibes/speed.ts +286 -0
- package/src/extension/knowledge-injection.ts +12 -3
- package/src/extension/management.ts +23 -3
- package/src/extension/register.ts +7 -0
- package/src/runtime/child-pi.ts +117 -10
- package/src/runtime/crew-agent-records.ts +10 -3
- package/src/runtime/retry-executor.ts +4 -1
- package/src/runtime/task-runner/state-helpers.ts +9 -30
- package/src/runtime/team-runner.ts +5 -3
- package/src/state/atomic-write.ts +153 -49
- package/src/state/event-log.ts +16 -10
- package/src/state/locks.ts +7 -8
- package/src/state/mailbox.ts +15 -4
- package/src/state/state-store.ts +39 -10
- package/src/teams/discover-teams.ts +56 -1
- package/src/utils/safe-paths.ts +2 -1
- package/src/workflows/discover-workflows.ts +72 -1
|
@@ -198,15 +198,86 @@ function parseDynamicWorkflowFile(filePath: string, source: ResourceSource): Wor
|
|
|
198
198
|
}
|
|
199
199
|
}
|
|
200
200
|
|
|
201
|
+
// ─── Workflow Discovery Cache (F17) ──────────────────────────────────────
|
|
202
|
+
// Mirrors the Agent Discovery Cache pattern (see discover-agents.ts:493-556).
|
|
203
|
+
// `discoverWorkflows(cwd)` is called on the powerbar hot path (≤200 ms coalesce =
|
|
204
|
+
// up to ~5 Hz when a run is active + emitting events). Without caching, each call
|
|
205
|
+
// walks 3 roots, each requiring readdirSync × 2 + readFileSync + regex-parse per
|
|
206
|
+
// `.workflow.md`. We use TTL + dir-stamp invalidation so the cache survives
|
|
207
|
+
// steady-state rendering yet still picks up file changes within a few seconds.
|
|
208
|
+
//
|
|
209
|
+
// SECURITY: ResourceIdentity preserved — same precedence + same parsers as before.
|
|
210
|
+
// Reviewers: there is no path-component concern; this only memoises a pure function
|
|
211
|
+
// of the filesystem state into a process-local Map.
|
|
212
|
+
const WORKFLOW_DISCOVERY_TTL_MS = 5000;
|
|
213
|
+
const WORKFLOW_DISCOVERY_MAX_ENTRIES = 32;
|
|
214
|
+
interface CachedWorkflowEntry {
|
|
215
|
+
result: WorkflowDiscoveryResult;
|
|
216
|
+
expiresAt: number;
|
|
217
|
+
/** mtime tuple of the 3 workflow source dirs; change ⇒ invalidate early. */
|
|
218
|
+
dirStamp: string;
|
|
219
|
+
}
|
|
220
|
+
const workflowCache = new Map<string, CachedWorkflowEntry>();
|
|
221
|
+
|
|
222
|
+
/** Compact mtime signature for the 3 workflow source dirs. Cheap (3 statSync). */
|
|
223
|
+
function workflowDirStamp(cwd: string): string {
|
|
224
|
+
const dirs = [
|
|
225
|
+
path.join(packageRoot(), "workflows"),
|
|
226
|
+
path.join(userPiRoot(), "workflows"),
|
|
227
|
+
path.join(projectCrewRoot(cwd), "workflows"),
|
|
228
|
+
];
|
|
229
|
+
let out = "";
|
|
230
|
+
for (const d of dirs) {
|
|
231
|
+
try {
|
|
232
|
+
const st = fs.statSync(d);
|
|
233
|
+
out += `${st.mtimeMs}|`;
|
|
234
|
+
} catch {
|
|
235
|
+
out += "0|";
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
return out;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
/** Drop one or all cached entries. Called from management actions and tests. */
|
|
242
|
+
export function invalidateWorkflowDiscoveryCache(cwd?: string): void {
|
|
243
|
+
if (cwd) {
|
|
244
|
+
workflowCache.delete(cwd);
|
|
245
|
+
} else {
|
|
246
|
+
workflowCache.clear();
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
|
|
201
250
|
export function discoverWorkflows(cwd: string): WorkflowDiscoveryResult {
|
|
202
251
|
if (!cwd || typeof cwd !== "string") {
|
|
203
252
|
return { builtin: [], user: [], project: [] };
|
|
204
253
|
}
|
|
205
|
-
|
|
254
|
+
// F17: serve from cache when both TTL is fresh AND dir-stamp is unchanged.
|
|
255
|
+
// `dirStamp` is a 3-stat pulse we run on every cached call — it is much
|
|
256
|
+
// cheaper than the disk scan it protects against (3 statSync vs 2 readdirSync
|
|
257
|
+
// + N readFileSync + regex parse per `.workflow.md`).
|
|
258
|
+
const now = Date.now();
|
|
259
|
+
const stamp = workflowDirStamp(cwd);
|
|
260
|
+
const cached = workflowCache.get(cwd);
|
|
261
|
+
if (cached && cached.expiresAt > now && cached.dirStamp === stamp) {
|
|
262
|
+
return cached.result;
|
|
263
|
+
}
|
|
264
|
+
const result: WorkflowDiscoveryResult = {
|
|
206
265
|
builtin: readWorkflowDir(path.join(packageRoot(), "workflows"), "builtin"),
|
|
207
266
|
user: readWorkflowDir(path.join(userPiRoot(), "workflows"), "user"),
|
|
208
267
|
project: readWorkflowDir(path.join(projectCrewRoot(cwd), "workflows"), "project"),
|
|
209
268
|
};
|
|
269
|
+
workflowCache.set(cwd, {
|
|
270
|
+
result,
|
|
271
|
+
expiresAt: now + WORKFLOW_DISCOVERY_TTL_MS,
|
|
272
|
+
dirStamp: stamp,
|
|
273
|
+
});
|
|
274
|
+
// Bounded LRU-ish eviction by insertion order (Map iteration order).
|
|
275
|
+
while (workflowCache.size > WORKFLOW_DISCOVERY_MAX_ENTRIES) {
|
|
276
|
+
const oldest = workflowCache.keys().next().value;
|
|
277
|
+
if (oldest === undefined) break;
|
|
278
|
+
workflowCache.delete(oldest);
|
|
279
|
+
}
|
|
280
|
+
return result;
|
|
210
281
|
}
|
|
211
282
|
|
|
212
283
|
export function allWorkflows(discovery: WorkflowDiscoveryResult | undefined): WorkflowConfig[] {
|