@cluesmith/codev 3.0.0-rc.9 → 3.0.1
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/LICENSE +201 -0
- package/{dashboard/dist/assets/index-Bs8I7N2s.css → dashboard-dist/assets/index-BWYZtvwm.css} +1 -1
- package/dashboard-dist/assets/index-Dn9zmcKp.js +195 -0
- package/dashboard-dist/assets/index-Dn9zmcKp.js.map +1 -0
- package/{dashboard/dist → dashboard-dist}/index.html +2 -2
- package/dist/agent-farm/cli.d.ts.map +1 -1
- package/dist/agent-farm/cli.js +1 -2
- package/dist/agent-farm/cli.js.map +1 -1
- package/dist/agent-farm/commands/bench.d.ts +1 -1
- package/dist/agent-farm/commands/bench.js +1 -1
- package/dist/agent-farm/commands/spawn-roles.d.ts +7 -3
- package/dist/agent-farm/commands/spawn-roles.d.ts.map +1 -1
- package/dist/agent-farm/commands/spawn-roles.js +47 -27
- package/dist/agent-farm/commands/spawn-roles.js.map +1 -1
- package/dist/agent-farm/commands/spawn.d.ts.map +1 -1
- package/dist/agent-farm/commands/spawn.js +51 -33
- package/dist/agent-farm/commands/spawn.js.map +1 -1
- package/dist/agent-farm/commands/status.js +5 -1
- package/dist/agent-farm/commands/status.js.map +1 -1
- package/dist/agent-farm/lib/tower-client.d.ts +6 -230
- package/dist/agent-farm/lib/tower-client.d.ts.map +1 -1
- package/dist/agent-farm/lib/tower-client.js +6 -293
- package/dist/agent-farm/lib/tower-client.js.map +1 -1
- package/dist/agent-farm/servers/overview.d.ts +2 -1
- package/dist/agent-farm/servers/overview.d.ts.map +1 -1
- package/dist/agent-farm/servers/overview.js +36 -5
- package/dist/agent-farm/servers/overview.js.map +1 -1
- package/dist/agent-farm/servers/tower-instances.d.ts.map +1 -1
- package/dist/agent-farm/servers/tower-instances.js +3 -2
- package/dist/agent-farm/servers/tower-instances.js.map +1 -1
- package/dist/agent-farm/servers/tower-routes.d.ts.map +1 -1
- package/dist/agent-farm/servers/tower-routes.js +10 -0
- package/dist/agent-farm/servers/tower-routes.js.map +1 -1
- package/dist/agent-farm/servers/tower-server.js +1 -1
- package/dist/cli.js +2 -2
- package/dist/cli.js.map +1 -1
- package/dist/commands/consult/index.d.ts +31 -1
- package/dist/commands/consult/index.d.ts.map +1 -1
- package/dist/commands/consult/index.js +106 -19
- package/dist/commands/consult/index.js.map +1 -1
- package/dist/commands/porch/artifacts.d.ts +11 -1
- package/dist/commands/porch/artifacts.d.ts.map +1 -1
- package/dist/commands/porch/artifacts.js +12 -2
- package/dist/commands/porch/artifacts.js.map +1 -1
- package/dist/commands/porch/index.d.ts +5 -1
- package/dist/commands/porch/index.d.ts.map +1 -1
- package/dist/commands/porch/index.js +178 -27
- package/dist/commands/porch/index.js.map +1 -1
- package/dist/commands/porch/next.d.ts.map +1 -1
- package/dist/commands/porch/next.js +54 -28
- package/dist/commands/porch/next.js.map +1 -1
- package/dist/commands/porch/state.d.ts +24 -2
- package/dist/commands/porch/state.d.ts.map +1 -1
- package/dist/commands/porch/state.js +65 -10
- package/dist/commands/porch/state.js.map +1 -1
- package/dist/commands/porch/types.d.ts +8 -0
- package/dist/commands/porch/types.d.ts.map +1 -1
- package/dist/lib/forge-contracts.d.ts +3 -0
- package/dist/lib/forge-contracts.d.ts.map +1 -1
- package/dist/lib/forge-contracts.js.map +1 -1
- package/dist/lib/team-github.d.ts +47 -0
- package/dist/lib/team-github.d.ts.map +1 -1
- package/dist/lib/team-github.js +111 -2
- package/dist/lib/team-github.js.map +1 -1
- package/dist/terminal/ws-protocol.d.ts +10 -8
- package/dist/terminal/ws-protocol.d.ts.map +1 -1
- package/dist/terminal/ws-protocol.js +3 -0
- package/dist/terminal/ws-protocol.js.map +1 -1
- package/package.json +27 -25
- package/scripts/forge/gitea/auth-status.sh +0 -0
- package/scripts/forge/gitea/issue-comment.sh +0 -0
- package/scripts/forge/gitea/issue-list.sh +0 -0
- package/scripts/forge/gitea/issue-view.sh +0 -0
- package/scripts/forge/gitea/pr-exists.sh +4 -1
- package/scripts/forge/gitea/pr-list.sh +0 -0
- package/scripts/forge/gitea/pr-merge.sh +0 -0
- package/scripts/forge/gitea/pr-view.sh +0 -0
- package/scripts/forge/gitea/recently-closed.sh +0 -0
- package/scripts/forge/gitea/recently-merged.sh +0 -0
- package/scripts/forge/gitea/repo-archive.sh +0 -0
- package/scripts/forge/gitea/user-identity.sh +0 -0
- package/scripts/forge/github/auth-status.sh +0 -0
- package/scripts/forge/github/issue-comment.sh +0 -0
- package/scripts/forge/github/issue-list.sh +2 -2
- package/scripts/forge/github/issue-view.sh +0 -0
- package/scripts/forge/github/on-it-timestamps.sh +0 -0
- package/scripts/forge/github/pr-diff.sh +0 -0
- package/scripts/forge/github/pr-exists.sh +3 -1
- package/scripts/forge/github/pr-list.sh +0 -0
- package/scripts/forge/github/pr-merge.sh +0 -0
- package/scripts/forge/github/pr-search.sh +0 -0
- package/scripts/forge/github/pr-view.sh +0 -0
- package/scripts/forge/github/recently-closed.sh +0 -0
- package/scripts/forge/github/recently-merged.sh +0 -0
- package/scripts/forge/github/repo-archive.sh +0 -0
- package/scripts/forge/github/team-activity.sh +0 -0
- package/scripts/forge/github/user-identity.sh +0 -0
- package/scripts/forge/gitlab/auth-status.sh +0 -0
- package/scripts/forge/gitlab/issue-comment.sh +0 -0
- package/scripts/forge/gitlab/issue-list.sh +0 -0
- package/scripts/forge/gitlab/issue-view.sh +0 -0
- package/scripts/forge/gitlab/pr-diff.sh +0 -0
- package/scripts/forge/gitlab/pr-exists.sh +3 -1
- package/scripts/forge/gitlab/pr-list.sh +0 -0
- package/scripts/forge/gitlab/pr-merge.sh +0 -0
- package/scripts/forge/gitlab/pr-search.sh +0 -0
- package/scripts/forge/gitlab/pr-view.sh +0 -0
- package/scripts/forge/gitlab/recently-closed.sh +0 -0
- package/scripts/forge/gitlab/recently-merged.sh +0 -0
- package/scripts/forge/gitlab/repo-archive.sh +0 -0
- package/scripts/forge/gitlab/user-identity.sh +0 -0
- package/scripts/postinstall.mjs +51 -0
- package/skeleton/.claude/skills/afx/SKILL.md +1 -3
- package/skeleton/.claude/skills/consult/SKILL.md +1 -1
- package/skeleton/.claude/skills/porch/SKILL.md +2 -2
- package/skeleton/protocol-schema.json +2 -2
- package/skeleton/protocols/air/prompts/pr.md +15 -3
- package/skeleton/protocols/air/protocol.md +0 -1
- package/skeleton/protocols/aspir/builder-prompt.md +23 -1
- package/skeleton/protocols/aspir/prompts/review.md +11 -0
- package/skeleton/protocols/aspir/protocol.json +8 -0
- package/skeleton/protocols/aspir/templates/plan.md +0 -20
- package/skeleton/protocols/aspir/templates/spec.md +0 -28
- package/skeleton/protocols/bugfix/builder-prompt.md +1 -1
- package/skeleton/protocols/bugfix/prompts/pr.md +15 -3
- package/skeleton/protocols/experiment/builder-prompt.md +15 -0
- package/skeleton/protocols/experiment/protocol.md +1 -6
- package/skeleton/protocols/maintain/builder-prompt.md +12 -11
- package/skeleton/protocols/maintain/prompts/maintain.md +88 -0
- package/skeleton/protocols/maintain/prompts/review.md +84 -0
- package/skeleton/protocols/maintain/protocol.json +14 -68
- package/skeleton/protocols/maintain/protocol.md +110 -408
- package/skeleton/protocols/maintain/templates/maintenance-run.md +18 -49
- package/skeleton/protocols/protocol-schema.json +1 -1
- package/skeleton/protocols/research/builder-prompt.md +85 -0
- package/skeleton/protocols/research/protocol.json +118 -0
- package/skeleton/protocols/research/protocol.md +169 -0
- package/skeleton/protocols/spike/protocol.md +1 -1
- package/skeleton/protocols/spir/builder-prompt.md +24 -1
- package/skeleton/protocols/spir/prompts/review.md +11 -0
- package/skeleton/protocols/spir/protocol.json +8 -0
- package/skeleton/protocols/spir/templates/plan.md +0 -20
- package/skeleton/protocols/spir/templates/spec.md +0 -28
- package/skeleton/resources/commands/agent-farm.md +2 -2
- package/skeleton/resources/commands/consult.md +15 -6
- package/skeleton/resources/commands/overview.md +0 -1
- package/skeleton/roles/architect.md +1 -1
- package/skeleton/roles/builder.md +11 -3
- package/skeleton/templates/AGENTS.md +3 -1
- package/skeleton/templates/CLAUDE.md +3 -1
- package/skeleton/templates/cheatsheet.md +2 -2
- package/dashboard/dist/assets/index-DleIqu7L.js +0 -194
- package/dashboard/dist/assets/index-DleIqu7L.js.map +0 -1
- package/skeleton/porch/prompts/understand.md +0 -61
- package/skeleton/porch/prompts/verify.md +0 -58
- package/skeleton/protocols/maintain/prompts/audit.md +0 -111
- package/skeleton/protocols/maintain/prompts/clean.md +0 -91
- package/skeleton/protocols/maintain/prompts/sync.md +0 -113
- package/skeleton/protocols/maintain/prompts/verify.md +0 -110
- package/skeleton/protocols/tick/builder-prompt.md +0 -65
- package/skeleton/protocols/tick/consult-types/impl-review.md +0 -72
- package/skeleton/protocols/tick/consult-types/plan-review.md +0 -59
- package/skeleton/protocols/tick/consult-types/pr-review.md +0 -72
- package/skeleton/protocols/tick/consult-types/spec-review.md +0 -55
- package/skeleton/protocols/tick/protocol.json +0 -151
- package/skeleton/protocols/tick/protocol.md +0 -277
- package/skeleton/protocols/tick/templates/plan.md +0 -67
- package/skeleton/protocols/tick/templates/review.md +0 -89
- package/skeleton/protocols/tick/templates/spec.md +0 -61
|
@@ -8,6 +8,17 @@
|
|
|
8
8
|
*/
|
|
9
9
|
import type { TeamMember } from './team.js';
|
|
10
10
|
import { type ForgeConfig } from './forge.js';
|
|
11
|
+
export interface ReviewBlockingEntry {
|
|
12
|
+
direction: 'authored' | 'reviewing';
|
|
13
|
+
otherName: string;
|
|
14
|
+
otherGithub: string;
|
|
15
|
+
pr: {
|
|
16
|
+
number: number;
|
|
17
|
+
title: string;
|
|
18
|
+
url: string;
|
|
19
|
+
createdAt: string;
|
|
20
|
+
};
|
|
21
|
+
}
|
|
11
22
|
export interface TeamMemberGitHubData {
|
|
12
23
|
assignedIssues: {
|
|
13
24
|
number: number;
|
|
@@ -33,6 +44,7 @@ export interface TeamMemberGitHubData {
|
|
|
33
44
|
closedAt: string;
|
|
34
45
|
}[];
|
|
35
46
|
};
|
|
47
|
+
reviewBlocking: ReviewBlockingEntry[];
|
|
36
48
|
}
|
|
37
49
|
export declare function getRepoInfo(cwd?: string): Promise<{
|
|
38
50
|
owner: string;
|
|
@@ -46,6 +58,41 @@ export declare function getRepoInfo(cwd?: string): Promise<{
|
|
|
46
58
|
* GraphQL variables are not substituted inside string literals.
|
|
47
59
|
*/
|
|
48
60
|
export declare function buildTeamGraphQLQuery(members: TeamMember[], owner: string, name: string): string;
|
|
61
|
+
/**
|
|
62
|
+
* Raw shape of an open-PR node as returned by the batched GraphQL query.
|
|
63
|
+
* Exported for unit-test fixtures.
|
|
64
|
+
*/
|
|
65
|
+
export interface OpenPrNode {
|
|
66
|
+
number: number;
|
|
67
|
+
title: string;
|
|
68
|
+
url: string;
|
|
69
|
+
isDraft?: boolean;
|
|
70
|
+
createdAt?: string;
|
|
71
|
+
reviewDecision?: 'APPROVED' | 'CHANGES_REQUESTED' | 'REVIEW_REQUIRED' | null;
|
|
72
|
+
reviewRequests?: {
|
|
73
|
+
nodes?: Array<{
|
|
74
|
+
requestedReviewer?: {
|
|
75
|
+
login?: string;
|
|
76
|
+
} | null;
|
|
77
|
+
} | null> | null;
|
|
78
|
+
} | null;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Derive review-blocking relationships from every team member's authored PRs.
|
|
82
|
+
*
|
|
83
|
+
* Two-pass algorithm:
|
|
84
|
+
* 1. Collect (author, reviewer, pr) tuples by iterating each author's PRs
|
|
85
|
+
* and cross-referencing requested reviewers against the team roster.
|
|
86
|
+
* 2. Distribute each tuple into the author's `reviewBlocking` array (as
|
|
87
|
+
* `direction: 'authored'`) and the reviewer's (as `direction: 'reviewing'`).
|
|
88
|
+
*
|
|
89
|
+
* Rules are documented in spec 694:
|
|
90
|
+
* - Open, not draft.
|
|
91
|
+
* - reviewDecision !== 'APPROVED'.
|
|
92
|
+
* - Requested reviewer must resolve to a User (not Team) and match the team roster.
|
|
93
|
+
* - Author is guaranteed to be a team member by construction (query scope).
|
|
94
|
+
*/
|
|
95
|
+
export declare function deriveReviewBlocking(prsByAuthor: Map<string, OpenPrNode[]>, members: TeamMember[]): Map<string, ReviewBlockingEntry[]>;
|
|
49
96
|
/**
|
|
50
97
|
* Parse the GraphQL response into a map of github handle → TeamMemberGitHubData.
|
|
51
98
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"team-github.d.ts","sourceRoot":"","sources":["../../src/lib/team-github.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAKH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAC5C,OAAO,EAAuB,KAAK,WAAW,EAAE,MAAM,YAAY,CAAC;AAQnE,MAAM,WAAW,oBAAoB;IACnC,cAAc,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IACjE,OAAO,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAC1D,cAAc,EAAE;QACd,SAAS,EAAE;YAAE,MAAM,EAAE,MAAM,CAAC;YAAC,KAAK,EAAE,MAAM,CAAC;YAAC,GAAG,EAAE,MAAM,CAAC;YAAC,QAAQ,EAAE,MAAM,CAAA;SAAE,EAAE,CAAC;QAC9E,YAAY,EAAE;YAAE,MAAM,EAAE,MAAM,CAAC;YAAC,KAAK,EAAE,MAAM,CAAC;YAAC,GAAG,EAAE,MAAM,CAAC;YAAC,QAAQ,EAAE,MAAM,CAAA;SAAE,EAAE,CAAC;KAClF,CAAC;
|
|
1
|
+
{"version":3,"file":"team-github.d.ts","sourceRoot":"","sources":["../../src/lib/team-github.ts"],"names":[],"mappings":"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"}
|
package/dist/lib/team-github.js
CHANGED
|
@@ -67,7 +67,19 @@ export function buildTeamGraphQLQuery(members, owner, name) {
|
|
|
67
67
|
nodes { ... on Issue { number title url } }
|
|
68
68
|
}
|
|
69
69
|
${alias}_prs: search(query: "repo:${repo} author:${m.github} is:pr is:open", type: ISSUE, first: 20) {
|
|
70
|
-
nodes {
|
|
70
|
+
nodes {
|
|
71
|
+
... on PullRequest {
|
|
72
|
+
number
|
|
73
|
+
title
|
|
74
|
+
url
|
|
75
|
+
isDraft
|
|
76
|
+
createdAt
|
|
77
|
+
reviewDecision
|
|
78
|
+
reviewRequests(first: 20) {
|
|
79
|
+
nodes { requestedReviewer { ... on User { login } } }
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
71
83
|
}
|
|
72
84
|
${alias}_merged: search(query: "repo:${repo} author:${m.github} is:pr is:merged merged:>=${since}", type: ISSUE, first: 20) {
|
|
73
85
|
nodes { ... on PullRequest { number title url mergedAt } }
|
|
@@ -81,11 +93,99 @@ export function buildTeamGraphQLQuery(members, owner, name) {
|
|
|
81
93
|
${fragments}
|
|
82
94
|
}`;
|
|
83
95
|
}
|
|
96
|
+
/**
|
|
97
|
+
* Derive review-blocking relationships from every team member's authored PRs.
|
|
98
|
+
*
|
|
99
|
+
* Two-pass algorithm:
|
|
100
|
+
* 1. Collect (author, reviewer, pr) tuples by iterating each author's PRs
|
|
101
|
+
* and cross-referencing requested reviewers against the team roster.
|
|
102
|
+
* 2. Distribute each tuple into the author's `reviewBlocking` array (as
|
|
103
|
+
* `direction: 'authored'`) and the reviewer's (as `direction: 'reviewing'`).
|
|
104
|
+
*
|
|
105
|
+
* Rules are documented in spec 694:
|
|
106
|
+
* - Open, not draft.
|
|
107
|
+
* - reviewDecision !== 'APPROVED'.
|
|
108
|
+
* - Requested reviewer must resolve to a User (not Team) and match the team roster.
|
|
109
|
+
* - Author is guaranteed to be a team member by construction (query scope).
|
|
110
|
+
*/
|
|
111
|
+
export function deriveReviewBlocking(prsByAuthor, members) {
|
|
112
|
+
// Case-insensitive lookup: lower-case github handle → TeamMember.
|
|
113
|
+
const roster = new Map();
|
|
114
|
+
for (const m of members) {
|
|
115
|
+
if (!isValidGitHubHandle(m.github))
|
|
116
|
+
continue;
|
|
117
|
+
roster.set(m.github.toLowerCase(), m);
|
|
118
|
+
}
|
|
119
|
+
const displayName = (m) => m.name || m.github;
|
|
120
|
+
const perMember = new Map();
|
|
121
|
+
const entriesFor = (handle) => {
|
|
122
|
+
const existing = perMember.get(handle);
|
|
123
|
+
if (existing)
|
|
124
|
+
return existing;
|
|
125
|
+
const fresh = [];
|
|
126
|
+
perMember.set(handle, fresh);
|
|
127
|
+
return fresh;
|
|
128
|
+
};
|
|
129
|
+
for (const [authorHandle, prs] of prsByAuthor) {
|
|
130
|
+
const author = roster.get(authorHandle.toLowerCase());
|
|
131
|
+
if (!author)
|
|
132
|
+
continue;
|
|
133
|
+
for (const pr of prs) {
|
|
134
|
+
if (pr.isDraft)
|
|
135
|
+
continue;
|
|
136
|
+
if (pr.reviewDecision === 'APPROVED')
|
|
137
|
+
continue;
|
|
138
|
+
const requestedNodes = pr.reviewRequests?.nodes ?? [];
|
|
139
|
+
for (const node of requestedNodes) {
|
|
140
|
+
const login = node?.requestedReviewer?.login;
|
|
141
|
+
if (!login)
|
|
142
|
+
continue; // Team-based requests resolve to undefined login.
|
|
143
|
+
const reviewer = roster.get(login.toLowerCase());
|
|
144
|
+
if (!reviewer)
|
|
145
|
+
continue; // External reviewer.
|
|
146
|
+
if (reviewer.github.toLowerCase() === author.github.toLowerCase())
|
|
147
|
+
continue; // Self-review edge.
|
|
148
|
+
const prMeta = {
|
|
149
|
+
number: pr.number,
|
|
150
|
+
title: pr.title,
|
|
151
|
+
url: pr.url,
|
|
152
|
+
createdAt: pr.createdAt ?? '',
|
|
153
|
+
};
|
|
154
|
+
entriesFor(author.github).push({
|
|
155
|
+
direction: 'authored',
|
|
156
|
+
otherName: displayName(reviewer),
|
|
157
|
+
otherGithub: reviewer.github,
|
|
158
|
+
pr: prMeta,
|
|
159
|
+
});
|
|
160
|
+
entriesFor(reviewer.github).push({
|
|
161
|
+
direction: 'reviewing',
|
|
162
|
+
otherName: displayName(author),
|
|
163
|
+
otherGithub: author.github,
|
|
164
|
+
pr: prMeta,
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
// Sort each member's entries oldest-first (stable, with PR number as tiebreaker).
|
|
170
|
+
for (const list of perMember.values()) {
|
|
171
|
+
list.sort((a, b) => {
|
|
172
|
+
const byDate = (a.pr.createdAt ?? '').localeCompare(b.pr.createdAt ?? '');
|
|
173
|
+
if (byDate !== 0)
|
|
174
|
+
return byDate;
|
|
175
|
+
return a.pr.number - b.pr.number;
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
return perMember;
|
|
179
|
+
}
|
|
180
|
+
// =============================================================================
|
|
181
|
+
// Response Parser
|
|
182
|
+
// =============================================================================
|
|
84
183
|
/**
|
|
85
184
|
* Parse the GraphQL response into a map of github handle → TeamMemberGitHubData.
|
|
86
185
|
*/
|
|
87
186
|
export function parseTeamGraphQLResponse(data, members) {
|
|
88
187
|
const result = new Map();
|
|
188
|
+
const prsByAuthor = new Map();
|
|
89
189
|
for (const member of members) {
|
|
90
190
|
if (!isValidGitHubHandle(member.github))
|
|
91
191
|
continue;
|
|
@@ -94,15 +194,24 @@ export function parseTeamGraphQLResponse(data, members) {
|
|
|
94
194
|
const prs = data[`${alias}_prs`];
|
|
95
195
|
const merged = data[`${alias}_merged`];
|
|
96
196
|
const closed = data[`${alias}_closed`];
|
|
197
|
+
const openPrNodes = prs?.nodes ?? [];
|
|
198
|
+
prsByAuthor.set(member.github, openPrNodes);
|
|
97
199
|
result.set(member.github, {
|
|
98
200
|
assignedIssues: (assigned?.nodes ?? []).map(n => ({ number: n.number, title: n.title, url: n.url })),
|
|
99
|
-
openPRs:
|
|
201
|
+
openPRs: openPrNodes.map(n => ({ number: n.number, title: n.title, url: n.url })),
|
|
100
202
|
recentActivity: {
|
|
101
203
|
mergedPRs: (merged?.nodes ?? []).map(n => ({ number: n.number, title: n.title, url: n.url, mergedAt: n.mergedAt })),
|
|
102
204
|
closedIssues: (closed?.nodes ?? []).map(n => ({ number: n.number, title: n.title, url: n.url, closedAt: n.closedAt })),
|
|
103
205
|
},
|
|
206
|
+
reviewBlocking: [],
|
|
104
207
|
});
|
|
105
208
|
}
|
|
209
|
+
const perMemberBlocking = deriveReviewBlocking(prsByAuthor, members);
|
|
210
|
+
for (const [handle, entries] of perMemberBlocking) {
|
|
211
|
+
const bucket = result.get(handle);
|
|
212
|
+
if (bucket)
|
|
213
|
+
bucket.reviewBlocking = entries;
|
|
214
|
+
}
|
|
106
215
|
return result;
|
|
107
216
|
}
|
|
108
217
|
// =============================================================================
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"team-github.js","sourceRoot":"","sources":["../../src/lib/team-github.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,mBAAmB,EAAE,MAAM,WAAW,CAAC;AAEhD,OAAO,EAAE,mBAAmB,EAAoB,MAAM,YAAY,CAAC;AAEnE,MAAM,aAAa,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"team-github.js","sourceRoot":"","sources":["../../src/lib/team-github.ts"],"names":[],"mappings":"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"}
|
|
@@ -4,17 +4,15 @@
|
|
|
4
4
|
* Hybrid protocol:
|
|
5
5
|
* - 0x00 prefix: Control frame (remainder is UTF-8 JSON)
|
|
6
6
|
* - 0x01 prefix: Data frame (remainder is raw PTY bytes)
|
|
7
|
+
*
|
|
8
|
+
* Types imported from @cluesmith/codev-types (dev dependency, erased at compile time).
|
|
9
|
+
* Constants declared locally to avoid runtime dependency on the types package.
|
|
7
10
|
*/
|
|
11
|
+
import type { ControlMessage } from '@cluesmith/codev-types';
|
|
12
|
+
export type { ControlMessage } from '@cluesmith/codev-types';
|
|
8
13
|
export declare const FRAME_CONTROL = 0;
|
|
9
14
|
export declare const FRAME_DATA = 1;
|
|
10
|
-
|
|
11
|
-
type: 'resize' | 'ping' | 'pong' | 'pause' | 'resume' | 'error' | 'seq';
|
|
12
|
-
payload: Record<string, unknown>;
|
|
13
|
-
}
|
|
14
|
-
/** Encode a control message into a binary frame. */
|
|
15
|
-
export declare function encodeControl(msg: ControlMessage): Buffer;
|
|
16
|
-
/** Encode raw PTY data into a binary frame. */
|
|
17
|
-
export declare function encodeData(data: Buffer | string): Buffer;
|
|
15
|
+
/** Server-side decoded frame — uses Buffer (Node.js) instead of Uint8Array. */
|
|
18
16
|
export type DecodedFrame = {
|
|
19
17
|
type: 'control';
|
|
20
18
|
message: ControlMessage;
|
|
@@ -22,6 +20,10 @@ export type DecodedFrame = {
|
|
|
22
20
|
type: 'data';
|
|
23
21
|
data: Buffer;
|
|
24
22
|
};
|
|
23
|
+
/** Encode a control message into a binary frame. */
|
|
24
|
+
export declare function encodeControl(msg: ControlMessage): Buffer;
|
|
25
|
+
/** Encode raw PTY data into a binary frame. */
|
|
26
|
+
export declare function encodeData(data: Buffer | string): Buffer;
|
|
25
27
|
/** Decode a received WebSocket frame. */
|
|
26
28
|
export declare function decodeFrame(frame: Buffer): DecodedFrame;
|
|
27
29
|
//# sourceMappingURL=ws-protocol.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ws-protocol.d.ts","sourceRoot":"","sources":["../../src/terminal/ws-protocol.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"ws-protocol.d.ts","sourceRoot":"","sources":["../../src/terminal/ws-protocol.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAC7D,YAAY,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAE7D,eAAO,MAAM,aAAa,IAAO,CAAC;AAClC,eAAO,MAAM,UAAU,IAAO,CAAC;AAE/B,+EAA+E;AAC/E,MAAM,MAAM,YAAY,GACpB;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,OAAO,EAAE,cAAc,CAAA;CAAE,GAC5C;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAEnC,oDAAoD;AACpD,wBAAgB,aAAa,CAAC,GAAG,EAAE,cAAc,GAAG,MAAM,CAOzD;AAED,+CAA+C;AAC/C,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAMxD;AAED,yCAAyC;AACzC,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,YAAY,CAmBvD"}
|
|
@@ -4,6 +4,9 @@
|
|
|
4
4
|
* Hybrid protocol:
|
|
5
5
|
* - 0x00 prefix: Control frame (remainder is UTF-8 JSON)
|
|
6
6
|
* - 0x01 prefix: Data frame (remainder is raw PTY bytes)
|
|
7
|
+
*
|
|
8
|
+
* Types imported from @cluesmith/codev-types (dev dependency, erased at compile time).
|
|
9
|
+
* Constants declared locally to avoid runtime dependency on the types package.
|
|
7
10
|
*/
|
|
8
11
|
export const FRAME_CONTROL = 0x00;
|
|
9
12
|
export const FRAME_DATA = 0x01;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ws-protocol.js","sourceRoot":"","sources":["../../src/terminal/ws-protocol.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"ws-protocol.js","sourceRoot":"","sources":["../../src/terminal/ws-protocol.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAKH,MAAM,CAAC,MAAM,aAAa,GAAG,IAAI,CAAC;AAClC,MAAM,CAAC,MAAM,UAAU,GAAG,IAAI,CAAC;AAO/B,oDAAoD;AACpD,MAAM,UAAU,aAAa,CAAC,GAAmB;IAC/C,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;IACjC,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IAC3C,MAAM,KAAK,GAAG,MAAM,CAAC,WAAW,CAAC,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACrD,KAAK,CAAC,CAAC,CAAC,GAAG,aAAa,CAAC;IACzB,OAAO,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;IACvB,OAAO,KAAK,CAAC;AACf,CAAC;AAED,+CAA+C;AAC/C,MAAM,UAAU,UAAU,CAAC,IAAqB;IAC9C,MAAM,OAAO,GAAG,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAC7E,MAAM,KAAK,GAAG,MAAM,CAAC,WAAW,CAAC,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACrD,KAAK,CAAC,CAAC,CAAC,GAAG,UAAU,CAAC;IACtB,OAAO,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;IACvB,OAAO,KAAK,CAAC;AACf,CAAC;AAED,yCAAyC;AACzC,MAAM,UAAU,WAAW,CAAC,KAAa;IACvC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvB,MAAM,IAAI,KAAK,CAAC,aAAa,CAAC,CAAC;IACjC,CAAC;IAED,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;IACxB,MAAM,OAAO,GAAG,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;IAElC,IAAI,MAAM,KAAK,aAAa,EAAE,CAAC;QAC7B,MAAM,IAAI,GAAG,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;QACvC,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAmB,CAAC;QACnD,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC;IACtC,CAAC;IAED,IAAI,MAAM,KAAK,UAAU,EAAE,CAAC;QAC1B,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;IACzC,CAAC;IAED,MAAM,IAAI,KAAK,CAAC,2BAA2B,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;AACpE,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cluesmith/codev",
|
|
3
|
-
"version": "3.0.
|
|
3
|
+
"version": "3.0.1",
|
|
4
4
|
"description": "Codev CLI - AI-assisted software development framework",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -17,43 +17,28 @@
|
|
|
17
17
|
"bin",
|
|
18
18
|
"skeleton",
|
|
19
19
|
"templates",
|
|
20
|
-
"dashboard
|
|
21
|
-
"scripts/forge"
|
|
20
|
+
"dashboard-dist",
|
|
21
|
+
"scripts/forge",
|
|
22
|
+
"scripts/postinstall.mjs"
|
|
22
23
|
],
|
|
23
|
-
"scripts": {
|
|
24
|
-
"clean": "rm -rf dist",
|
|
25
|
-
"build": "npm run clean && tsc && npm run build:dashboard && npm run copy-skeleton",
|
|
26
|
-
"build:dashboard": "cd dashboard && npm install && npm run build",
|
|
27
|
-
"dev:dashboard": "cd dashboard && npm run dev",
|
|
28
|
-
"copy-skeleton": "rm -rf skeleton && cp -r ../../codev-skeleton skeleton",
|
|
29
|
-
"dev": "tsx src/cli.ts",
|
|
30
|
-
"start": "node dist/cli.js",
|
|
31
|
-
"test": "vitest",
|
|
32
|
-
"test:e2e": "npm run build && vitest run --config vitest.e2e.config.ts",
|
|
33
|
-
"test:e2e:watch": "vitest --config vitest.e2e.config.ts",
|
|
34
|
-
"test:e2e:playwright": "npx playwright test",
|
|
35
|
-
"test:e2e:cli": "npm run build && vitest run --config vitest.cli.config.ts",
|
|
36
|
-
"postinstall": "node -e \"try{require('fs').chmodSync(require('path').join(require.resolve('node-pty'),'..','..','prebuilds',process.platform+'-'+process.arch,'spawn-helper'),0o755)}catch{}\"",
|
|
37
|
-
"prepublishOnly": "npm run build"
|
|
38
|
-
},
|
|
39
24
|
"dependencies": {
|
|
40
25
|
"@anthropic-ai/claude-agent-sdk": "^0.2.41",
|
|
41
26
|
"@google/genai": "^1.0.0",
|
|
42
27
|
"@openai/codex-sdk": "^0.101.0",
|
|
43
|
-
"@types/http-proxy": "^1.17.17",
|
|
44
28
|
"better-sqlite3": "^12.5.0",
|
|
45
29
|
"chalk": "^5.3.0",
|
|
46
30
|
"commander": "^12.1.0",
|
|
47
31
|
"glob": "^11.0.0",
|
|
48
|
-
"http-proxy": "^1.18.1",
|
|
49
32
|
"js-yaml": "^4.1.0",
|
|
50
33
|
"node-pty": "^1.1.0",
|
|
51
34
|
"open": "^10.1.0",
|
|
52
35
|
"tree-kill": "^1.2.2",
|
|
53
|
-
"ws": "^8.18.0"
|
|
36
|
+
"ws": "^8.18.0",
|
|
37
|
+
"@cluesmith/codev-core": "0.0.2"
|
|
54
38
|
},
|
|
55
39
|
"devDependencies": {
|
|
56
40
|
"@playwright/test": "^1.58.0",
|
|
41
|
+
"@xterm/xterm": "^5.5.0",
|
|
57
42
|
"@types/better-sqlite3": "^7.6.13",
|
|
58
43
|
"@types/js-yaml": "^4.0.9",
|
|
59
44
|
"@types/node": "^22.10.1",
|
|
@@ -63,7 +48,9 @@
|
|
|
63
48
|
"playwright": "^1.58.0",
|
|
64
49
|
"tsx": "^4.19.2",
|
|
65
50
|
"typescript": "^5.7.2",
|
|
66
|
-
"vitest": "^4.0.15"
|
|
51
|
+
"vitest": "^4.0.15",
|
|
52
|
+
"@cluesmith/codev-dashboard": "0.0.0",
|
|
53
|
+
"@cluesmith/codev-types": "0.0.2"
|
|
67
54
|
},
|
|
68
55
|
"engines": {
|
|
69
56
|
"node": ">=20.0.0"
|
|
@@ -78,9 +65,24 @@
|
|
|
78
65
|
"multi-agent"
|
|
79
66
|
],
|
|
80
67
|
"author": "Cluesmith",
|
|
81
|
-
"license": "
|
|
68
|
+
"license": "Apache-2.0",
|
|
82
69
|
"repository": {
|
|
83
70
|
"type": "git",
|
|
84
71
|
"url": "https://github.com/cluesmith/codev"
|
|
72
|
+
},
|
|
73
|
+
"scripts": {
|
|
74
|
+
"clean": "rm -rf dist",
|
|
75
|
+
"build": "pnpm clean && tsc && pnpm build:dashboard && pnpm copy-skeleton",
|
|
76
|
+
"build:dashboard": "cd ../dashboard && pnpm build && rm -rf ../../packages/codev/dashboard-dist && cp -r dist ../../packages/codev/dashboard-dist",
|
|
77
|
+
"dev:dashboard": "cd ../dashboard && pnpm dev",
|
|
78
|
+
"copy-skeleton": "rm -rf skeleton && cp -r ../../codev-skeleton skeleton",
|
|
79
|
+
"dev": "tsx src/cli.ts",
|
|
80
|
+
"start": "node dist/cli.js",
|
|
81
|
+
"test": "vitest",
|
|
82
|
+
"test:e2e": "pnpm build && vitest run --config vitest.e2e.config.ts",
|
|
83
|
+
"test:e2e:watch": "vitest --config vitest.e2e.config.ts",
|
|
84
|
+
"test:e2e:playwright": "pnpm exec playwright test",
|
|
85
|
+
"test:e2e:cli": "pnpm build && vitest run --config vitest.cli.config.ts",
|
|
86
|
+
"postinstall": "node ./scripts/postinstall.mjs"
|
|
85
87
|
}
|
|
86
|
-
}
|
|
88
|
+
}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -1,3 +1,6 @@
|
|
|
1
1
|
#!/bin/sh
|
|
2
2
|
# Forge concept: pr-exists (Gitea via tea CLI)
|
|
3
|
-
|
|
3
|
+
# Returns true for open or merged pulls only. Closed-not-merged pulls are excluded.
|
|
4
|
+
# --state all fetches pulls in all states; without it, only open pulls are returned.
|
|
5
|
+
# Gitea: merged PRs have state="closed" + merged=true; abandoned PRs have state="closed" + merged=false
|
|
6
|
+
tea pulls list --state all --fields index --output json | jq "[.[] | select(.head.ref == \"$CODEV_BRANCH_NAME\" and (.state == \"open\" or (.state == \"closed\" and .merged == true)))] | length > 0"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
#!/bin/sh
|
|
2
2
|
# Forge concept: issue-list (GitHub via gh CLI)
|
|
3
|
-
# Output: JSON [{number, title, url, labels, createdAt, author}]
|
|
4
|
-
exec gh issue list --limit 200 --json number,title,url,labels,createdAt,author
|
|
3
|
+
# Output: JSON [{number, title, url, labels, createdAt, author, assignees}]
|
|
4
|
+
exec gh issue list --limit 200 --json number,title,url,labels,createdAt,author,assignees
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -2,4 +2,6 @@
|
|
|
2
2
|
# Forge concept: pr-exists (GitHub via gh CLI)
|
|
3
3
|
# Input: CODEV_BRANCH_NAME
|
|
4
4
|
# Output: "true" or "false"
|
|
5
|
-
|
|
5
|
+
# Returns true for OPEN or MERGED PRs only. CLOSED-not-merged PRs are excluded.
|
|
6
|
+
# (bugfix #568: --state all is needed to catch merged PRs; #653: filter out CLOSED)
|
|
7
|
+
exec gh pr list --state all --head "$CODEV_BRANCH_NAME" --json number,state --jq '[.[] | select(.state == "OPEN" or .state == "MERGED")] | length > 0'
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -1,3 +1,5 @@
|
|
|
1
1
|
#!/bin/sh
|
|
2
2
|
# Forge concept: pr-exists (GitLab via glab CLI)
|
|
3
|
-
|
|
3
|
+
# Returns true for open or merged MRs only. Closed-not-merged MRs are excluded.
|
|
4
|
+
# --all fetches MRs in all states (open, merged, closed); without it, only open MRs are returned.
|
|
5
|
+
glab mr list --all --source-branch "$CODEV_BRANCH_NAME" --output json | jq '[.[] | select(.state == "opened" or .state == "merged")] | length > 0'
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
// Restores executable bits that pnpm pack/publish strips from files outside
|
|
4
|
+
// the `bin` field. See issue #693 — without this, `afx spawn` fails with
|
|
5
|
+
// Permission denied when invoking forge concept scripts.
|
|
6
|
+
|
|
7
|
+
import { chmodSync, readdirSync } from 'node:fs';
|
|
8
|
+
import { createRequire } from 'node:module';
|
|
9
|
+
import { dirname, join } from 'node:path';
|
|
10
|
+
import { fileURLToPath } from 'node:url';
|
|
11
|
+
|
|
12
|
+
const here = dirname(fileURLToPath(import.meta.url));
|
|
13
|
+
const forgeRoot = join(here, 'forge');
|
|
14
|
+
|
|
15
|
+
function chmodForgeScripts(root) {
|
|
16
|
+
let providers;
|
|
17
|
+
try {
|
|
18
|
+
providers = readdirSync(root, { withFileTypes: true });
|
|
19
|
+
} catch {
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
for (const provider of providers) {
|
|
23
|
+
if (!provider.isDirectory()) continue;
|
|
24
|
+
const providerDir = join(root, provider.name);
|
|
25
|
+
for (const entry of readdirSync(providerDir, { withFileTypes: true })) {
|
|
26
|
+
if (!entry.isFile() || !entry.name.endsWith('.sh')) continue;
|
|
27
|
+
chmodSync(join(providerDir, entry.name), 0o755);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function chmodNodePtySpawnHelper() {
|
|
33
|
+
try {
|
|
34
|
+
const require = createRequire(import.meta.url);
|
|
35
|
+
const ptyEntry = require.resolve('node-pty');
|
|
36
|
+
const helper = join(
|
|
37
|
+
ptyEntry,
|
|
38
|
+
'..',
|
|
39
|
+
'..',
|
|
40
|
+
'prebuilds',
|
|
41
|
+
`${process.platform}-${process.arch}`,
|
|
42
|
+
'spawn-helper'
|
|
43
|
+
);
|
|
44
|
+
chmodSync(helper, 0o755);
|
|
45
|
+
} catch {
|
|
46
|
+
// node-pty may not ship a prebuild for this platform; harmless.
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
chmodForgeScripts(forgeRoot);
|
|
51
|
+
chmodNodePtySpawnHelper();
|
|
@@ -17,11 +17,10 @@ afx spawn [number] [options]
|
|
|
17
17
|
|
|
18
18
|
| Flag | Description |
|
|
19
19
|
|------|-------------|
|
|
20
|
-
| `--protocol <name>` | Protocol: spir, aspir, air, bugfix,
|
|
20
|
+
| `--protocol <name>` | Protocol: spir, aspir, air, bugfix, maintain, experiment. **Required for numbered spawns.** |
|
|
21
21
|
| `--task <text>` | Ad-hoc task (no issue number needed) |
|
|
22
22
|
| `--shell` | Bare Claude session |
|
|
23
23
|
| `--worktree` | Bare worktree session |
|
|
24
|
-
| `--amends <number>` | Original spec number (TICK only) |
|
|
25
24
|
| `--files <files>` | Context files, comma-separated. **Requires `--task`.** |
|
|
26
25
|
| `--no-comment` | Skip commenting on the GitHub issue |
|
|
27
26
|
| `--force` | Skip dirty-worktree and collision checks |
|
|
@@ -38,7 +37,6 @@ afx spawn 42 --protocol spir # SPIR builder for issue #42
|
|
|
38
37
|
afx spawn 42 --protocol aspir # ASPIR (autonomous, no human gates)
|
|
39
38
|
afx spawn 42 --protocol air # AIR (small features)
|
|
40
39
|
afx spawn 42 --protocol bugfix # Bugfix
|
|
41
|
-
afx spawn 42 --protocol tick --amends 30 # TICK amendment to spec 30
|
|
42
40
|
afx spawn 42 --protocol spir --soft # Soft mode
|
|
43
41
|
afx spawn 42 --resume # Resume existing builder
|
|
44
42
|
afx spawn --task "fix the flaky test" # Ad-hoc task (no issue)
|
|
@@ -30,7 +30,7 @@ The `-m` / `--model` flag is **always required** except for `consult stats`.
|
|
|
30
30
|
-m, --model <model> Model to use (required except stats)
|
|
31
31
|
--prompt <text> Inline prompt (general mode)
|
|
32
32
|
--prompt-file <path> Prompt file path (general mode)
|
|
33
|
-
--protocol <name> Protocol: spir, aspir, air, bugfix,
|
|
33
|
+
--protocol <name> Protocol: spir, aspir, air, bugfix, maintain
|
|
34
34
|
-t, --type <type> Review type (see below)
|
|
35
35
|
--issue <number> Issue number (required in architect context)
|
|
36
36
|
--output <path> Save result to file
|