pi-crew 0.5.1 → 0.5.2
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 +28 -0
- package/README.md +1 -1
- package/docs/actions-reference.md +87 -0
- package/docs/commands-reference.md +5 -0
- package/docs/pi-crew-bugs.md +6 -0
- package/index.ts +1 -1
- package/package.json +18 -16
- package/src/benchmark/benchmark-runner.ts +245 -0
- package/src/benchmark/feedback-loop.ts +66 -0
- package/src/extension/async-notifier.ts +1 -1
- package/src/extension/autonomous-policy.ts +1 -1
- package/src/extension/cross-extension-rpc.ts +1 -1
- package/src/extension/plan-orchestrate.ts +322 -0
- package/src/extension/register.ts +31 -41
- package/src/extension/registration/command-utils.ts +1 -1
- package/src/extension/registration/commands.ts +1 -1
- package/src/extension/registration/compaction-guard.ts +1 -1
- package/src/extension/registration/subagent-helpers.ts +1 -1
- package/src/extension/registration/subagent-tools.ts +1 -1
- package/src/extension/registration/team-tool.ts +1 -1
- package/src/extension/registration/viewers.ts +1 -1
- package/src/extension/session-summary.ts +1 -1
- package/src/extension/team-manager-command.ts +1 -1
- package/src/extension/team-tool/context.ts +1 -1
- package/src/extension/team-tool/handle-schedule.ts +183 -0
- package/src/extension/team-tool/orchestrate.ts +102 -0
- package/src/extension/team-tool/run.ts +215 -28
- package/src/extension/team-tool.ts +10 -0
- package/src/extension/tool-result.ts +1 -1
- package/src/i18n.ts +1 -1
- package/src/observability/event-to-metric.ts +1 -1
- package/src/prompt/prompt-runtime.ts +1 -1
- package/src/runtime/background-runner.ts +27 -5
- package/src/runtime/crash-recovery.ts +1 -1
- package/src/runtime/crew-hooks.ts +240 -0
- package/src/runtime/custom-tools/irc-tool.ts +1 -1
- package/src/runtime/custom-tools/submit-result-tool.ts +1 -1
- package/src/runtime/diagnostic-export.ts +38 -2
- package/src/runtime/foreground-watchdog.ts +1 -1
- package/src/runtime/live-session-runtime.ts +1 -1
- package/src/runtime/mcp-proxy.ts +1 -1
- package/src/runtime/pi-spawn.ts +20 -4
- package/src/runtime/process-status.ts +15 -2
- package/src/runtime/runtime-resolver.ts +1 -1
- package/src/runtime/session-resources.ts +1 -1
- package/src/runtime/task-runner.ts +31 -1
- package/src/runtime/team-runner.ts +6 -0
- package/src/schema/team-tool-schema.ts +24 -1
- package/src/state/crew-init.ts +56 -38
- package/src/state/decision-ledger.ts +295 -0
- package/src/state/hook-instinct-bridge.ts +90 -0
- package/src/state/hook-integrations.ts +51 -0
- package/src/state/instinct-store.ts +249 -0
- package/src/state/run-metrics.ts +135 -0
- package/src/state/tiered-eval.ts +471 -0
- package/src/state/types-eval.ts +58 -0
- package/src/state/types.ts +3 -0
- package/src/tools/safe-bash-extension.ts +5 -5
- package/src/ui/crew-widget.ts +1 -1
- package/src/ui/pi-ui-compat.ts +1 -1
- package/src/ui/run-action-dispatcher.ts +1 -1
- package/src/ui/tool-render.ts +2 -2
- package/src/utils/project-detector.ts +160 -0
- package/test-bugs-all.mjs +1 -1
- package/skills/.gitkeep +0 -0
- package/skills/REFERENCE.md +0 -136
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
import { execSync } from "node:child_process";
|
|
3
|
+
import * as fs from "node:fs";
|
|
4
|
+
import * as path from "node:path";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Information about a detected project.
|
|
8
|
+
*/
|
|
9
|
+
export interface ProjectInfo {
|
|
10
|
+
projectId: string;
|
|
11
|
+
projectName: string;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Create a SHA256 hash of a string, returning the first 16 characters.
|
|
16
|
+
*/
|
|
17
|
+
function hashPath(input: string): string {
|
|
18
|
+
return createHash("sha256").update(input).digest("hex").slice(0, 16);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Extract the repository name from a git remote URL.
|
|
23
|
+
* Handles formats like:
|
|
24
|
+
* - https://github.com/user/repo.git
|
|
25
|
+
* - https://github.com/user/repo
|
|
26
|
+
* - git@github.com:user/repo.git
|
|
27
|
+
* - ssh://git@github.com/user/repo.git
|
|
28
|
+
*/
|
|
29
|
+
function extractRepoName(remoteUrl: string): string | null {
|
|
30
|
+
// Remove .git suffix
|
|
31
|
+
const withoutGit = remoteUrl.replace(/\.git$/, "");
|
|
32
|
+
|
|
33
|
+
// Handle SSH format: git@github.com:user/repo
|
|
34
|
+
const sshMatch = withoutGit.match(/^git@[^:]+:(.+)$/);
|
|
35
|
+
if (sshMatch) {
|
|
36
|
+
const parts = sshMatch[1].split("/");
|
|
37
|
+
return parts[parts.length - 1] ?? null;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// Handle HTTPS/HTTP/SSH URL format
|
|
41
|
+
try {
|
|
42
|
+
const url = new URL(withoutGit);
|
|
43
|
+
const pathParts = url.pathname.split("/").filter(Boolean);
|
|
44
|
+
return pathParts[pathParts.length - 1] ?? null;
|
|
45
|
+
} catch {
|
|
46
|
+
// Not a valid URL, try to extract from path-like string
|
|
47
|
+
const parts = withoutGit.split("/").filter(Boolean);
|
|
48
|
+
return parts[parts.length - 1] ?? null;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Try to get the repository name from git remote origin.
|
|
54
|
+
*/
|
|
55
|
+
function tryGitRemote(cwd: string): string | null {
|
|
56
|
+
try {
|
|
57
|
+
const remoteUrl = execSync("git remote get-url origin", {
|
|
58
|
+
cwd,
|
|
59
|
+
encoding: "utf-8",
|
|
60
|
+
stdio: ["pipe", "pipe", "ignore"],
|
|
61
|
+
}).trim();
|
|
62
|
+
|
|
63
|
+
if (!remoteUrl) return null;
|
|
64
|
+
|
|
65
|
+
const repoName = extractRepoName(remoteUrl);
|
|
66
|
+
if (!repoName) return null;
|
|
67
|
+
|
|
68
|
+
// Verify it's a valid directory name (no path traversal attempts)
|
|
69
|
+
if (repoName.includes("..") || repoName.includes("/")) return null;
|
|
70
|
+
|
|
71
|
+
return repoName;
|
|
72
|
+
} catch {
|
|
73
|
+
return null;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Try to get the directory name from git toplevel.
|
|
79
|
+
*/
|
|
80
|
+
function tryGitToplevel(cwd: string): string | null {
|
|
81
|
+
try {
|
|
82
|
+
const toplevel = execSync("git rev-parse --show-toplevel", {
|
|
83
|
+
cwd,
|
|
84
|
+
encoding: "utf-8",
|
|
85
|
+
stdio: ["pipe", "pipe", "ignore"],
|
|
86
|
+
}).trim();
|
|
87
|
+
|
|
88
|
+
if (!toplevel || !fs.existsSync(toplevel)) return null;
|
|
89
|
+
|
|
90
|
+
const dirName = path.basename(toplevel);
|
|
91
|
+
// Verify it's a valid directory name
|
|
92
|
+
if (!dirName || dirName.includes("..") || dirName.includes("/")) return null;
|
|
93
|
+
|
|
94
|
+
return dirName;
|
|
95
|
+
} catch {
|
|
96
|
+
return null;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Detect project information from a working directory.
|
|
102
|
+
* Uses a hierarchy of detection methods, falling through on failure.
|
|
103
|
+
*
|
|
104
|
+
* Detection hierarchy (first successful wins):
|
|
105
|
+
* 1. CLAUDE_PROJECT_DIR env var → hash the path, use dir name as name
|
|
106
|
+
* 2. git remote get-url origin → extract repo name from URL
|
|
107
|
+
* 3. git rev-parse --show-toplevel → use dir name
|
|
108
|
+
* 4. Fallback: hash(cwd) for projectId, path.basename(cwd) for name
|
|
109
|
+
*/
|
|
110
|
+
export function detectProjectId(cwd: string): ProjectInfo {
|
|
111
|
+
// Normalize the cwd path
|
|
112
|
+
const normalizedCwd = path.resolve(cwd);
|
|
113
|
+
|
|
114
|
+
// Method 1: Check CLAUDE_PROJECT_DIR env var
|
|
115
|
+
const claudeProjectDir = process.env.CLAUDE_PROJECT_DIR;
|
|
116
|
+
if (claudeProjectDir && claudeProjectDir.trim()) {
|
|
117
|
+
const resolvedPath = path.resolve(claudeProjectDir.trim());
|
|
118
|
+
const projectName = path.basename(resolvedPath);
|
|
119
|
+
const projectId = hashPath(resolvedPath);
|
|
120
|
+
return { projectId, projectName };
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// Method 2: Try git remote origin
|
|
124
|
+
const repoName = tryGitRemote(normalizedCwd);
|
|
125
|
+
if (repoName) {
|
|
126
|
+
const projectId = hashPath(normalizedCwd);
|
|
127
|
+
return { projectId, projectName: repoName };
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
// Method 3: Try git toplevel
|
|
131
|
+
const toplevelName = tryGitToplevel(normalizedCwd);
|
|
132
|
+
if (toplevelName) {
|
|
133
|
+
const projectId = hashPath(normalizedCwd);
|
|
134
|
+
return { projectId, projectName: toplevelName };
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
// Method 4: Fallback - hash the cwd and use basename
|
|
138
|
+
const projectId = hashPath(normalizedCwd);
|
|
139
|
+
const projectName = path.basename(normalizedCwd) || "unknown";
|
|
140
|
+
return { projectId, projectName };
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* Get the storage directory for a specific project's instincts.
|
|
145
|
+
* @param projectId - The project identifier (from detectProjectId)
|
|
146
|
+
* @param crewRoot - The crew root directory (e.g., from projectCrewRoot)
|
|
147
|
+
* @returns The path to the project's storage directory
|
|
148
|
+
*/
|
|
149
|
+
export function getProjectStorageDir(projectId: string, crewRoot: string): string {
|
|
150
|
+
return path.join(crewRoot, "instincts", "projects", projectId);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* Get the global storage directory for instincts.
|
|
155
|
+
* @param crewRoot - The crew root directory
|
|
156
|
+
* @returns The path to the global storage directory
|
|
157
|
+
*/
|
|
158
|
+
export function getGlobalStorageDir(crewRoot: string): string {
|
|
159
|
+
return path.join(crewRoot, "instincts", "global");
|
|
160
|
+
}
|
package/test-bugs-all.mjs
CHANGED
|
@@ -70,7 +70,7 @@ if (completedIdsFix) {
|
|
|
70
70
|
// Check dist file
|
|
71
71
|
console.log("\n=== Checking dist/index.mjs ===");
|
|
72
72
|
const distContent = fs.readFileSync("dist/index.mjs", "utf-8");
|
|
73
|
-
const distNeedsAttention = distContent.includes('status === "completed" ||
|
|
73
|
+
const distNeedsAttention = distContent.includes('t2.status === "completed" || t2.status === "needs_attention"');
|
|
74
74
|
if (distNeedsAttention) {
|
|
75
75
|
console.log(" ✅ Bug #20 fix is in dist/index.mjs");
|
|
76
76
|
} else {
|
package/skills/.gitkeep
DELETED
|
File without changes
|
package/skills/REFERENCE.md
DELETED
|
@@ -1,136 +0,0 @@
|
|
|
1
|
-
# pi-crew Skills Reference
|
|
2
|
-
|
|
3
|
-
## Skill Chains
|
|
4
|
-
|
|
5
|
-
### Bug Investigation
|
|
6
|
-
|
|
7
|
-
```
|
|
8
|
-
systematic-debugging (4 phases with refuse gate)
|
|
9
|
-
↓
|
|
10
|
-
verification-before-done (evidence before claim)
|
|
11
|
-
↓
|
|
12
|
-
post-mortem (RCA documentation)
|
|
13
|
-
```
|
|
14
|
-
|
|
15
|
-
### Multi-phase Work
|
|
16
|
-
|
|
17
|
-
```
|
|
18
|
-
orchestration (phase coordination)
|
|
19
|
-
↓
|
|
20
|
-
delegation-patterns (task splitting)
|
|
21
|
-
↓
|
|
22
|
-
verification-before-done (after each phase)
|
|
23
|
-
```
|
|
24
|
-
|
|
25
|
-
### Code Review (Quick)
|
|
26
|
-
|
|
27
|
-
```
|
|
28
|
-
scrutinize (outsider perspective + simpler alternative)
|
|
29
|
-
```
|
|
30
|
-
|
|
31
|
-
### Code Review (Deep)
|
|
32
|
-
|
|
33
|
-
```
|
|
34
|
-
scrutinize (outsider perspective)
|
|
35
|
-
↓
|
|
36
|
-
multi-perspective-review (8-pass deep review)
|
|
37
|
-
↓
|
|
38
|
-
secure-agent-orchestration-review (security focus)
|
|
39
|
-
```
|
|
40
|
-
|
|
41
|
-
---
|
|
42
|
-
|
|
43
|
-
## When to Invoke
|
|
44
|
-
|
|
45
|
-
| Situation | Skill |
|
|
46
|
-
|-----------|-------|
|
|
47
|
-
| Bug / test failure / crash | `systematic-debugging` |
|
|
48
|
-
| Before claiming done | `verification-before-done` |
|
|
49
|
-
| Code review (quick) | `scrutinize` |
|
|
50
|
-
| Code review (deep) | `multi-perspective-review` |
|
|
51
|
-
| Task delegation | `delegation-patterns` |
|
|
52
|
-
| Complex multi-phase work | `orchestration` |
|
|
53
|
-
| After bug is fixed | `post-mortem` |
|
|
54
|
-
| Security review | `secure-agent-orchestration-review` |
|
|
55
|
-
| Workspace safety | `workspace-isolation` |
|
|
56
|
-
| Bash safety | `safe-bash` |
|
|
57
|
-
|
|
58
|
-
---
|
|
59
|
-
|
|
60
|
-
## Skills Inventory
|
|
61
|
-
|
|
62
|
-
### Core Discipline
|
|
63
|
-
|
|
64
|
-
| Skill | Description |
|
|
65
|
-
|-------|-------------|
|
|
66
|
-
| `systematic-debugging` | Four-phase debugging with refuse gates, falsify-first discipline |
|
|
67
|
-
| `verification-before-done` | Evidence before claims |
|
|
68
|
-
| `orchestration` | Multi-phase coordination, 8 rules including "respawn not absorb" |
|
|
69
|
-
|
|
70
|
-
### Review
|
|
71
|
-
|
|
72
|
-
| Skill | Description |
|
|
73
|
-
|-------|-------------|
|
|
74
|
-
| `scrutinize` | Outsider-perspective review questioning intent |
|
|
75
|
-
| `multi-perspective-review` | 8-pass deep code review |
|
|
76
|
-
| `secure-agent-orchestration-review` | Security-focused review |
|
|
77
|
-
|
|
78
|
-
### Documentation
|
|
79
|
-
|
|
80
|
-
| Skill | Description |
|
|
81
|
-
|-------|-------------|
|
|
82
|
-
| `post-mortem` | Engineering RCA record |
|
|
83
|
-
|
|
84
|
-
### Delegation
|
|
85
|
-
|
|
86
|
-
| Skill | Description |
|
|
87
|
-
|-------|-------------|
|
|
88
|
-
| `delegation-patterns` | Task splitting patterns |
|
|
89
|
-
| `requirements-to-task-packet` | Task packet creation |
|
|
90
|
-
|
|
91
|
-
### Runtime/Safety
|
|
92
|
-
|
|
93
|
-
| Skill | Description |
|
|
94
|
-
|-------|-------------|
|
|
95
|
-
| `workspace-isolation` | Security boundary enforcement |
|
|
96
|
-
| `worktree-isolation` | Git worktree safety |
|
|
97
|
-
| `safe-bash` | Bash command safety |
|
|
98
|
-
| `state-mutation-locking` | State mutation protection |
|
|
99
|
-
|
|
100
|
-
### Observability
|
|
101
|
-
|
|
102
|
-
| Skill | Description |
|
|
103
|
-
|-------|-------------|
|
|
104
|
-
| `event-log-tracing` | JSONL event log analysis |
|
|
105
|
-
| `runtime-state-reader` | Runtime state inspection |
|
|
106
|
-
| `observability-reliability` | Reliability patterns |
|
|
107
|
-
|
|
108
|
-
---
|
|
109
|
-
|
|
110
|
-
## Anti-patterns
|
|
111
|
-
|
|
112
|
-
| Anti-pattern | Skill | Rule |
|
|
113
|
-
|--------------|-------|------|
|
|
114
|
-
| Proposing fix before reproducing | `systematic-debugging` | Refuse Gate |
|
|
115
|
-
| Running proof before disproof | `systematic-debugging` | Phase 3 |
|
|
116
|
-
| Claiming "tests pass" without fresh run | `verification-before-done` | Gate Function |
|
|
117
|
-
| Reviewing diff-local without tracing path | `scrutinize` | Trace step |
|
|
118
|
-
| Skipping simpler-alternative pass | `multi-perspective-review` | Pre-review |
|
|
119
|
-
| Editing files yourself as orchestrator | `orchestration` | Rule 1 |
|
|
120
|
-
| Dispatching serially when parallel possible | `orchestration` | Rule 3 |
|
|
121
|
-
| Committing a red tree | `orchestration` | Rule 6 |
|
|
122
|
-
| Absorbing subagent's broken work | `orchestration` | Rule 7 |
|
|
123
|
-
| Rubber-stamp review | `multi-perspective-review` | Rules |
|
|
124
|
-
|
|
125
|
-
---
|
|
126
|
-
|
|
127
|
-
## Key Enforcement Patterns (from 9arm)
|
|
128
|
-
|
|
129
|
-
| Pattern | Implemented In |
|
|
130
|
-
|---------|---------------|
|
|
131
|
-
| **Refuse Gate** | `systematic-debugging` |
|
|
132
|
-
| **Recite Ritual** | `systematic-debugging` (Invocation) |
|
|
133
|
-
| **Falsify Before Proof** | `systematic-debugging` (Phase 3) |
|
|
134
|
-
| **Simpler Alternative Pass** | `scrutinize`, `multi-perspective-review` |
|
|
135
|
-
| **Required Inputs Gate** | `post-mortem` |
|
|
136
|
-
| **Respawn Not Absorb** | `orchestration` (Rule 7) |
|