@rallycry/conveyor-agent 11.0.7 → 11.0.9
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/dist/{boot-SQKXI5NY.js → boot-ZE6BM7L2.js} +2 -2
- package/dist/{chunk-NFNB2C35.js → chunk-7F57PZO7.js} +752 -376
- package/dist/{chunk-43XITDZP.js → chunk-DDECZOAT.js} +1 -1
- package/dist/{chunk-APP6Y2D7.js → chunk-YMZ6Q55T.js} +16 -0
- package/dist/cli.js +5 -5
- package/dist/index.d.ts +20 -0
- package/dist/index.js +2 -2
- package/dist/{serve-boot-ESZKFN5M.js → serve-boot-FJSZE737.js} +2 -2
- package/package.json +2 -2
|
@@ -59,7 +59,7 @@ import {
|
|
|
59
59
|
statWorkspacePath,
|
|
60
60
|
updateRemoteToken,
|
|
61
61
|
verifyGitCredential
|
|
62
|
-
} from "./chunk-
|
|
62
|
+
} from "./chunk-YMZ6Q55T.js";
|
|
63
63
|
import {
|
|
64
64
|
registerBootMilestoneSocketFallback,
|
|
65
65
|
reportBootMilestone
|
|
@@ -230,11 +230,12 @@ import { z as z6 } from "zod";
|
|
|
230
230
|
import { z as z7 } from "zod";
|
|
231
231
|
import { z as z8 } from "zod";
|
|
232
232
|
import { z as z9 } from "zod";
|
|
233
|
+
import { z as z10 } from "zod";
|
|
233
234
|
var EXTERNAL_AGENT_MESSAGE_SOURCE = "external_agent";
|
|
234
235
|
var DEFAULT_SONNET_MODEL = "claude-sonnet-5";
|
|
235
236
|
var DEFAULT_OPUS_MODEL = "claude-opus-5";
|
|
236
237
|
var DEFAULT_HAIKU_MODEL = "claude-haiku-4-5-20251001";
|
|
237
|
-
var FABLE_MODEL = "claude-fable-5";
|
|
238
|
+
var FABLE_MODEL = "claude-fable-5-1";
|
|
238
239
|
var PREVIOUS_SONNET_MODEL = "claude-sonnet-4-6";
|
|
239
240
|
var PREVIOUS_OPUS_MODEL = "claude-opus-4-8";
|
|
240
241
|
var PTY_STREAM_PORT_BASE = 7420;
|
|
@@ -993,10 +994,6 @@ var ReportReviewSpawnFailureRequestSchema = z4.object({
|
|
|
993
994
|
var ReportBuilderSpawnFailureRequestSchema = ReportReviewSpawnFailureRequestSchema.omit({
|
|
994
995
|
reviewSessionId: true
|
|
995
996
|
}).extend({ buildSessionId: z4.string() });
|
|
996
|
-
var RequestWorkspaceRecycleRequestSchema = z4.object({
|
|
997
|
-
sessionId: z4.string(),
|
|
998
|
-
reason: z4.string().max(2e3)
|
|
999
|
-
});
|
|
1000
997
|
var SpawnTaskSessionRequestSchema = z4.object({
|
|
1001
998
|
taskId: z4.string(),
|
|
1002
999
|
kind: z4.enum(["tui", "shell"])
|
|
@@ -1679,12 +1676,21 @@ var GetProjectAnalyticsSummaryRequestSchema = z6.object({
|
|
|
1679
1676
|
rangeDays: z6.number().int().min(1).max(GET_ANALYTICS_SUMMARY_MAX_RANGE_DAYS).optional(),
|
|
1680
1677
|
campaign: z6.string().max(200).optional()
|
|
1681
1678
|
});
|
|
1679
|
+
var RequestWorkspaceRecycleRequestSchema = z7.object({
|
|
1680
|
+
sessionId: z7.string(),
|
|
1681
|
+
reason: z7.string().max(2e3)
|
|
1682
|
+
});
|
|
1683
|
+
var ReportApiOutageRequestSchema = z7.object({
|
|
1684
|
+
sessionId: z7.string(),
|
|
1685
|
+
detail: z7.string().max(2e3),
|
|
1686
|
+
attempts: z7.number().int().min(0).max(100)
|
|
1687
|
+
});
|
|
1682
1688
|
var SHA_PATTERN = /^[0-9a-f]{40}$/i;
|
|
1683
|
-
var ReviewGuideFileReferenceSchema =
|
|
1684
|
-
path:
|
|
1685
|
-
startLine:
|
|
1686
|
-
endLine:
|
|
1687
|
-
hunkHeader:
|
|
1689
|
+
var ReviewGuideFileReferenceSchema = z8.object({
|
|
1690
|
+
path: z8.string().min(1).max(500),
|
|
1691
|
+
startLine: z8.number().int().positive().max(1e6).optional(),
|
|
1692
|
+
endLine: z8.number().int().positive().max(1e6).optional(),
|
|
1693
|
+
hunkHeader: z8.string().min(1).max(300).optional()
|
|
1688
1694
|
}).strict().superRefine((value, ctx) => {
|
|
1689
1695
|
if (value.endLine !== void 0 && value.startLine === void 0) {
|
|
1690
1696
|
ctx.addIssue({
|
|
@@ -1701,19 +1707,19 @@ var ReviewGuideFileReferenceSchema = z7.object({
|
|
|
1701
1707
|
});
|
|
1702
1708
|
}
|
|
1703
1709
|
});
|
|
1704
|
-
var ReviewGuideSectionSchema =
|
|
1705
|
-
title:
|
|
1706
|
-
explanation:
|
|
1707
|
-
classification:
|
|
1708
|
-
files:
|
|
1710
|
+
var ReviewGuideSectionSchema = z8.object({
|
|
1711
|
+
title: z8.string().min(1).max(160),
|
|
1712
|
+
explanation: z8.string().min(1).max(2e3),
|
|
1713
|
+
classification: z8.enum(["core", "supporting"]).optional(),
|
|
1714
|
+
files: z8.array(ReviewGuideFileReferenceSchema).min(1).max(20)
|
|
1709
1715
|
}).strict();
|
|
1710
|
-
var ReviewGuideContentSchema =
|
|
1711
|
-
overview:
|
|
1712
|
-
sections:
|
|
1716
|
+
var ReviewGuideContentSchema = z8.object({
|
|
1717
|
+
overview: z8.string().min(1).max(3e3),
|
|
1718
|
+
sections: z8.array(ReviewGuideSectionSchema).min(1).max(12)
|
|
1713
1719
|
}).strict();
|
|
1714
1720
|
var PublishReviewGuideRequestSchema = ReviewGuideContentSchema.extend({
|
|
1715
|
-
sessionId:
|
|
1716
|
-
reviewedSha:
|
|
1721
|
+
sessionId: z8.string().min(1),
|
|
1722
|
+
reviewedSha: z8.string().regex(SHA_PATTERN, "reviewedSha must be a 40-character commit SHA")
|
|
1717
1723
|
}).strict();
|
|
1718
1724
|
var CONTEXT_LINK_LOCATOR_MAX = 300;
|
|
1719
1725
|
var TEST_TITLE = /\b(?:it|test|describe)(?:\.\w+)?\s*\(\s*(['"`])((?:(?!\1)[\s\S])*)\1/g;
|
|
@@ -1730,130 +1736,130 @@ function locatorMatchesContent(content, locatorType, locator) {
|
|
|
1730
1736
|
var TAG_DESCRIPTION_MAX = CARD_DESCRIPTION_MAX;
|
|
1731
1737
|
var TAG_OVERVIEW_MAX = 32e3;
|
|
1732
1738
|
var TAG_REASON_MAX = 500;
|
|
1733
|
-
var ProjectTagContextPathSchema =
|
|
1734
|
-
type:
|
|
1735
|
-
path:
|
|
1736
|
-
label:
|
|
1739
|
+
var ProjectTagContextPathSchema = z9.object({
|
|
1740
|
+
type: z9.enum(["rule", "doc", "file", "folder"]),
|
|
1741
|
+
path: z9.string().min(1).max(500),
|
|
1742
|
+
label: z9.string().max(100).optional(),
|
|
1737
1743
|
/** Verified-link tether — text that must keep existing in the file. */
|
|
1738
|
-
locator:
|
|
1744
|
+
locator: z9.string().min(1).max(CONTEXT_LINK_LOCATOR_MAX).regex(/^[^\r\n]*$/, "Locator cannot contain line breaks").optional(),
|
|
1739
1745
|
/** test = must appear in a real test/describe title; code = any substring. */
|
|
1740
|
-
locatorType:
|
|
1746
|
+
locatorType: z9.enum(["test", "code"]).optional()
|
|
1741
1747
|
}).refine((link) => link.locator === void 0 === (link.locatorType === void 0), {
|
|
1742
1748
|
message: "locator and locatorType must be provided together"
|
|
1743
1749
|
}).refine((link) => link.locator === void 0 || link.type !== "folder", {
|
|
1744
1750
|
message: "folder links cannot carry a locator"
|
|
1745
1751
|
});
|
|
1746
|
-
var hexColor =
|
|
1747
|
-
var overviewPathSchema =
|
|
1748
|
-
var CreateProjectTagRequestSchema =
|
|
1749
|
-
projectId:
|
|
1750
|
-
name:
|
|
1752
|
+
var hexColor = z9.string().regex(/^#[0-9a-fA-F]{6}$/, "Expected #RRGGBB hex color");
|
|
1753
|
+
var overviewPathSchema = z9.string().min(1).max(500).regex(/^[^\r\n]*$/, "Overview path cannot contain line breaks");
|
|
1754
|
+
var CreateProjectTagRequestSchema = z9.object({
|
|
1755
|
+
projectId: z9.string(),
|
|
1756
|
+
name: z9.string().min(1).max(50),
|
|
1751
1757
|
color: hexColor.optional(),
|
|
1752
|
-
description:
|
|
1753
|
-
overview:
|
|
1758
|
+
description: z9.string().max(TAG_DESCRIPTION_MAX).optional(),
|
|
1759
|
+
overview: z9.string().max(TAG_OVERVIEW_MAX).optional(),
|
|
1754
1760
|
/** Source the overview from this repo file (stored overview stays as the pending fallback). */
|
|
1755
1761
|
overviewPath: overviewPathSchema.optional(),
|
|
1756
|
-
contextPaths:
|
|
1762
|
+
contextPaths: z9.array(ProjectTagContextPathSchema).max(20).optional(),
|
|
1757
1763
|
/** Parents to link at create time (multi-parent DAG). */
|
|
1758
|
-
parentTagIds:
|
|
1759
|
-
requestingUserId:
|
|
1764
|
+
parentTagIds: z9.array(z9.string()).max(25).optional(),
|
|
1765
|
+
requestingUserId: z9.string().optional()
|
|
1760
1766
|
});
|
|
1761
|
-
var UpdateProjectTagRequestSchema =
|
|
1762
|
-
projectId:
|
|
1763
|
-
tagId:
|
|
1764
|
-
name:
|
|
1767
|
+
var UpdateProjectTagRequestSchema = z9.object({
|
|
1768
|
+
projectId: z9.string(),
|
|
1769
|
+
tagId: z9.string(),
|
|
1770
|
+
name: z9.string().min(1).max(50).optional(),
|
|
1765
1771
|
color: hexColor.optional(),
|
|
1766
|
-
description:
|
|
1772
|
+
description: z9.string().max(TAG_DESCRIPTION_MAX).optional(),
|
|
1767
1773
|
/** Full markdown glossary body; null clears it. Rejected while overviewPath is set. */
|
|
1768
|
-
overview:
|
|
1774
|
+
overview: z9.string().max(TAG_OVERVIEW_MAX).nullable().optional(),
|
|
1769
1775
|
/** Repo file to source the overview from; null clears back to the stored overview. */
|
|
1770
1776
|
overviewPath: overviewPathSchema.nullable().optional(),
|
|
1771
1777
|
/** Full replacement of the tag's context links when provided. */
|
|
1772
|
-
contextPaths:
|
|
1778
|
+
contextPaths: z9.array(ProjectTagContextPathSchema).max(20).optional(),
|
|
1773
1779
|
/** Full-set replacement of the tag's parent tags (multi-parent DAG). */
|
|
1774
|
-
parentTagIds:
|
|
1780
|
+
parentTagIds: z9.array(z9.string()).max(25).optional(),
|
|
1775
1781
|
/** One-line revision provenance, recorded in the tag's history. */
|
|
1776
|
-
reason:
|
|
1782
|
+
reason: z9.string().max(TAG_REASON_MAX).optional(),
|
|
1777
1783
|
/** Card the caller was working in — stamped into the revision history. */
|
|
1778
|
-
taskId:
|
|
1779
|
-
requestingUserId:
|
|
1784
|
+
taskId: z9.string().optional(),
|
|
1785
|
+
requestingUserId: z9.string().optional()
|
|
1780
1786
|
});
|
|
1781
|
-
var PostToProjectChatRequestSchema =
|
|
1782
|
-
projectId:
|
|
1783
|
-
content:
|
|
1784
|
-
requestingUserId:
|
|
1787
|
+
var PostToProjectChatRequestSchema = z9.object({
|
|
1788
|
+
projectId: z9.string(),
|
|
1789
|
+
content: z9.string().min(1).max(2e4),
|
|
1790
|
+
requestingUserId: z9.string().optional(),
|
|
1785
1791
|
/** Marks the post so the server can persist it beyond chat (tag-audit summaries land in tag history). */
|
|
1786
|
-
kind:
|
|
1787
|
-
});
|
|
1788
|
-
var StartTagAuditRequestSchema =
|
|
1789
|
-
projectId:
|
|
1790
|
-
requestingUserId:
|
|
1791
|
-
});
|
|
1792
|
-
var StartTaskAuditRequestSchema =
|
|
1793
|
-
projectId:
|
|
1794
|
-
taskIds:
|
|
1795
|
-
requestingUserId:
|
|
1796
|
-
});
|
|
1797
|
-
var GetActiveAuditSessionsRequestSchema =
|
|
1798
|
-
projectId:
|
|
1799
|
-
});
|
|
1800
|
-
var ReportTaskAuditResultRequestSchema =
|
|
1801
|
-
projectId:
|
|
1802
|
-
taskId:
|
|
1803
|
-
summary:
|
|
1804
|
-
turnGrades:
|
|
1805
|
-
|
|
1806
|
-
turnIndex:
|
|
1807
|
-
phase:
|
|
1808
|
-
grade:
|
|
1809
|
-
reasoning:
|
|
1810
|
-
eventType:
|
|
1811
|
-
eventSummary:
|
|
1792
|
+
kind: z9.enum(["tag_audit_summary"]).optional()
|
|
1793
|
+
});
|
|
1794
|
+
var StartTagAuditRequestSchema = z9.object({
|
|
1795
|
+
projectId: z9.string(),
|
|
1796
|
+
requestingUserId: z9.string().optional()
|
|
1797
|
+
});
|
|
1798
|
+
var StartTaskAuditRequestSchema = z9.object({
|
|
1799
|
+
projectId: z9.string(),
|
|
1800
|
+
taskIds: z9.array(z9.string()).min(1).max(20),
|
|
1801
|
+
requestingUserId: z9.string().optional()
|
|
1802
|
+
});
|
|
1803
|
+
var GetActiveAuditSessionsRequestSchema = z9.object({
|
|
1804
|
+
projectId: z9.string()
|
|
1805
|
+
});
|
|
1806
|
+
var ReportTaskAuditResultRequestSchema = z9.object({
|
|
1807
|
+
projectId: z9.string(),
|
|
1808
|
+
taskId: z9.string(),
|
|
1809
|
+
summary: z9.string(),
|
|
1810
|
+
turnGrades: z9.array(
|
|
1811
|
+
z9.object({
|
|
1812
|
+
turnIndex: z9.number(),
|
|
1813
|
+
phase: z9.enum(["planning", "building", "human"]),
|
|
1814
|
+
grade: z9.enum(["correct", "neutral", "blunder"]),
|
|
1815
|
+
reasoning: z9.string(),
|
|
1816
|
+
eventType: z9.string(),
|
|
1817
|
+
eventSummary: z9.string()
|
|
1812
1818
|
})
|
|
1813
1819
|
),
|
|
1814
|
-
planningAccuracy:
|
|
1815
|
-
buildingAccuracy:
|
|
1816
|
-
humanAccuracy:
|
|
1817
|
-
planningCorrect:
|
|
1818
|
-
planningNeutral:
|
|
1819
|
-
planningBlunder:
|
|
1820
|
-
buildingCorrect:
|
|
1821
|
-
buildingNeutral:
|
|
1822
|
-
buildingBlunder:
|
|
1823
|
-
humanCorrect:
|
|
1824
|
-
humanNeutral:
|
|
1825
|
-
humanBlunder:
|
|
1826
|
-
humanEvaluations:
|
|
1827
|
-
|
|
1828
|
-
messageIndex:
|
|
1829
|
-
rating:
|
|
1830
|
-
reasoning:
|
|
1820
|
+
planningAccuracy: z9.number().nullable(),
|
|
1821
|
+
buildingAccuracy: z9.number().nullable(),
|
|
1822
|
+
humanAccuracy: z9.number().nullable(),
|
|
1823
|
+
planningCorrect: z9.number(),
|
|
1824
|
+
planningNeutral: z9.number(),
|
|
1825
|
+
planningBlunder: z9.number(),
|
|
1826
|
+
buildingCorrect: z9.number(),
|
|
1827
|
+
buildingNeutral: z9.number(),
|
|
1828
|
+
buildingBlunder: z9.number(),
|
|
1829
|
+
humanCorrect: z9.number(),
|
|
1830
|
+
humanNeutral: z9.number(),
|
|
1831
|
+
humanBlunder: z9.number(),
|
|
1832
|
+
humanEvaluations: z9.array(
|
|
1833
|
+
z9.object({
|
|
1834
|
+
messageIndex: z9.number(),
|
|
1835
|
+
rating: z9.union([z9.literal(-1), z9.literal(0), z9.literal(1)]),
|
|
1836
|
+
reasoning: z9.string()
|
|
1831
1837
|
})
|
|
1832
1838
|
).optional(),
|
|
1833
|
-
suggestionIds:
|
|
1834
|
-
auditCostUsd:
|
|
1835
|
-
model:
|
|
1839
|
+
suggestionIds: z9.array(z9.string()),
|
|
1840
|
+
auditCostUsd: z9.number().nullable(),
|
|
1841
|
+
model: z9.string().nullable(),
|
|
1836
1842
|
/** When set, the audit is marked failed with this message instead. */
|
|
1837
|
-
error:
|
|
1843
|
+
error: z9.string().optional()
|
|
1838
1844
|
});
|
|
1839
|
-
var GetTaskAuditsRequestSchema =
|
|
1840
|
-
projectId:
|
|
1841
|
-
limit:
|
|
1845
|
+
var GetTaskAuditsRequestSchema = z9.object({
|
|
1846
|
+
projectId: z9.string(),
|
|
1847
|
+
limit: z9.number().int().positive().max(200).optional().default(50)
|
|
1842
1848
|
});
|
|
1843
|
-
var GetTaskAuditRequestSchema =
|
|
1844
|
-
projectId:
|
|
1845
|
-
auditId:
|
|
1849
|
+
var GetTaskAuditRequestSchema = z9.object({
|
|
1850
|
+
projectId: z9.string(),
|
|
1851
|
+
auditId: z9.string()
|
|
1846
1852
|
});
|
|
1847
|
-
var GetTaskAuditAggregatesRequestSchema =
|
|
1848
|
-
projectId:
|
|
1853
|
+
var GetTaskAuditAggregatesRequestSchema = z9.object({
|
|
1854
|
+
projectId: z9.string()
|
|
1849
1855
|
});
|
|
1850
|
-
var DeleteTaskAuditRequestSchema =
|
|
1851
|
-
projectId:
|
|
1852
|
-
auditId:
|
|
1853
|
-
requestingUserId:
|
|
1856
|
+
var DeleteTaskAuditRequestSchema = z9.object({
|
|
1857
|
+
projectId: z9.string(),
|
|
1858
|
+
auditId: z9.string(),
|
|
1859
|
+
requestingUserId: z9.string().optional()
|
|
1854
1860
|
});
|
|
1855
|
-
var MarkInitialPromptSubmittedRequestSchema =
|
|
1856
|
-
sessionId:
|
|
1861
|
+
var MarkInitialPromptSubmittedRequestSchema = z9.object({
|
|
1862
|
+
sessionId: z9.string()
|
|
1857
1863
|
});
|
|
1858
1864
|
var CRITICAL_AUTOMATED_SOURCES = /* @__PURE__ */ new Set([
|
|
1859
1865
|
"ci_failure",
|
|
@@ -1871,47 +1877,139 @@ var DEFAULT_PACK_EXECUTION = "single-pod";
|
|
|
1871
1877
|
function parsePackExecution(value) {
|
|
1872
1878
|
return PACK_EXECUTIONS.includes(value ?? "") ? value : DEFAULT_PACK_EXECUTION;
|
|
1873
1879
|
}
|
|
1880
|
+
var MEETING_CHECKLIST_TITLE_MAX = 300;
|
|
1874
1881
|
var MEETING_TRANSCRIPT_MAX_CHARS = 2e6;
|
|
1875
1882
|
var MEETING_TITLE_MAX = 200;
|
|
1876
|
-
var
|
|
1877
|
-
|
|
1878
|
-
|
|
1879
|
-
|
|
1883
|
+
var MEETING_OCCURRED_AT_MIN_YEAR = 2e3;
|
|
1884
|
+
var MEETING_OCCURRED_AT_MAX_FUTURE_MS = 48 * 60 * 60 * 1e3;
|
|
1885
|
+
var OCCURRED_AT_RANGE_MESSAGE = `occurredAt must be a real date: no earlier than ${MEETING_OCCURRED_AT_MIN_YEAR}, and no more than 48 hours in the future.`;
|
|
1886
|
+
var MeetingOccurredAtSchema = z10.string().datetime().refine((value) => {
|
|
1887
|
+
const ms = Date.parse(value);
|
|
1888
|
+
if (Number.isNaN(ms)) return false;
|
|
1889
|
+
if (ms > Date.now() + MEETING_OCCURRED_AT_MAX_FUTURE_MS) return false;
|
|
1890
|
+
return new Date(ms).getUTCFullYear() >= MEETING_OCCURRED_AT_MIN_YEAR;
|
|
1891
|
+
}, OCCURRED_AT_RANGE_MESSAGE);
|
|
1892
|
+
var CreateMeetingFromTranscriptRequestSchema = z10.object({
|
|
1893
|
+
projectId: z10.string().cuid(),
|
|
1894
|
+
rawText: z10.string().min(1).max(MEETING_TRANSCRIPT_MAX_CHARS),
|
|
1895
|
+
title: z10.string().min(1).max(MEETING_TITLE_MAX).optional(),
|
|
1880
1896
|
/** ISO 8601. Defaults to now when the source carries no date. */
|
|
1881
|
-
occurredAt:
|
|
1897
|
+
occurredAt: MeetingOccurredAtSchema.optional(),
|
|
1882
1898
|
/** Override auto-detection. Rarely needed; detection handles the three formats. */
|
|
1883
|
-
format:
|
|
1884
|
-
source:
|
|
1885
|
-
});
|
|
1886
|
-
var GetMeetingRequestSchema =
|
|
1887
|
-
projectId:
|
|
1888
|
-
meetingId:
|
|
1889
|
-
});
|
|
1890
|
-
var UpdateMeetingRequestSchema =
|
|
1891
|
-
projectId:
|
|
1892
|
-
meetingId:
|
|
1893
|
-
title:
|
|
1894
|
-
occurredAt:
|
|
1895
|
-
});
|
|
1896
|
-
var RegenerateMeetingSummaryRequestSchema =
|
|
1897
|
-
projectId:
|
|
1898
|
-
meetingId:
|
|
1899
|
-
});
|
|
1900
|
-
var DeleteMeetingRequestSchema =
|
|
1901
|
-
projectId:
|
|
1902
|
-
meetingId:
|
|
1903
|
-
});
|
|
1904
|
-
var
|
|
1905
|
-
|
|
1906
|
-
|
|
1907
|
-
|
|
1908
|
-
});
|
|
1909
|
-
var
|
|
1910
|
-
projectId:
|
|
1911
|
-
meetingId:
|
|
1912
|
-
|
|
1913
|
-
|
|
1899
|
+
format: z10.enum(["text", "vtt", "srt"]).optional(),
|
|
1900
|
+
source: z10.enum(["manual", "slack"]).optional()
|
|
1901
|
+
});
|
|
1902
|
+
var GetMeetingRequestSchema = z10.object({
|
|
1903
|
+
projectId: z10.string().cuid(),
|
|
1904
|
+
meetingId: z10.string().cuid()
|
|
1905
|
+
});
|
|
1906
|
+
var UpdateMeetingRequestSchema = z10.object({
|
|
1907
|
+
projectId: z10.string().cuid(),
|
|
1908
|
+
meetingId: z10.string().cuid(),
|
|
1909
|
+
title: z10.string().min(1).max(MEETING_TITLE_MAX).optional(),
|
|
1910
|
+
occurredAt: MeetingOccurredAtSchema.optional()
|
|
1911
|
+
});
|
|
1912
|
+
var RegenerateMeetingSummaryRequestSchema = z10.object({
|
|
1913
|
+
projectId: z10.string().cuid(),
|
|
1914
|
+
meetingId: z10.string().cuid()
|
|
1915
|
+
});
|
|
1916
|
+
var DeleteMeetingRequestSchema = z10.object({
|
|
1917
|
+
projectId: z10.string().cuid(),
|
|
1918
|
+
meetingId: z10.string().cuid()
|
|
1919
|
+
});
|
|
1920
|
+
var checklistTitle = z10.string().min(1).max(MEETING_CHECKLIST_TITLE_MAX);
|
|
1921
|
+
var ListMeetingChecklistRequestSchema = z10.object({
|
|
1922
|
+
projectId: z10.string().cuid(),
|
|
1923
|
+
meetingId: z10.string().cuid()
|
|
1924
|
+
});
|
|
1925
|
+
var AddMeetingChecklistItemsRequestSchema = z10.object({
|
|
1926
|
+
projectId: z10.string().cuid(),
|
|
1927
|
+
meetingId: z10.string().cuid(),
|
|
1928
|
+
items: z10.array(z10.object({ title: checklistTitle })).min(1).max(50)
|
|
1929
|
+
});
|
|
1930
|
+
var UpdateMeetingChecklistItemRequestSchema = z10.object({
|
|
1931
|
+
projectId: z10.string().cuid(),
|
|
1932
|
+
meetingId: z10.string().cuid(),
|
|
1933
|
+
itemId: z10.string().cuid(),
|
|
1934
|
+
title: checklistTitle.optional(),
|
|
1935
|
+
ordinal: z10.number().int().min(0).optional(),
|
|
1936
|
+
/** Explicit null clears the link; undefined leaves it alone. */
|
|
1937
|
+
linkedTaskId: z10.string().cuid().nullable().optional()
|
|
1938
|
+
}).refine(
|
|
1939
|
+
(v) => v.title !== void 0 || v.ordinal !== void 0 || v.linkedTaskId !== void 0,
|
|
1940
|
+
"Pass at least one of title, ordinal, or linkedTaskId."
|
|
1941
|
+
);
|
|
1942
|
+
var DeleteMeetingChecklistItemRequestSchema = z10.object({
|
|
1943
|
+
projectId: z10.string().cuid(),
|
|
1944
|
+
meetingId: z10.string().cuid(),
|
|
1945
|
+
itemId: z10.string().cuid()
|
|
1946
|
+
});
|
|
1947
|
+
var SetMeetingChecklistItemCheckedRequestSchema = z10.object({
|
|
1948
|
+
projectId: z10.string().cuid(),
|
|
1949
|
+
meetingId: z10.string().cuid(),
|
|
1950
|
+
itemId: z10.string().cuid(),
|
|
1951
|
+
checked: z10.boolean(),
|
|
1952
|
+
/** Attach the card in the same call that ticks the item. */
|
|
1953
|
+
linkedTaskId: z10.string().cuid().nullable().optional()
|
|
1954
|
+
});
|
|
1955
|
+
var ListMeetingsRequestSchema = z10.object({
|
|
1956
|
+
projectId: z10.string().cuid(),
|
|
1957
|
+
limit: z10.number().int().min(1).max(50).optional(),
|
|
1958
|
+
search: z10.string().max(200).optional()
|
|
1959
|
+
});
|
|
1960
|
+
var ReadMeetingTranscriptRequestSchema = z10.object({
|
|
1961
|
+
projectId: z10.string().cuid(),
|
|
1962
|
+
meetingId: z10.string().cuid(),
|
|
1963
|
+
offset: z10.number().int().min(0).optional(),
|
|
1964
|
+
limit: z10.number().int().min(1).max(500).optional()
|
|
1965
|
+
});
|
|
1966
|
+
var MEETING_SUMMARY_MAX_CHARS = 5e4;
|
|
1967
|
+
var AddProjectMeetingChecklistItemsRequestSchema = z10.object({
|
|
1968
|
+
projectId: z10.string().cuid(),
|
|
1969
|
+
meetingId: z10.string().cuid(),
|
|
1970
|
+
items: z10.array(z10.object({ title: z10.string().min(1).max(MEETING_CHECKLIST_TITLE_MAX) })).min(1).max(50),
|
|
1971
|
+
requestingUserId: z10.string().optional()
|
|
1972
|
+
});
|
|
1973
|
+
var CheckProjectMeetingChecklistItemRequestSchema = z10.object({
|
|
1974
|
+
projectId: z10.string().cuid(),
|
|
1975
|
+
meetingId: z10.string().cuid(),
|
|
1976
|
+
title: z10.string().min(1).max(MEETING_CHECKLIST_TITLE_MAX),
|
|
1977
|
+
checked: z10.boolean(),
|
|
1978
|
+
/** Card id or slug. Resolved server-side and required to be in the project. */
|
|
1979
|
+
linkedTask: z10.string().min(1).optional(),
|
|
1980
|
+
requestingUserId: z10.string().optional()
|
|
1981
|
+
});
|
|
1982
|
+
var EditProjectMeetingChecklistItemRequestSchema = z10.object({
|
|
1983
|
+
projectId: z10.string().cuid(),
|
|
1984
|
+
meetingId: z10.string().cuid(),
|
|
1985
|
+
title: z10.string().min(1).max(MEETING_CHECKLIST_TITLE_MAX),
|
|
1986
|
+
newTitle: z10.string().min(1).max(MEETING_CHECKLIST_TITLE_MAX),
|
|
1987
|
+
requestingUserId: z10.string().optional()
|
|
1988
|
+
});
|
|
1989
|
+
var RemoveProjectMeetingChecklistItemRequestSchema = z10.object({
|
|
1990
|
+
projectId: z10.string().cuid(),
|
|
1991
|
+
meetingId: z10.string().cuid(),
|
|
1992
|
+
title: z10.string().min(1).max(MEETING_CHECKLIST_TITLE_MAX),
|
|
1993
|
+
requestingUserId: z10.string().optional()
|
|
1994
|
+
});
|
|
1995
|
+
var CreateProjectMeetingRequestSchema = z10.object({
|
|
1996
|
+
projectId: z10.string().cuid(),
|
|
1997
|
+
rawText: z10.string().min(1).max(MEETING_TRANSCRIPT_MAX_CHARS),
|
|
1998
|
+
title: z10.string().min(1).max(MEETING_TITLE_MAX).optional(),
|
|
1999
|
+
occurredAt: MeetingOccurredAtSchema.optional(),
|
|
2000
|
+
requestingUserId: z10.string().optional()
|
|
1914
2001
|
});
|
|
2002
|
+
var UpdateProjectMeetingRequestSchema = z10.object({
|
|
2003
|
+
projectId: z10.string().cuid(),
|
|
2004
|
+
meetingId: z10.string().cuid(),
|
|
2005
|
+
title: z10.string().min(1).max(MEETING_TITLE_MAX).optional(),
|
|
2006
|
+
occurredAt: MeetingOccurredAtSchema.optional(),
|
|
2007
|
+
summary: z10.string().min(1).max(MEETING_SUMMARY_MAX_CHARS).optional(),
|
|
2008
|
+
requestingUserId: z10.string().optional()
|
|
2009
|
+
}).refine(
|
|
2010
|
+
(v) => v.title !== void 0 || v.occurredAt !== void 0 || v.summary !== void 0,
|
|
2011
|
+
"Pass at least one of title, occurredAt, or summary."
|
|
2012
|
+
);
|
|
1915
2013
|
var AGENT_STATUS_REASON_USER_QUESTION = "user_question";
|
|
1916
2014
|
var TASK_CHAT_HISTORY_LIMIT = 20;
|
|
1917
2015
|
var PM_CHAT_HISTORY_LIMIT = 40;
|
|
@@ -1940,7 +2038,7 @@ var ANTHROPIC_CATALOG = [
|
|
|
1940
2038
|
anthropicEntry(PREVIOUS_SONNET_MODEL, "Sonnet 4.6", 3, 15),
|
|
1941
2039
|
// The Haiku line (4.5 and older) predates the tuning surface and 400s on it.
|
|
1942
2040
|
anthropicEntry(DEFAULT_HAIKU_MODEL, "Haiku 4.5", 1, 5, { supportsEffort: false }),
|
|
1943
|
-
anthropicEntry(FABLE_MODEL, "Fable 5
|
|
2041
|
+
anthropicEntry(FABLE_MODEL, "Fable 5.1", 10, 50)
|
|
1944
2042
|
];
|
|
1945
2043
|
var HUMAN_PROSE_WRITING_STYLE = `## Writing style for humans
|
|
1946
2044
|
When you write prose a person will read \u2014 chat messages, plan updates, PR titles and bodies, PR review guides (the \`publish_review_guide\` overview and section explanations), review comments \u2014 follow these rules (based on ASD-STE100 Simplified Technical English):
|
|
@@ -1954,6 +2052,9 @@ When you write prose a person will read \u2014 chat messages, plan updates, PR t
|
|
|
1954
2052
|
- Define a technical term on first use when a non-engineer will read the message.
|
|
1955
2053
|
- Never drop a condition, number, or scope qualifier to shorten a sentence. Precision beats brevity.
|
|
1956
2054
|
These rules do NOT apply to code, code comments, commit messages, or quoted output.`;
|
|
2055
|
+
var CLAUDESPACE_WORKLOAD_LABEL = "rc-workload";
|
|
2056
|
+
var CLAUDESPACE_WORKLOAD_VALUE = "claudespace";
|
|
2057
|
+
var CONVEYOR_POD_SELECTOR = `${CLAUDESPACE_WORKLOAD_LABEL}=${CLAUDESPACE_WORKLOAD_VALUE}`;
|
|
1957
2058
|
var MS_PER_DAY = 24 * 60 * 60 * 1e3;
|
|
1958
2059
|
var MENTION_TOKEN_REGEX = /@\[(\w+):([^\]]+)\]/g;
|
|
1959
2060
|
function parseMentions(content) {
|
|
@@ -2495,7 +2596,7 @@ function defineTool(name, description, schema, handler, options) {
|
|
|
2495
2596
|
|
|
2496
2597
|
// src/harness/claude-code/index.ts
|
|
2497
2598
|
import { query, tool, createSdkMcpServer } from "@anthropic-ai/claude-agent-sdk";
|
|
2498
|
-
import { z as
|
|
2599
|
+
import { z as z11 } from "zod";
|
|
2499
2600
|
var ClaudeCodeHarness = class {
|
|
2500
2601
|
/** The SDK stream is itself the structured-event source. */
|
|
2501
2602
|
emitsStructuredEvents = true;
|
|
@@ -2528,7 +2629,7 @@ var ClaudeCodeHarness = class {
|
|
|
2528
2629
|
}
|
|
2529
2630
|
);
|
|
2530
2631
|
if (t.strict) {
|
|
2531
|
-
sdkTool.inputSchema =
|
|
2632
|
+
sdkTool.inputSchema = z11.strictObject(t.schema);
|
|
2532
2633
|
}
|
|
2533
2634
|
return sdkTool;
|
|
2534
2635
|
});
|
|
@@ -3096,6 +3197,7 @@ function mapAssistant(record) {
|
|
|
3096
3197
|
};
|
|
3097
3198
|
const usage = mapUsage(message);
|
|
3098
3199
|
if (usage !== void 0) result.message.usage = usage;
|
|
3200
|
+
if (record.isApiErrorMessage === true) result.isApiError = true;
|
|
3099
3201
|
return result;
|
|
3100
3202
|
}
|
|
3101
3203
|
function mapResultSuccess(record) {
|
|
@@ -3786,7 +3888,7 @@ var PtyOutputCoalescer = class {
|
|
|
3786
3888
|
|
|
3787
3889
|
// src/harness/pty/tool-server.ts
|
|
3788
3890
|
import { createServer as createServer2 } from "http";
|
|
3789
|
-
import { z as
|
|
3891
|
+
import { z as z12 } from "zod";
|
|
3790
3892
|
import { writeFile as writeFile3 } from "fs/promises";
|
|
3791
3893
|
import { join as join3 } from "path";
|
|
3792
3894
|
import { randomBytes } from "crypto";
|
|
@@ -3843,7 +3945,7 @@ var PtyToolServer = class {
|
|
|
3843
3945
|
const mcp = new McpServer({ name: this.name, version: "1.0.0" });
|
|
3844
3946
|
const register = mcp.registerTool.bind(mcp);
|
|
3845
3947
|
for (const tool2 of this.tools) {
|
|
3846
|
-
const inputSchema = tool2.strict ?
|
|
3948
|
+
const inputSchema = tool2.strict ? z12.strictObject(tool2.schema) : tool2.schema;
|
|
3847
3949
|
register(
|
|
3848
3950
|
tool2.name,
|
|
3849
3951
|
{
|
|
@@ -4344,7 +4446,7 @@ function seedWorkspaceTrust(config, trustCwd) {
|
|
|
4344
4446
|
var FABLE_MODEL_OPTION = {
|
|
4345
4447
|
value: `${FABLE_MODEL}[1m]`,
|
|
4346
4448
|
label: "Fable",
|
|
4347
|
-
description: "Fable 5 - most capable for your hardest and longest-running tasks"
|
|
4449
|
+
description: "Fable 5.1 - most capable for your hardest and longest-running tasks"
|
|
4348
4450
|
};
|
|
4349
4451
|
function seedFableModelOption(config) {
|
|
4350
4452
|
const cache = Array.isArray(config.additionalModelOptionsCache) ? config.additionalModelOptionsCache : [];
|
|
@@ -6799,9 +6901,7 @@ function buildChatInstructions(context, scenario, newMessages) {
|
|
|
6799
6901
|
const parts = [];
|
|
6800
6902
|
if (scenario === "fresh") {
|
|
6801
6903
|
parts.push(
|
|
6802
|
-
`
|
|
6803
|
-
`Reply with post_to_chat \u2014 your turn output is NOT shown in chat, so post_to_chat is the only way the team sees your answer.`,
|
|
6804
|
-
`Ask clarifying questions when they help. This is a conversation, not an autonomous build.`
|
|
6904
|
+
`The user's message is above. Do what it asks and reply with post_to_chat \u2014 your turn output is NOT shown in chat, so post_to_chat is the only way the user sees your answer.`
|
|
6805
6905
|
);
|
|
6806
6906
|
} else if (userMessages.length > 0) {
|
|
6807
6907
|
parts.push(
|
|
@@ -6818,17 +6918,6 @@ Respond to them with post_to_chat (your turn output is NOT shown in chat).`
|
|
|
6818
6918
|
`Post a brief status update with post_to_chat if you still owe the team a response, then wait for them.`
|
|
6819
6919
|
);
|
|
6820
6920
|
}
|
|
6821
|
-
if (!context.plan?.trim()) {
|
|
6822
|
-
parts.push(
|
|
6823
|
-
`
|
|
6824
|
-
If this conversation turns into a development task: save a plan with update_task first \u2014 that identifies the card and moves it to In Progress \u2014 then implement it and open a PR with mcp__conveyor__create_pull_request, like a normal build.`
|
|
6825
|
-
);
|
|
6826
|
-
return parts;
|
|
6827
|
-
}
|
|
6828
|
-
parts.push(
|
|
6829
|
-
`
|
|
6830
|
-
This card has a saved plan, so it is a development task now. Implement it on the git branch "${context.githubBranch}", then run the \`/conveyor-build\` skill and follow it \u2014 the same workflow any build on this card would use, including how to verify before opening the PR.`
|
|
6831
|
-
);
|
|
6832
6921
|
if (context.githubPRUrl) {
|
|
6833
6922
|
parts.push(`An existing PR is open at ${context.githubPRUrl}. Do not create a new PR.`);
|
|
6834
6923
|
}
|
|
@@ -7461,31 +7550,20 @@ function buildModePrompt(agentMode, context, runnerMode) {
|
|
|
7461
7550
|
}
|
|
7462
7551
|
}
|
|
7463
7552
|
function buildChatPrompt(context) {
|
|
7464
|
-
const
|
|
7553
|
+
const branch = context?.githubBranch?.trim();
|
|
7554
|
+
const gitScope = branch ? ` on branch \`${branch}\`` : "";
|
|
7465
7555
|
return [
|
|
7466
7556
|
`
|
|
7467
|
-
## Mode:
|
|
7468
|
-
`
|
|
7469
|
-
`-
|
|
7470
|
-
`-
|
|
7471
|
-
`- This card starts Unidentified. That is correct \u2014 it stays a conversation until the work becomes a development task (see below).`,
|
|
7472
|
-
``,
|
|
7473
|
-
`### Deliverables \u2014 attach files to the card`,
|
|
7474
|
-
`- When you create a file the user should keep, attach it to the card with the \`upload_attachment\` tool so it shows up on the card. Mention in chat what you attached.`,
|
|
7475
|
-
`- \`upload_attachment\` accepts any file type (markdown, PDF, HTML, text, data, images) up to 25MB \u2014 this is how docs are delivered. Do NOT publish deliverables as a Claude artifact or any other off-platform link; the card is the system of record.`,
|
|
7476
|
-
`- For conversational work, attachments are the deliverable. Do NOT open a PR to hand over a document or an answer.`,
|
|
7557
|
+
## Mode: Interactive`,
|
|
7558
|
+
`This is a direct Claude Code session on this card. The user drives it message by message; you have the same access you would have running Claude Code locally in this repo (full read/write, shell, git${gitScope}).`,
|
|
7559
|
+
`- Your turn output is NOT shown in chat \u2014 reply with \`post_to_chat\`.`,
|
|
7560
|
+
`- There is no required Conveyor workflow here. Do what the message asks: answer, investigate, write files, build, or open a PR. Skills such as \`/conveyor-plan\` and \`/conveyor-build\` are available if the user asks for them or they clearly help; nothing runs them for you.`,
|
|
7477
7561
|
``,
|
|
7478
|
-
`###
|
|
7479
|
-
`-
|
|
7480
|
-
`-
|
|
7481
|
-
`-
|
|
7482
|
-
`-
|
|
7483
|
-
``,
|
|
7484
|
-
`### Finishing the conversation`,
|
|
7485
|
-
`- When the user indicates they are done (or explicitly asks to wrap up / close the card), call \`force_update_task_status\` with status \`"Complete"\`. It works from either status, so a card still sitting Unidentified can be completed the same way as one that reached In Progress.`,
|
|
7486
|
-
`- If you opened a PR, do NOT complete the card \u2014 the PR review flow takes it from there.`,
|
|
7487
|
-
`- If the user is still engaged, keep helping \u2014 only complete the card once the interaction has concluded.`,
|
|
7488
|
-
`- Do not complete the card while you still owe the user a response or an attachment.`
|
|
7562
|
+
`### Card facts`,
|
|
7563
|
+
`- This card starts Unidentified and stays so until a plan is saved with \`update_task\`; that first plan identifies it and moves it to In Progress.`,
|
|
7564
|
+
`- Files the user should keep go on the card via \`upload_attachment\` (any file type, up to 25MB), not an off-platform link.`,
|
|
7565
|
+
`- \`create_pull_request\` opens the PR for this card and moves it to Review PR. Save a short plan first so the card is identified \u2014 a record, not an approval gate.`,
|
|
7566
|
+
`- When the user says they are done, call \`force_update_task_status\` with status \`"Complete"\`. Not if a PR is open \u2014 the review flow takes it from there.`
|
|
7489
7567
|
].join("\n");
|
|
7490
7568
|
}
|
|
7491
7569
|
function buildReviewTagSection(context) {
|
|
@@ -8346,7 +8424,7 @@ async function buildInitialPrompt(mode, context, isAuto, agentMode, packExecutio
|
|
|
8346
8424
|
}
|
|
8347
8425
|
|
|
8348
8426
|
// src/tools/task-context-tools.ts
|
|
8349
|
-
import { z as
|
|
8427
|
+
import { z as z14 } from "zod";
|
|
8350
8428
|
|
|
8351
8429
|
// ../shared/dist/tool-contracts/index.js
|
|
8352
8430
|
var f = {
|
|
@@ -8375,14 +8453,14 @@ var f = {
|
|
|
8375
8453
|
return { kind: "nullable", inner };
|
|
8376
8454
|
}
|
|
8377
8455
|
};
|
|
8378
|
-
function compileString(
|
|
8379
|
-
let schema =
|
|
8456
|
+
function compileString(z21, spec) {
|
|
8457
|
+
let schema = z21.string();
|
|
8380
8458
|
if (spec.min !== void 0) schema = schema.min(spec.min);
|
|
8381
8459
|
if (spec.max !== void 0) schema = schema.max(spec.max);
|
|
8382
8460
|
return schema;
|
|
8383
8461
|
}
|
|
8384
|
-
function compileNumber(
|
|
8385
|
-
let schema =
|
|
8462
|
+
function compileNumber(z21, spec) {
|
|
8463
|
+
let schema = z21.number();
|
|
8386
8464
|
if (spec.int) schema = schema.int();
|
|
8387
8465
|
if (spec.positive) schema = schema.positive();
|
|
8388
8466
|
if (spec.nonnegative) schema = schema.nonnegative();
|
|
@@ -8390,49 +8468,49 @@ function compileNumber(z20, spec) {
|
|
|
8390
8468
|
if (spec.max !== void 0) schema = schema.max(spec.max);
|
|
8391
8469
|
return schema;
|
|
8392
8470
|
}
|
|
8393
|
-
function compileArray(
|
|
8394
|
-
let schema =
|
|
8471
|
+
function compileArray(z21, spec) {
|
|
8472
|
+
let schema = z21.array(compileField(z21, spec.item));
|
|
8395
8473
|
if (spec.min !== void 0) schema = schema.min(spec.min);
|
|
8396
8474
|
return schema;
|
|
8397
8475
|
}
|
|
8398
|
-
function compileBase(
|
|
8476
|
+
function compileBase(z21, spec) {
|
|
8399
8477
|
switch (spec.kind) {
|
|
8400
8478
|
case "string":
|
|
8401
|
-
return compileString(
|
|
8479
|
+
return compileString(z21, spec);
|
|
8402
8480
|
case "number":
|
|
8403
|
-
return compileNumber(
|
|
8481
|
+
return compileNumber(z21, spec);
|
|
8404
8482
|
case "boolean":
|
|
8405
|
-
return
|
|
8483
|
+
return z21.boolean();
|
|
8406
8484
|
case "enum":
|
|
8407
|
-
return
|
|
8485
|
+
return z21.enum([...spec.values]);
|
|
8408
8486
|
case "array":
|
|
8409
|
-
return compileArray(
|
|
8487
|
+
return compileArray(z21, spec);
|
|
8410
8488
|
case "object":
|
|
8411
|
-
return
|
|
8489
|
+
return z21.object(compileShape(z21, spec.fields));
|
|
8412
8490
|
}
|
|
8413
8491
|
}
|
|
8414
8492
|
function descriptionOf(spec) {
|
|
8415
8493
|
if (spec.kind === "optional" || spec.kind === "nullable") return descriptionOf(spec.inner);
|
|
8416
8494
|
return spec.desc;
|
|
8417
8495
|
}
|
|
8418
|
-
function compileUndescribed(
|
|
8496
|
+
function compileUndescribed(z21, spec) {
|
|
8419
8497
|
if (spec.kind === "optional") {
|
|
8420
|
-
return compileUndescribed(
|
|
8498
|
+
return compileUndescribed(z21, spec.inner).optional();
|
|
8421
8499
|
}
|
|
8422
8500
|
if (spec.kind === "nullable") {
|
|
8423
|
-
return compileUndescribed(
|
|
8501
|
+
return compileUndescribed(z21, spec.inner).nullable();
|
|
8424
8502
|
}
|
|
8425
|
-
return compileBase(
|
|
8503
|
+
return compileBase(z21, spec);
|
|
8426
8504
|
}
|
|
8427
|
-
function compileField(
|
|
8428
|
-
const schema = compileUndescribed(
|
|
8505
|
+
function compileField(z21, spec) {
|
|
8506
|
+
const schema = compileUndescribed(z21, spec);
|
|
8429
8507
|
const desc = descriptionOf(spec);
|
|
8430
8508
|
return desc === void 0 ? schema : schema.describe(desc);
|
|
8431
8509
|
}
|
|
8432
|
-
function compileShape(
|
|
8510
|
+
function compileShape(z21, fields) {
|
|
8433
8511
|
const shape = {};
|
|
8434
8512
|
for (const [key, spec] of Object.entries(fields)) {
|
|
8435
|
-
shape[key] = compileField(
|
|
8513
|
+
shape[key] = compileField(z21, spec);
|
|
8436
8514
|
}
|
|
8437
8515
|
return shape;
|
|
8438
8516
|
}
|
|
@@ -9013,7 +9091,7 @@ var createSubtaskContract = defineToolContract({
|
|
|
9013
9091
|
),
|
|
9014
9092
|
tags: f.optional(
|
|
9015
9093
|
f.array(f.string(), {
|
|
9016
|
-
desc: 'Tag names to assign to the subtask (e.g. ["refactor"]). Unknown names are rejected
|
|
9094
|
+
desc: 'Tag names to assign to the subtask (e.g. ["refactor"]). Unknown names are rejected before the subtask is created, so nothing is written and a corrected retry creates exactly one subtask. Create the tag first with manage_tags. Use list_tags to see available tags.'
|
|
9017
9095
|
})
|
|
9018
9096
|
)
|
|
9019
9097
|
}
|
|
@@ -9606,10 +9684,149 @@ var readMeetingTranscriptContract = defineToolContract({
|
|
|
9606
9684
|
}
|
|
9607
9685
|
}
|
|
9608
9686
|
});
|
|
9687
|
+
var RAW_TEXT_DESC = "The transcript itself. Plain text with `Speaker: line` labels, or a WebVTT/SRT file's contents \u2014 the format is detected, and the speaker labels become the participant list. Paste the whole thing; it is stored as the meeting's record.";
|
|
9688
|
+
var OCCURRED_AT_DESC = "When the meeting happened, ISO 8601 (e.g. 2026-09-02T15:00:00Z). Defaults to now. Must be a real date \u2014 no earlier than 2000, and no more than 48 hours ahead.";
|
|
9689
|
+
var TITLE_DESC = "Meeting title. Defaults to `Meeting <date>` when you do not name one.";
|
|
9690
|
+
var createMeetingContract = defineToolContract({
|
|
9691
|
+
name: "create_meeting",
|
|
9692
|
+
agent: {
|
|
9693
|
+
description: `File a transcript as a project meeting. Use this when you have the text of a call \u2014 a paste, an export, notes captured elsewhere \u2014 and it belongs in the project's record. The transcript is parsed into speaker segments and an AI summary is written straight after, so the meeting reads "processing" for a few seconds before its overview appears. This creates a MEETING, not cards: turning what was decided into work is still create_task's job.`,
|
|
9694
|
+
fields: {
|
|
9695
|
+
rawText: f.string({ desc: RAW_TEXT_DESC, min: 1 }),
|
|
9696
|
+
title: f.optional(f.string({ desc: TITLE_DESC, max: 200 })),
|
|
9697
|
+
occurredAt: f.optional(f.string({ desc: OCCURRED_AT_DESC }))
|
|
9698
|
+
}
|
|
9699
|
+
},
|
|
9700
|
+
mcp: {
|
|
9701
|
+
description: `File a transcript as a project meeting. The text is parsed into speaker segments and summarized automatically, so the meeting reports status "processing" briefly before its overview lands. Creates a meeting only \u2014 use the card tools to turn decisions into work. ${MCP_TAIL}`,
|
|
9702
|
+
fields: {
|
|
9703
|
+
projectId: mcpProjectId,
|
|
9704
|
+
rawText: f.string({ desc: RAW_TEXT_DESC, min: 1 }),
|
|
9705
|
+
title: f.optional(f.string({ desc: TITLE_DESC, max: 200 })),
|
|
9706
|
+
occurredAt: f.optional(f.string({ desc: OCCURRED_AT_DESC }))
|
|
9707
|
+
}
|
|
9708
|
+
}
|
|
9709
|
+
});
|
|
9710
|
+
var SUMMARY_DESC = "Replace the meeting's overview with this text. Markdown, and it is what every reader sees from then on \u2014 write the whole overview, not a note about it. Writing a summary marks the meeting ready, so a later regenerate is the only thing that overwrites it.";
|
|
9711
|
+
var updateMeetingContract = defineToolContract({
|
|
9712
|
+
name: "update_meeting",
|
|
9713
|
+
agent: {
|
|
9714
|
+
description: `Correct a meeting's title or date, or replace its AI summary with a better one. This is how a rewritten overview actually persists \u2014 read the transcript, write the summary you want, and pass it here. Pass at least one field; the ones you leave out are untouched.`,
|
|
9715
|
+
fields: {
|
|
9716
|
+
meetingId: f.string({ desc: MEETING_ID }),
|
|
9717
|
+
title: f.optional(f.string({ desc: TITLE_DESC, max: 200 })),
|
|
9718
|
+
occurredAt: f.optional(f.string({ desc: OCCURRED_AT_DESC })),
|
|
9719
|
+
summary: f.optional(f.string({ desc: SUMMARY_DESC, min: 1 }))
|
|
9720
|
+
}
|
|
9721
|
+
},
|
|
9722
|
+
mcp: {
|
|
9723
|
+
description: `Correct a meeting's title or date, or replace its AI summary with a rewritten one. Pass at least one field; omitted fields are left alone. ${MCP_TAIL}`,
|
|
9724
|
+
fields: {
|
|
9725
|
+
projectId: mcpProjectId,
|
|
9726
|
+
meetingId: f.string({ desc: MEETING_ID }),
|
|
9727
|
+
title: f.optional(f.string({ desc: TITLE_DESC, max: 200 })),
|
|
9728
|
+
occurredAt: f.optional(f.string({ desc: OCCURRED_AT_DESC })),
|
|
9729
|
+
summary: f.optional(f.string({ desc: SUMMARY_DESC, min: 1 }))
|
|
9730
|
+
}
|
|
9731
|
+
}
|
|
9732
|
+
});
|
|
9733
|
+
var CHECKLIST_ITEM_TITLE = "The item's exact title, as get_meeting lists it. Matched case-insensitively.";
|
|
9734
|
+
var CHECKLIST_INTRO = "A meeting's checklist is its follow-ups: one line each, ticked when done, optionally pointing at the Conveyor card that carries the work. The AI summary's proposed next steps are seeded here automatically.";
|
|
9735
|
+
var addMeetingChecklistItemsContract = defineToolContract({
|
|
9736
|
+
name: "add_meeting_checklist_items",
|
|
9737
|
+
agent: {
|
|
9738
|
+
description: `Add follow-up items to a meeting's checklist. ${CHECKLIST_INTRO} Use this for a step the summary missed, or one that came out of a later conversation. Items whose title already exists are skipped, so re-running this is safe.`,
|
|
9739
|
+
fields: {
|
|
9740
|
+
meetingId: f.string({ desc: MEETING_ID }),
|
|
9741
|
+
items: f.array(
|
|
9742
|
+
f.object({ title: f.string({ desc: "One follow-up, as a single line.", min: 1 }) }),
|
|
9743
|
+
{ desc: "The items to add, in the order they should appear." }
|
|
9744
|
+
)
|
|
9745
|
+
}
|
|
9746
|
+
},
|
|
9747
|
+
mcp: {
|
|
9748
|
+
description: `Add follow-up items to a meeting's checklist. ${CHECKLIST_INTRO} Existing titles are skipped, so re-running is safe. ${MCP_TAIL}`,
|
|
9749
|
+
fields: {
|
|
9750
|
+
projectId: mcpProjectId,
|
|
9751
|
+
meetingId: f.string({ desc: MEETING_ID }),
|
|
9752
|
+
items: f.array(
|
|
9753
|
+
f.object({ title: f.string({ desc: "One follow-up, as a single line.", min: 1 }) }),
|
|
9754
|
+
{ desc: "The items to add, in the order they should appear." }
|
|
9755
|
+
)
|
|
9756
|
+
}
|
|
9757
|
+
}
|
|
9758
|
+
});
|
|
9759
|
+
var LINKED_TASK_DESC = "Card id or slug to attach to this item \u2014 the card that carries the work. Must be in the same project. Pass it in the same call that ticks the item when you just filed the card.";
|
|
9760
|
+
var checkMeetingChecklistItemContract = defineToolContract({
|
|
9761
|
+
name: "check_meeting_checklist_item",
|
|
9762
|
+
agent: {
|
|
9763
|
+
description: `Tick or untick one of a meeting's checklist items, and optionally attach the card that carries it. This is how a next step becomes tracked work: file the card with create_task, then call this with the item's title and the new card's slug. Ticking records YOU as the person who did it. Unticking clears that, but keeps the linked card.`,
|
|
9764
|
+
fields: {
|
|
9765
|
+
meetingId: f.string({ desc: MEETING_ID }),
|
|
9766
|
+
title: f.string({ desc: CHECKLIST_ITEM_TITLE }),
|
|
9767
|
+
checked: f.boolean({ desc: "true to tick the item, false to untick it." }),
|
|
9768
|
+
linkedTask: f.optional(f.string({ desc: LINKED_TASK_DESC }))
|
|
9769
|
+
}
|
|
9770
|
+
},
|
|
9771
|
+
mcp: {
|
|
9772
|
+
description: `Tick or untick a meeting checklist item, optionally attaching the card that carries it. Ticking records the acting user. Unticking clears that but keeps the link. ${MCP_TAIL}`,
|
|
9773
|
+
fields: {
|
|
9774
|
+
projectId: mcpProjectId,
|
|
9775
|
+
meetingId: f.string({ desc: MEETING_ID }),
|
|
9776
|
+
title: f.string({ desc: CHECKLIST_ITEM_TITLE }),
|
|
9777
|
+
checked: f.boolean({ desc: "true to tick the item, false to untick it." }),
|
|
9778
|
+
linkedTask: f.optional(f.string({ desc: LINKED_TASK_DESC }))
|
|
9779
|
+
}
|
|
9780
|
+
}
|
|
9781
|
+
});
|
|
9782
|
+
var editMeetingChecklistItemContract = defineToolContract({
|
|
9783
|
+
name: "edit_meeting_checklist_item",
|
|
9784
|
+
agent: {
|
|
9785
|
+
description: `Reword one of a meeting's checklist items. Use it to sharpen a vague next step into something someone can act on; to mark it done use check_meeting_checklist_item instead.`,
|
|
9786
|
+
fields: {
|
|
9787
|
+
meetingId: f.string({ desc: MEETING_ID }),
|
|
9788
|
+
title: f.string({ desc: CHECKLIST_ITEM_TITLE }),
|
|
9789
|
+
newTitle: f.string({ desc: "The replacement text, as a single line.", min: 1 })
|
|
9790
|
+
}
|
|
9791
|
+
},
|
|
9792
|
+
mcp: {
|
|
9793
|
+
description: `Reword a meeting checklist item. To mark it done use check_meeting_checklist_item. ${MCP_TAIL}`,
|
|
9794
|
+
fields: {
|
|
9795
|
+
projectId: mcpProjectId,
|
|
9796
|
+
meetingId: f.string({ desc: MEETING_ID }),
|
|
9797
|
+
title: f.string({ desc: CHECKLIST_ITEM_TITLE }),
|
|
9798
|
+
newTitle: f.string({ desc: "The replacement text, as a single line.", min: 1 })
|
|
9799
|
+
}
|
|
9800
|
+
}
|
|
9801
|
+
});
|
|
9802
|
+
var removeMeetingChecklistItemContract = defineToolContract({
|
|
9803
|
+
name: "remove_meeting_checklist_item",
|
|
9804
|
+
agent: {
|
|
9805
|
+
description: `Delete one of a meeting's checklist items. For a step that turned out not to be needed. An item someone already ticked is a record that work happened \u2014 untick it or leave it rather than deleting it.`,
|
|
9806
|
+
fields: {
|
|
9807
|
+
meetingId: f.string({ desc: MEETING_ID }),
|
|
9808
|
+
title: f.string({ desc: CHECKLIST_ITEM_TITLE })
|
|
9809
|
+
}
|
|
9810
|
+
},
|
|
9811
|
+
mcp: {
|
|
9812
|
+
description: `Delete a meeting checklist item. Prefer unticking over deleting an item someone already completed. ${MCP_TAIL}`,
|
|
9813
|
+
fields: {
|
|
9814
|
+
projectId: mcpProjectId,
|
|
9815
|
+
meetingId: f.string({ desc: MEETING_ID }),
|
|
9816
|
+
title: f.string({ desc: CHECKLIST_ITEM_TITLE })
|
|
9817
|
+
}
|
|
9818
|
+
}
|
|
9819
|
+
});
|
|
9609
9820
|
var meetingsContracts = [
|
|
9610
9821
|
listMeetingsContract,
|
|
9611
9822
|
getMeetingContract,
|
|
9612
|
-
readMeetingTranscriptContract
|
|
9823
|
+
readMeetingTranscriptContract,
|
|
9824
|
+
createMeetingContract,
|
|
9825
|
+
updateMeetingContract,
|
|
9826
|
+
addMeetingChecklistItemsContract,
|
|
9827
|
+
checkMeetingChecklistItemContract,
|
|
9828
|
+
editMeetingChecklistItemContract,
|
|
9829
|
+
removeMeetingChecklistItemContract
|
|
9613
9830
|
];
|
|
9614
9831
|
var SINCE_MINUTES = f.optional(
|
|
9615
9832
|
f.number({
|
|
@@ -9744,9 +9961,9 @@ var TOOL_CONTRACTS = Object.fromEntries(
|
|
|
9744
9961
|
);
|
|
9745
9962
|
|
|
9746
9963
|
// src/tools/contract-tool.ts
|
|
9747
|
-
import { z as
|
|
9964
|
+
import { z as z13 } from "zod";
|
|
9748
9965
|
function agentShape(surface) {
|
|
9749
|
-
return compileShape(
|
|
9966
|
+
return compileShape(z13, surface.fields);
|
|
9750
9967
|
}
|
|
9751
9968
|
function defineContractTool(contract, handler, options) {
|
|
9752
9969
|
return {
|
|
@@ -9903,11 +10120,11 @@ function buildGetExecutionLogsTool(connection) {
|
|
|
9903
10120
|
"get_execution_logs",
|
|
9904
10121
|
"Read CLI execution logs \u2014 agent reasoning, tool calls, and setup/dev-server output. Filter via source='agent' or 'application'. For human chat use read_task_chat.",
|
|
9905
10122
|
{
|
|
9906
|
-
task_id:
|
|
10123
|
+
task_id: z14.string().optional().describe(
|
|
9907
10124
|
"Task ID or slug. Omit to read logs from the current task. Only the current task or one of its child tasks can be read."
|
|
9908
10125
|
),
|
|
9909
|
-
source:
|
|
9910
|
-
limit:
|
|
10126
|
+
source: z14.enum(["agent", "application"]).optional().describe("Filter by log source. Omit for all logs."),
|
|
10127
|
+
limit: z14.number().optional().describe("Max number of log entries to return (default 50, max 500).")
|
|
9911
10128
|
},
|
|
9912
10129
|
async ({ task_id, source, limit }) => {
|
|
9913
10130
|
try {
|
|
@@ -10002,7 +10219,7 @@ function buildTaskContextTools(connection) {
|
|
|
10002
10219
|
}
|
|
10003
10220
|
|
|
10004
10221
|
// src/tools/dependency-suggestion-tools.ts
|
|
10005
|
-
import { z as
|
|
10222
|
+
import { z as z15 } from "zod";
|
|
10006
10223
|
function buildGetDependenciesTool(connection) {
|
|
10007
10224
|
return defineContractTool(
|
|
10008
10225
|
getDependenciesContract,
|
|
@@ -10026,10 +10243,10 @@ function buildGetSuggestionsTool(connection) {
|
|
|
10026
10243
|
"get_suggestions",
|
|
10027
10244
|
"List project suggestions sorted by vote score. Filter by status or cap with limit (default 20). Suggestions are project-level ideas, not tasks \u2014 use get_task for tasks.",
|
|
10028
10245
|
{
|
|
10029
|
-
status:
|
|
10246
|
+
status: z15.string().optional().describe(
|
|
10030
10247
|
"Filter by status: Planning, Open, InProgress, ReviewPR, ReviewDev, ReviewLive, Complete, Cancelled"
|
|
10031
10248
|
),
|
|
10032
|
-
limit:
|
|
10249
|
+
limit: z15.number().int().min(1).max(100).optional().describe("Max results (default 20)")
|
|
10033
10250
|
},
|
|
10034
10251
|
async ({ status, limit }) => {
|
|
10035
10252
|
try {
|
|
@@ -10053,7 +10270,7 @@ function buildGetSuggestionsTool(connection) {
|
|
|
10053
10270
|
}
|
|
10054
10271
|
|
|
10055
10272
|
// src/tools/mutation-tools.ts
|
|
10056
|
-
import { z as
|
|
10273
|
+
import { z as z16 } from "zod";
|
|
10057
10274
|
|
|
10058
10275
|
// src/runner/refresh-verify-heal.ts
|
|
10059
10276
|
async function refreshAndVerifyGithubCredential(cwd, mint) {
|
|
@@ -10185,7 +10402,7 @@ function buildForceUpdateTaskStatusTool(connection) {
|
|
|
10185
10402
|
"force_update_task_status",
|
|
10186
10403
|
"EMERGENCY ONLY: force-override a task's Kanban status. Use when an automatic transition failed and the task is wedged. Normal flow transitions status automatically.",
|
|
10187
10404
|
{
|
|
10188
|
-
status:
|
|
10405
|
+
status: z16.enum([
|
|
10189
10406
|
"Planning",
|
|
10190
10407
|
"Open",
|
|
10191
10408
|
"InProgress",
|
|
@@ -10195,7 +10412,7 @@ function buildForceUpdateTaskStatusTool(connection) {
|
|
|
10195
10412
|
"Complete",
|
|
10196
10413
|
"Cancelled"
|
|
10197
10414
|
]).describe("The new status for the task"),
|
|
10198
|
-
task_id:
|
|
10415
|
+
task_id: z16.string().optional().describe("Child task ID to update. Omit to update the current task.")
|
|
10199
10416
|
},
|
|
10200
10417
|
async ({ status, task_id }) => {
|
|
10201
10418
|
try {
|
|
@@ -10348,10 +10565,10 @@ function buildCreateFollowUpTaskTool(connection) {
|
|
|
10348
10565
|
"create_follow_up_task",
|
|
10349
10566
|
"Create a follow-up task that depends on the current task. The new card is a SIBLING of this one (same parent) and is blocked until this task merges \u2014 it is NOT a child of this card. To break this card into child cards that build as a pack, use create_subtask. For blockers use add_dependency.",
|
|
10350
10567
|
{
|
|
10351
|
-
title:
|
|
10352
|
-
description:
|
|
10353
|
-
plan:
|
|
10354
|
-
story_point_value:
|
|
10568
|
+
title: z16.string().describe("Follow-up task title"),
|
|
10569
|
+
description: z16.string().optional().describe(cardDescriptionDesc("Brief description of the follow-up work")),
|
|
10570
|
+
plan: z16.string().optional().describe("Implementation plan if known"),
|
|
10571
|
+
story_point_value: z16.number().optional().describe("Story point estimate (1=Common, 2=Magic, 3=Rare, 5=Unique)")
|
|
10355
10572
|
},
|
|
10356
10573
|
async ({ title, description, plan, story_point_value }) => {
|
|
10357
10574
|
try {
|
|
@@ -10378,11 +10595,11 @@ function buildCreateSuggestionTool(connection) {
|
|
|
10378
10595
|
"create_suggestion",
|
|
10379
10596
|
"Suggest a feature, improvement, rule, or idea for the project. Duplicates are deduped and your upvote is recorded. For actionable work on this task open a follow-up task.",
|
|
10380
10597
|
{
|
|
10381
|
-
title:
|
|
10382
|
-
description:
|
|
10598
|
+
title: z16.string().describe("Short title for the suggestion"),
|
|
10599
|
+
description: z16.string().optional().describe(
|
|
10383
10600
|
"1-2 sentence description of what should change and why. Keep concise and project-focused."
|
|
10384
10601
|
),
|
|
10385
|
-
tag_names:
|
|
10602
|
+
tag_names: z16.array(z16.string()).optional().describe("Tag names to categorize the suggestion")
|
|
10386
10603
|
},
|
|
10387
10604
|
async ({ title, description, tag_names }) => {
|
|
10388
10605
|
try {
|
|
@@ -10411,8 +10628,8 @@ function buildVoteSuggestionTool(connection) {
|
|
|
10411
10628
|
"vote_suggestion",
|
|
10412
10629
|
"Vote +1 or -1 on a project suggestion. Use to express support or disagreement with a specific suggestion returned by get_suggestions.",
|
|
10413
10630
|
{
|
|
10414
|
-
suggestion_id:
|
|
10415
|
-
value:
|
|
10631
|
+
suggestion_id: z16.string().describe("The suggestion ID to vote on"),
|
|
10632
|
+
value: z16.number().refine((v) => v === 1 || v === -1, { message: "Value must be 1 or -1" }).describe("+1 to upvote, -1 to downvote")
|
|
10416
10633
|
},
|
|
10417
10634
|
async ({ suggestion_id, value }) => {
|
|
10418
10635
|
try {
|
|
@@ -10793,7 +11010,7 @@ function buildCommonTools(connection, config) {
|
|
|
10793
11010
|
}
|
|
10794
11011
|
|
|
10795
11012
|
// src/tools/pm-tools.ts
|
|
10796
|
-
import { z as
|
|
11013
|
+
import { z as z17 } from "zod";
|
|
10797
11014
|
|
|
10798
11015
|
// src/tools/task-update-tools.ts
|
|
10799
11016
|
var CURRENT_TASK_ONLY = ["title", "description", "plan", "githubBranch"];
|
|
@@ -10866,8 +11083,8 @@ function buildUpdateTaskTool(connection) {
|
|
|
10866
11083
|
"update_task_plan",
|
|
10867
11084
|
"Save the plan and/or description to the current task. In auto/building mode, save the plan BEFORE writing code and keep it current as the approach evolves \u2014 post it, then build; never pause the build waiting for approval. For children use update_subtask; for title/tags/PR use update_task_properties.",
|
|
10868
11085
|
{
|
|
10869
|
-
plan:
|
|
10870
|
-
description:
|
|
11086
|
+
plan: z17.string().optional().describe("The task plan in markdown"),
|
|
11087
|
+
description: z17.string().optional().describe(cardDescriptionDesc("Updated task description"))
|
|
10871
11088
|
},
|
|
10872
11089
|
async ({ plan, description }) => {
|
|
10873
11090
|
try {
|
|
@@ -10890,10 +11107,10 @@ function buildHandoffTool(connection) {
|
|
|
10890
11107
|
"handoff_to_agent",
|
|
10891
11108
|
"Hand this task off to an implementer agent for the build phase \u2014 mid-conversation, same session, no restart. Call this once the plan is compiled and saved (update_task). The server swaps this task to the difficulty-sized implementer agent (which may run at a different model level), announces the handoff in the activity log + chat, and switches you into build mode to start implementing. Size the work with the storyPoints arg (or set it first via update_task_properties). Returns the implementer's name + model.",
|
|
10892
11109
|
{
|
|
10893
|
-
storyPoints:
|
|
11110
|
+
storyPoints: z17.number().int().positive().optional().describe(
|
|
10894
11111
|
"Difficulty sizing (1=Common, 2=Magic, 3=Rare, 5=Unique, 8=Pack) \u2014 picks which implementer agent takes over. Omit to use the task's current story points."
|
|
10895
11112
|
),
|
|
10896
|
-
message:
|
|
11113
|
+
message: z17.string().optional().describe("Optional kickoff note posted to the chat alongside the handoff notice.")
|
|
10897
11114
|
},
|
|
10898
11115
|
async ({ storyPoints, message }) => {
|
|
10899
11116
|
try {
|
|
@@ -11044,7 +11261,7 @@ function buildPackTools(connection) {
|
|
|
11044
11261
|
"start_child_cloud_build",
|
|
11045
11262
|
"Start a cloud build (codespace) for a child task. Preconditions: child status is `Open`, story points set, and an agent assigned \u2014 satisfy all three with update_subtask (status/agentIdOrName/storyPointValue) first; none happen automatically. A PACK_CHILD_LIMIT error is backpressure, not failure: check list_subtasks packSlots for which children hold the in-flight slots, merge/stop one, then retry. On a feature-branch pack, dev is merged into the pack branch first so the child branches from a fresh base; a conflict is reported in the result and never blocks the launch.",
|
|
11046
11263
|
{
|
|
11047
|
-
childTaskId:
|
|
11264
|
+
childTaskId: z17.string().describe("The child task ID to start a cloud build for")
|
|
11048
11265
|
},
|
|
11049
11266
|
async ({ childTaskId }) => {
|
|
11050
11267
|
try {
|
|
@@ -11073,7 +11290,7 @@ Base sync: dev \u2192 ${sync.branch} failed \u2014 ${sync.error}. The child was
|
|
|
11073
11290
|
"stop_child_build",
|
|
11074
11291
|
"Send a graceful stop signal to a running child build's agent. Not a force-kill \u2014 the agent may take a moment to wind down. Stopping a child eventually frees its PACK_CHILD_LIMIT build slot (see list_subtasks packSlots).",
|
|
11075
11292
|
{
|
|
11076
|
-
childTaskId:
|
|
11293
|
+
childTaskId: z17.string().describe("The child task ID whose build should be stopped")
|
|
11077
11294
|
},
|
|
11078
11295
|
async ({ childTaskId }) => {
|
|
11079
11296
|
try {
|
|
@@ -11132,7 +11349,7 @@ function buildPmTools(connection, options) {
|
|
|
11132
11349
|
}
|
|
11133
11350
|
|
|
11134
11351
|
// src/tools/discovery-tools.ts
|
|
11135
|
-
import { z as
|
|
11352
|
+
import { z as z18 } from "zod";
|
|
11136
11353
|
var SP_DESCRIPTION2 = "Story point value (1=Common, 2=Magic, 3=Rare, 5=Unique). The key is 'storyPointValue' \u2014 not 'storyPoints'.";
|
|
11137
11354
|
var VALID_PROPERTY_KEYS = "title, storyPointValue, tagNames, githubPRUrl, githubBranch, risk";
|
|
11138
11355
|
function describeUpdatedFields(p) {
|
|
@@ -11151,12 +11368,12 @@ function buildDiscoveryTools(connection) {
|
|
|
11151
11368
|
"update_task_properties",
|
|
11152
11369
|
"Set one or more task properties in a single call. Valid keys: title, storyPointValue, tagNames, githubPRUrl, githubBranch, risk. All are optional \u2014 include only the ones you want to update (at least one). Unknown keys are rejected.",
|
|
11153
11370
|
{
|
|
11154
|
-
title:
|
|
11155
|
-
storyPointValue:
|
|
11156
|
-
tagNames:
|
|
11157
|
-
githubPRUrl:
|
|
11158
|
-
githubBranch:
|
|
11159
|
-
risk:
|
|
11371
|
+
title: z18.string().optional().describe("The new task title"),
|
|
11372
|
+
storyPointValue: z18.number().optional().describe(SP_DESCRIPTION2),
|
|
11373
|
+
tagNames: z18.array(z18.string()).optional().describe("Array of tag names to assign"),
|
|
11374
|
+
githubPRUrl: z18.string().url().optional().describe("GitHub pull request URL to link to this task"),
|
|
11375
|
+
githubBranch: z18.string().optional().describe("Set the GitHub branch name for this task (e.g. 'conveyor/my-feature-abc123')"),
|
|
11376
|
+
risk: z18.enum(["critical", "high", "medium", "low"]).nullable().optional().describe(
|
|
11160
11377
|
"Risk level \u2014 how much important surface the task touches (critical/high/medium/low). Pass null to clear."
|
|
11161
11378
|
)
|
|
11162
11379
|
},
|
|
@@ -11196,7 +11413,7 @@ function buildDiscoveryTools(connection) {
|
|
|
11196
11413
|
}
|
|
11197
11414
|
|
|
11198
11415
|
// src/tools/project-tools.ts
|
|
11199
|
-
import { z as
|
|
11416
|
+
import { z as z19 } from "zod";
|
|
11200
11417
|
|
|
11201
11418
|
// src/execution/context-path-verifier.ts
|
|
11202
11419
|
import { readFile as readFile2 } from "fs/promises";
|
|
@@ -11274,16 +11491,16 @@ function formatContextPathProblems(problems) {
|
|
|
11274
11491
|
}
|
|
11275
11492
|
|
|
11276
11493
|
// src/tools/project-tools.ts
|
|
11277
|
-
var CONTEXT_PATH_SHAPE =
|
|
11278
|
-
type:
|
|
11494
|
+
var CONTEXT_PATH_SHAPE = z19.object({
|
|
11495
|
+
type: z19.enum(["rule", "doc", "file", "folder"]).describe(
|
|
11279
11496
|
"Link kind \u2014 all paths are repo-relative; doc marks a synced project doc, which resolves from the workspace like rule/file"
|
|
11280
11497
|
),
|
|
11281
|
-
path:
|
|
11282
|
-
label:
|
|
11283
|
-
locator:
|
|
11498
|
+
path: z19.string().min(1).max(500).describe("Repo-relative path"),
|
|
11499
|
+
label: z19.string().max(100).optional(),
|
|
11500
|
+
locator: z19.string().min(1).max(CONTEXT_LINK_LOCATOR_MAX).regex(/^[^\r\n]*$/, "Locator cannot contain line breaks").optional().describe(
|
|
11284
11501
|
'Verified-link tether: text that must keep existing in the file. With locatorType "test" it must appear inside a real it/test/describe TITLE; with "code" anywhere in the file. Validated at write time against the checkout and re-checked by the periodic sweep \u2014 a rename/delete flags the link stale. Locators containing <> are placeholders and never checked.'
|
|
11285
11502
|
),
|
|
11286
|
-
locatorType:
|
|
11503
|
+
locatorType: z19.enum(["test", "code"]).optional().describe(
|
|
11287
11504
|
"How the locator must match \u2014 required iff locator is set; not valid on folder links"
|
|
11288
11505
|
)
|
|
11289
11506
|
}).refine((link) => link.locator === void 0 === (link.locatorType === void 0), {
|
|
@@ -11332,15 +11549,15 @@ function buildCreateTagTool(connection, projectId, workspaceDir) {
|
|
|
11332
11549
|
"create_tag",
|
|
11333
11550
|
"Create a project tag. Include a crisp description (\u2264255 chars \u2014 the summary) and contextPaths (rule/doc/file/folder links agents auto-load when working on matching tasks); put the full spec in overview. Set parentTagIds to place the tag in the hierarchy right away. Every contextPath is checked against the repo checkout \u2014 a path that does not exist, or whose type does not match what is on disk, rejects the whole call. Fails if the name already exists.",
|
|
11334
11551
|
{
|
|
11335
|
-
name:
|
|
11336
|
-
color:
|
|
11337
|
-
description:
|
|
11338
|
-
overview:
|
|
11339
|
-
overviewPath:
|
|
11552
|
+
name: z19.string().min(1).max(50),
|
|
11553
|
+
color: z19.string().regex(/^#[0-9a-fA-F]{6}$/).optional().describe("#RRGGBB (default gray)"),
|
|
11554
|
+
description: z19.string().max(TAG_DESCRIPTION_MAX).optional(),
|
|
11555
|
+
overview: z19.string().max(TAG_OVERVIEW_MAX).optional().describe("Full markdown glossary body \u2014 the term's spec"),
|
|
11556
|
+
overviewPath: z19.string().min(1).max(500).optional().describe(
|
|
11340
11557
|
"Repo file to source the overview from (base-branch content is served everywhere). A not-yet-merged path is fine \u2014 the tag serves the stored overview as fallback until the file lands."
|
|
11341
11558
|
),
|
|
11342
|
-
parentTagIds:
|
|
11343
|
-
contextPaths:
|
|
11559
|
+
parentTagIds: z19.array(z19.string()).max(25).optional().describe("Parent tag ids from list_tags (multi-parent DAG) to link at create time"),
|
|
11560
|
+
contextPaths: z19.array(CONTEXT_PATH_SHAPE).max(20).optional()
|
|
11344
11561
|
},
|
|
11345
11562
|
async ({ name, color, description, overview, overviewPath, parentTagIds, contextPaths }) => {
|
|
11346
11563
|
const rejection = await rejectBadContextPaths(contextPaths, workspaceDir);
|
|
@@ -11368,19 +11585,19 @@ function buildUpdateTagTool(connection, projectId, taskId, workspaceDir) {
|
|
|
11368
11585
|
"update_tag",
|
|
11369
11586
|
"Update a tag's name, color, description (\u2264255), markdown overview, parent tags, or contextPaths. contextPaths and parentTagIds are FULL replacements \u2014 include what you want to keep. ALWAYS pass a short reason; it lands in the tag's revision history (with your current card auto-stamped) so the team sees why the glossary changed. Every contextPath is checked against the repo checkout \u2014 a path that does not exist, or whose type does not match what is on disk, rejects the whole call and nothing is written.",
|
|
11370
11587
|
{
|
|
11371
|
-
tagId:
|
|
11372
|
-
name:
|
|
11373
|
-
color:
|
|
11374
|
-
description:
|
|
11375
|
-
overview:
|
|
11588
|
+
tagId: z19.string().describe("Tag id from list_tags"),
|
|
11589
|
+
name: z19.string().min(1).max(50).optional(),
|
|
11590
|
+
color: z19.string().regex(/^#[0-9a-fA-F]{6}$/).optional(),
|
|
11591
|
+
description: z19.string().max(TAG_DESCRIPTION_MAX).optional(),
|
|
11592
|
+
overview: z19.string().max(TAG_OVERVIEW_MAX).nullable().optional().describe(
|
|
11376
11593
|
"Full markdown glossary body; null clears it. REJECTED while overviewPath is set \u2014 edit the sourced file in the repo instead"
|
|
11377
11594
|
),
|
|
11378
|
-
overviewPath:
|
|
11595
|
+
overviewPath: z19.string().min(1).max(500).nullable().optional().describe(
|
|
11379
11596
|
"Repo file to source the overview from (null clears back to the stored overview). A not-yet-merged path is fine \u2014 the stored overview serves as fallback until the file lands on the base branch."
|
|
11380
11597
|
),
|
|
11381
|
-
parentTagIds:
|
|
11382
|
-
reason:
|
|
11383
|
-
contextPaths:
|
|
11598
|
+
parentTagIds: z19.array(z19.string()).max(25).optional().describe("Full-set replacement of the tag's parent tags (multi-parent DAG)"),
|
|
11599
|
+
reason: z19.string().max(TAG_REASON_MAX).optional().describe("One line on why \u2014 shown in the tag's revision history"),
|
|
11600
|
+
contextPaths: z19.array(CONTEXT_PATH_SHAPE).max(20).optional()
|
|
11384
11601
|
},
|
|
11385
11602
|
async ({
|
|
11386
11603
|
tagId,
|
|
@@ -11438,8 +11655,8 @@ function buildPostToProjectChatTool(connection, projectId) {
|
|
|
11438
11655
|
"post_to_project_chat",
|
|
11439
11656
|
"Post a markdown message to the PROJECT chat \u2014 use once at the end of an audit for the summary the team reads.",
|
|
11440
11657
|
{
|
|
11441
|
-
message:
|
|
11442
|
-
kind:
|
|
11658
|
+
message: z19.string().min(1).max(2e4),
|
|
11659
|
+
kind: z19.enum(["tag_audit_summary"]).optional().describe(
|
|
11443
11660
|
"Set to 'tag_audit_summary' when posting a tag-audit summary so it is also saved to the persistent tag history"
|
|
11444
11661
|
)
|
|
11445
11662
|
},
|
|
@@ -11458,7 +11675,7 @@ function buildGetProjectTaskTool(connection, projectId) {
|
|
|
11458
11675
|
"get_project_task",
|
|
11459
11676
|
"Fetch any task in the project by id or slug: title, description, plan, status, and metadata. The audit evidence trail starts here.",
|
|
11460
11677
|
{
|
|
11461
|
-
taskId:
|
|
11678
|
+
taskId: z19.string().describe("Task id or slug")
|
|
11462
11679
|
},
|
|
11463
11680
|
async ({ taskId }) => {
|
|
11464
11681
|
try {
|
|
@@ -11476,8 +11693,8 @@ function buildReadProjectTaskChatTool(connection, projectId) {
|
|
|
11476
11693
|
"read_project_task_chat",
|
|
11477
11694
|
"Read any project task's chat messages (newest last). role 'user' rows are HUMAN turns; 'assistant'/'system' rows are agent posts and activity-log entries.",
|
|
11478
11695
|
{
|
|
11479
|
-
taskId:
|
|
11480
|
-
limit:
|
|
11696
|
+
taskId: z19.string().describe("Task id or slug"),
|
|
11697
|
+
limit: z19.number().int().min(1).max(200).optional().describe("Messages to fetch (default 50)")
|
|
11481
11698
|
},
|
|
11482
11699
|
async ({ taskId, limit }) => {
|
|
11483
11700
|
try {
|
|
@@ -11499,9 +11716,9 @@ function buildGetProjectTaskLogsTool(connection, projectId) {
|
|
|
11499
11716
|
"get_project_task_logs",
|
|
11500
11717
|
"Read any project task's persisted agent event stream (message / tool_use / turn_end / error / completed). Turn boundaries are turn_end events. Entries are truncated to ~2KB each; max 500 per call.",
|
|
11501
11718
|
{
|
|
11502
|
-
taskId:
|
|
11503
|
-
limit:
|
|
11504
|
-
source:
|
|
11719
|
+
taskId: z19.string().describe("Task id or slug"),
|
|
11720
|
+
limit: z19.number().int().min(1).max(500).optional().describe("Entries to fetch (default 50)"),
|
|
11721
|
+
source: z19.enum(["agent", "application"]).optional().describe("Filter: 'agent' = model events (default useful for grading)")
|
|
11505
11722
|
},
|
|
11506
11723
|
async ({ taskId, limit, source }) => {
|
|
11507
11724
|
try {
|
|
@@ -11519,44 +11736,44 @@ function buildGetProjectTaskLogsTool(connection, projectId) {
|
|
|
11519
11736
|
{ annotations: { readOnlyHint: true } }
|
|
11520
11737
|
);
|
|
11521
11738
|
}
|
|
11522
|
-
var TURN_GRADE_SHAPE =
|
|
11523
|
-
turnIndex:
|
|
11524
|
-
phase:
|
|
11525
|
-
grade:
|
|
11526
|
-
reasoning:
|
|
11527
|
-
eventType:
|
|
11528
|
-
eventSummary:
|
|
11739
|
+
var TURN_GRADE_SHAPE = z19.object({
|
|
11740
|
+
turnIndex: z19.number().int().min(0),
|
|
11741
|
+
phase: z19.enum(["planning", "building", "human"]),
|
|
11742
|
+
grade: z19.enum(["correct", "neutral", "blunder"]),
|
|
11743
|
+
reasoning: z19.string(),
|
|
11744
|
+
eventType: z19.string().describe('e.g. "message", "tool_use", "human_message"'),
|
|
11745
|
+
eventSummary: z19.string().max(200).describe("\u2264120 chars of what happened this turn")
|
|
11529
11746
|
});
|
|
11530
|
-
var HUMAN_EVAL_SHAPE =
|
|
11531
|
-
messageIndex:
|
|
11532
|
-
rating:
|
|
11533
|
-
reasoning:
|
|
11747
|
+
var HUMAN_EVAL_SHAPE = z19.object({
|
|
11748
|
+
messageIndex: z19.number().int().min(0).describe("Index into the task's human messages, oldest first"),
|
|
11749
|
+
rating: z19.number().int().min(-1).max(1),
|
|
11750
|
+
reasoning: z19.string()
|
|
11534
11751
|
});
|
|
11535
11752
|
function buildReportTaskAuditResultTool(connection, projectId) {
|
|
11536
11753
|
return defineTool(
|
|
11537
11754
|
"report_task_audit_result",
|
|
11538
11755
|
"Persist one audited task's grades (call once per task after grading it). Pass error instead to mark the audit failed when the evidence is unusable.",
|
|
11539
11756
|
{
|
|
11540
|
-
taskId:
|
|
11541
|
-
summary:
|
|
11542
|
-
turnGrades:
|
|
11543
|
-
planningAccuracy:
|
|
11544
|
-
buildingAccuracy:
|
|
11545
|
-
humanAccuracy:
|
|
11546
|
-
planningCorrect:
|
|
11547
|
-
planningNeutral:
|
|
11548
|
-
planningBlunder:
|
|
11549
|
-
buildingCorrect:
|
|
11550
|
-
buildingNeutral:
|
|
11551
|
-
buildingBlunder:
|
|
11552
|
-
humanCorrect:
|
|
11553
|
-
humanNeutral:
|
|
11554
|
-
humanBlunder:
|
|
11555
|
-
humanEvaluations:
|
|
11556
|
-
suggestionIds:
|
|
11557
|
-
auditCostUsd:
|
|
11558
|
-
model:
|
|
11559
|
-
error:
|
|
11757
|
+
taskId: z19.string().describe("The audited task's id (NOT slug)"),
|
|
11758
|
+
summary: z19.string().describe("3-6 sentences: what went well, what was wasted"),
|
|
11759
|
+
turnGrades: z19.array(TURN_GRADE_SHAPE),
|
|
11760
|
+
planningAccuracy: z19.number().min(0).max(1).nullable(),
|
|
11761
|
+
buildingAccuracy: z19.number().min(0).max(1).nullable(),
|
|
11762
|
+
humanAccuracy: z19.number().min(0).max(1).nullable(),
|
|
11763
|
+
planningCorrect: z19.number().int().min(0),
|
|
11764
|
+
planningNeutral: z19.number().int().min(0),
|
|
11765
|
+
planningBlunder: z19.number().int().min(0),
|
|
11766
|
+
buildingCorrect: z19.number().int().min(0),
|
|
11767
|
+
buildingNeutral: z19.number().int().min(0),
|
|
11768
|
+
buildingBlunder: z19.number().int().min(0),
|
|
11769
|
+
humanCorrect: z19.number().int().min(0),
|
|
11770
|
+
humanNeutral: z19.number().int().min(0),
|
|
11771
|
+
humanBlunder: z19.number().int().min(0),
|
|
11772
|
+
humanEvaluations: z19.array(HUMAN_EVAL_SHAPE).optional(),
|
|
11773
|
+
suggestionIds: z19.array(z19.string()).describe("Suggestion ids filed for this task, or []"),
|
|
11774
|
+
auditCostUsd: z19.number().nullable(),
|
|
11775
|
+
model: z19.string().nullable().describe("The model you are running as"),
|
|
11776
|
+
error: z19.string().optional().describe("Set ONLY to mark this task's audit failed")
|
|
11560
11777
|
},
|
|
11561
11778
|
async (input) => {
|
|
11562
11779
|
try {
|
|
@@ -11849,6 +12066,13 @@ function errText4(prefix, error) {
|
|
|
11849
12066
|
return textResult(`${prefix}: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
11850
12067
|
}
|
|
11851
12068
|
function buildMeetingTools(connection, projectId) {
|
|
12069
|
+
return [
|
|
12070
|
+
...readTools(connection, projectId),
|
|
12071
|
+
...writeTools(connection, projectId),
|
|
12072
|
+
...checklistTools(connection, projectId)
|
|
12073
|
+
];
|
|
12074
|
+
}
|
|
12075
|
+
function readTools(connection, projectId) {
|
|
11852
12076
|
return [
|
|
11853
12077
|
defineContractTool(
|
|
11854
12078
|
listMeetingsContract,
|
|
@@ -11911,6 +12135,107 @@ ${res.lines.join("\n")}${footer}`);
|
|
|
11911
12135
|
)
|
|
11912
12136
|
];
|
|
11913
12137
|
}
|
|
12138
|
+
function writeTools(connection, projectId) {
|
|
12139
|
+
return [
|
|
12140
|
+
defineContractTool(createMeetingContract, async (input) => {
|
|
12141
|
+
try {
|
|
12142
|
+
const res = await connection.call("createProjectMeeting", {
|
|
12143
|
+
projectId,
|
|
12144
|
+
rawText: input.rawText,
|
|
12145
|
+
title: input.title,
|
|
12146
|
+
occurredAt: input.occurredAt
|
|
12147
|
+
});
|
|
12148
|
+
return textResult(
|
|
12149
|
+
`Created "${res.title}" (${res.segmentCount} segments, ${res.participants.length} participants).
|
|
12150
|
+
The AI summary is being written now; read it back with get_meeting in a few seconds.
|
|
12151
|
+
${res.url}`
|
|
12152
|
+
);
|
|
12153
|
+
} catch (error) {
|
|
12154
|
+
return errText4("Failed to create the meeting", error);
|
|
12155
|
+
}
|
|
12156
|
+
}),
|
|
12157
|
+
defineContractTool(updateMeetingContract, async (input) => {
|
|
12158
|
+
try {
|
|
12159
|
+
const res = await connection.call("updateProjectMeeting", {
|
|
12160
|
+
projectId,
|
|
12161
|
+
meetingId: input.meetingId,
|
|
12162
|
+
title: input.title,
|
|
12163
|
+
occurredAt: input.occurredAt,
|
|
12164
|
+
summary: input.summary
|
|
12165
|
+
});
|
|
12166
|
+
return textResult(`Updated "${res.title}".
|
|
12167
|
+
${res.url}`);
|
|
12168
|
+
} catch (error) {
|
|
12169
|
+
return errText4("Failed to update the meeting", error);
|
|
12170
|
+
}
|
|
12171
|
+
})
|
|
12172
|
+
];
|
|
12173
|
+
}
|
|
12174
|
+
function describeItem(item) {
|
|
12175
|
+
const box = item.checked ? "[x]" : "[ ]";
|
|
12176
|
+
const who = item.checked && item.checkedBy ? ` \u2014 ${item.checkedBy}` : "";
|
|
12177
|
+
const card = item.linkedTaskSlug ? ` (${item.linkedTaskSlug})` : "";
|
|
12178
|
+
return `${box} ${item.title}${who}${card}`;
|
|
12179
|
+
}
|
|
12180
|
+
function checklistTools(connection, projectId) {
|
|
12181
|
+
return [
|
|
12182
|
+
defineContractTool(addMeetingChecklistItemsContract, async (input) => {
|
|
12183
|
+
try {
|
|
12184
|
+
const res = await connection.call("addProjectMeetingChecklistItems", {
|
|
12185
|
+
projectId,
|
|
12186
|
+
meetingId: input.meetingId,
|
|
12187
|
+
items: input.items
|
|
12188
|
+
});
|
|
12189
|
+
if (res.length === 0) {
|
|
12190
|
+
return textResult("No items added \u2014 every title is already on this checklist.");
|
|
12191
|
+
}
|
|
12192
|
+
return textResult(`Added ${res.length}:
|
|
12193
|
+
${res.map(describeItem).join("\n")}`);
|
|
12194
|
+
} catch (error) {
|
|
12195
|
+
return errText4("Failed to add checklist items", error);
|
|
12196
|
+
}
|
|
12197
|
+
}),
|
|
12198
|
+
defineContractTool(checkMeetingChecklistItemContract, async (input) => {
|
|
12199
|
+
try {
|
|
12200
|
+
const res = await connection.call("checkProjectMeetingChecklistItem", {
|
|
12201
|
+
projectId,
|
|
12202
|
+
meetingId: input.meetingId,
|
|
12203
|
+
title: input.title,
|
|
12204
|
+
checked: input.checked,
|
|
12205
|
+
linkedTask: input.linkedTask
|
|
12206
|
+
});
|
|
12207
|
+
return textResult(describeItem(res));
|
|
12208
|
+
} catch (error) {
|
|
12209
|
+
return errText4("Failed to update the checklist item", error);
|
|
12210
|
+
}
|
|
12211
|
+
}),
|
|
12212
|
+
defineContractTool(editMeetingChecklistItemContract, async (input) => {
|
|
12213
|
+
try {
|
|
12214
|
+
const res = await connection.call("editProjectMeetingChecklistItem", {
|
|
12215
|
+
projectId,
|
|
12216
|
+
meetingId: input.meetingId,
|
|
12217
|
+
title: input.title,
|
|
12218
|
+
newTitle: input.newTitle
|
|
12219
|
+
});
|
|
12220
|
+
return textResult(describeItem(res));
|
|
12221
|
+
} catch (error) {
|
|
12222
|
+
return errText4("Failed to edit the checklist item", error);
|
|
12223
|
+
}
|
|
12224
|
+
}),
|
|
12225
|
+
defineContractTool(removeMeetingChecklistItemContract, async (input) => {
|
|
12226
|
+
try {
|
|
12227
|
+
const res = await connection.call("removeProjectMeetingChecklistItem", {
|
|
12228
|
+
projectId,
|
|
12229
|
+
meetingId: input.meetingId,
|
|
12230
|
+
title: input.title
|
|
12231
|
+
});
|
|
12232
|
+
return textResult(`Removed "${res.title}".`);
|
|
12233
|
+
} catch (error) {
|
|
12234
|
+
return errText4("Failed to remove the checklist item", error);
|
|
12235
|
+
}
|
|
12236
|
+
})
|
|
12237
|
+
];
|
|
12238
|
+
}
|
|
11914
12239
|
|
|
11915
12240
|
// src/tools/connected-tools.ts
|
|
11916
12241
|
function connectedToolsFor(connection, context) {
|
|
@@ -11930,7 +12255,7 @@ function connectedToolsFor(connection, context) {
|
|
|
11930
12255
|
// src/tools/code-review-tools.ts
|
|
11931
12256
|
import { execFile } from "child_process";
|
|
11932
12257
|
import { promisify } from "util";
|
|
11933
|
-
import { z as
|
|
12258
|
+
import { z as z20 } from "zod";
|
|
11934
12259
|
async function endReviewSession(connection, reason) {
|
|
11935
12260
|
await connection.call("endReviewSession", {
|
|
11936
12261
|
sessionId: connection.sessionId,
|
|
@@ -11938,26 +12263,26 @@ async function endReviewSession(connection, reason) {
|
|
|
11938
12263
|
});
|
|
11939
12264
|
}
|
|
11940
12265
|
var RISK_LEVELS2 = ["critical", "high", "medium", "low"];
|
|
11941
|
-
var reviewedShaSchema =
|
|
12266
|
+
var reviewedShaSchema = z20.string().regex(/^[0-9a-f]{40}$/i).describe("REQUIRED. The full 40-character commit SHA this verdict reviews.");
|
|
11942
12267
|
var riskDescription = "REQUIRED. The risk level this change carries, judged by the surface area it touches: critical = touches critical/foundational surface, high = important surface, medium = moderate, low = small/isolated. Set this on every verdict. You have authority to override a risk level already set on the task if you disagree with it.";
|
|
11943
|
-
var ReviewGuideToolSchema =
|
|
11944
|
-
reviewedSha:
|
|
12268
|
+
var ReviewGuideToolSchema = z20.strictObject({
|
|
12269
|
+
reviewedSha: z20.string().regex(/^[0-9a-f]{40}$/i).describe(
|
|
11945
12270
|
"REQUIRED. The PR's current head as a full 40-char SHA. Run `git rev-parse HEAD` immediately before this call \u2014 never extend an abbreviated hash into 40 characters."
|
|
11946
12271
|
),
|
|
11947
|
-
overview:
|
|
11948
|
-
sections:
|
|
11949
|
-
|
|
11950
|
-
title:
|
|
11951
|
-
explanation:
|
|
11952
|
-
classification:
|
|
11953
|
-
files:
|
|
11954
|
-
|
|
11955
|
-
path:
|
|
12272
|
+
overview: z20.string().min(1).max(6e4).describe("REQUIRED. Plain-text walkthrough intro, max 3000 characters. Keep it short."),
|
|
12273
|
+
sections: z20.array(
|
|
12274
|
+
z20.strictObject({
|
|
12275
|
+
title: z20.string().min(1).max(160),
|
|
12276
|
+
explanation: z20.string().min(1).max(2e3),
|
|
12277
|
+
classification: z20.enum(["core", "supporting"]).optional(),
|
|
12278
|
+
files: z20.array(
|
|
12279
|
+
z20.strictObject({
|
|
12280
|
+
path: z20.string().min(1).max(500).describe(
|
|
11956
12281
|
"A file the PR's diff actually changed. Context files you merely read are rejected."
|
|
11957
12282
|
),
|
|
11958
|
-
startLine:
|
|
11959
|
-
endLine:
|
|
11960
|
-
hunkHeader:
|
|
12283
|
+
startLine: z20.number().int().positive().max(1e6).optional(),
|
|
12284
|
+
endLine: z20.number().int().positive().max(1e6).optional(),
|
|
12285
|
+
hunkHeader: z20.string().min(1).max(300).optional().describe(
|
|
11961
12286
|
"Optional anchor, matched byte-exactly against the full hunk header line from `git diff` INCLUDING the context text after the second @@. Copy it verbatim from `git diff <base>..HEAD -- <file> | grep '^@@'`, or omit anchors entirely (path-only entries always validate)."
|
|
11962
12287
|
)
|
|
11963
12288
|
})
|
|
@@ -12041,8 +12366,8 @@ function buildApproveCodeReviewTool(connection) {
|
|
|
12041
12366
|
"Approve the code review and exit. Use when the diff passes all review criteria. Requires a summary and a risk level \u2014 for changes, use request_code_changes with a structured issues[] list.",
|
|
12042
12367
|
{
|
|
12043
12368
|
reviewedSha: reviewedShaSchema,
|
|
12044
|
-
summary:
|
|
12045
|
-
risk:
|
|
12369
|
+
summary: z20.string().describe("Brief summary of what was reviewed and why it looks good"),
|
|
12370
|
+
risk: z20.enum(RISK_LEVELS2).describe(riskDescription)
|
|
12046
12371
|
},
|
|
12047
12372
|
async ({ reviewedSha, summary, risk }) => {
|
|
12048
12373
|
const content = `**Code Review: Approved** :white_check_mark:
|
|
@@ -12073,16 +12398,16 @@ function buildRequestCodeChangesTool(connection) {
|
|
|
12073
12398
|
"Request changes during code review and exit. Use when substantive issues must be fixed before merge. Each issue: { file, line?, severity: critical|major|minor, description }.",
|
|
12074
12399
|
{
|
|
12075
12400
|
reviewedSha: reviewedShaSchema,
|
|
12076
|
-
issues:
|
|
12077
|
-
|
|
12078
|
-
file:
|
|
12079
|
-
line:
|
|
12080
|
-
severity:
|
|
12081
|
-
description:
|
|
12401
|
+
issues: z20.array(
|
|
12402
|
+
z20.object({
|
|
12403
|
+
file: z20.string().describe("File path where the issue was found"),
|
|
12404
|
+
line: z20.number().optional().describe("Line number (if applicable)"),
|
|
12405
|
+
severity: z20.enum(["critical", "major", "minor"]).describe("Issue severity"),
|
|
12406
|
+
description: z20.string().describe("What is wrong and how to fix it")
|
|
12082
12407
|
})
|
|
12083
12408
|
).describe("List of issues found during review"),
|
|
12084
|
-
summary:
|
|
12085
|
-
risk:
|
|
12409
|
+
summary: z20.string().describe("Brief overall summary of the review findings"),
|
|
12410
|
+
risk: z20.enum(RISK_LEVELS2).describe(riskDescription)
|
|
12086
12411
|
},
|
|
12087
12412
|
async ({ reviewedSha, issues, summary, risk }) => {
|
|
12088
12413
|
const issueLines = issues.map((issue) => {
|
|
@@ -12152,7 +12477,7 @@ function getModeTools(agentMode, connection, config, context) {
|
|
|
12152
12477
|
}
|
|
12153
12478
|
}
|
|
12154
12479
|
function buildPrGuideToolsFor(effectiveMode, connection, config, context) {
|
|
12155
|
-
const isLeafBuild = effectiveMode === "building" || effectiveMode === "auto";
|
|
12480
|
+
const isLeafBuild = effectiveMode === "building" || effectiveMode === "auto" || effectiveMode === "chat";
|
|
12156
12481
|
const isSinglePodPack = config.mode === "pack" && config.packExecution !== "fan-out";
|
|
12157
12482
|
return (isLeafBuild || isSinglePodPack) && (isSinglePodPack || !context?.isParentTask) ? [
|
|
12158
12483
|
buildPublishReviewGuideTool(connection, {
|
|
@@ -12639,10 +12964,14 @@ async function processAssistantCase(event, host, state) {
|
|
|
12639
12964
|
}
|
|
12640
12965
|
const usage = await handleAssistantCase(event, host, state.turnToolCalls);
|
|
12641
12966
|
if (usage) state.lastAssistantUsage = usage;
|
|
12642
|
-
if (!state.sawApiError) {
|
|
12967
|
+
if (!state.sawApiError || event.isApiError && !state.terminalApiError) {
|
|
12643
12968
|
const fullText = event.message.content.filter((b) => b.type === "text").map((b) => b.text).join(" ");
|
|
12644
12969
|
if (API_ERROR_PATTERN.test(fullText)) {
|
|
12645
12970
|
state.sawApiError = true;
|
|
12971
|
+
if (event.isApiError) {
|
|
12972
|
+
state.terminalApiError = true;
|
|
12973
|
+
state.apiErrorText = fullText.slice(0, 300);
|
|
12974
|
+
}
|
|
12646
12975
|
}
|
|
12647
12976
|
}
|
|
12648
12977
|
}
|
|
@@ -12657,7 +12986,7 @@ async function processResultCase(event, host, context, startTime, state) {
|
|
|
12657
12986
|
);
|
|
12658
12987
|
if (info.stoppedTyping) state.isTyping = false;
|
|
12659
12988
|
state.retriable = info.retriable;
|
|
12660
|
-
if (!info.retriable) state.sawApiError = false;
|
|
12989
|
+
if (!info.retriable && !state.terminalApiError) state.sawApiError = false;
|
|
12661
12990
|
state.resultSummary = info.resultSummary;
|
|
12662
12991
|
if (info.staleSession) state.staleSession = true;
|
|
12663
12992
|
if (info.authError) state.authError = true;
|
|
@@ -12678,6 +13007,8 @@ async function processEvents(events, context, host) {
|
|
|
12678
13007
|
isTyping: false,
|
|
12679
13008
|
retriable: false,
|
|
12680
13009
|
sawApiError: false,
|
|
13010
|
+
terminalApiError: false,
|
|
13011
|
+
apiErrorText: void 0,
|
|
12681
13012
|
resultSummary: void 0,
|
|
12682
13013
|
rateLimitResetsAt: void 0,
|
|
12683
13014
|
rateLimitRejectedType: void 0,
|
|
@@ -12720,8 +13051,12 @@ async function processEvents(events, context, host) {
|
|
|
12720
13051
|
}
|
|
12721
13052
|
flushPendingToolCalls(host, state.turnToolCalls);
|
|
12722
13053
|
stopTypingIfNeeded(host, state.isTyping);
|
|
13054
|
+
return buildProcessResult(state);
|
|
13055
|
+
}
|
|
13056
|
+
function buildProcessResult(state) {
|
|
12723
13057
|
return {
|
|
12724
13058
|
retriable: state.retriable || state.sawApiError,
|
|
13059
|
+
...state.apiErrorText && { apiErrorText: state.apiErrorText },
|
|
12725
13060
|
resultSummary: state.resultSummary,
|
|
12726
13061
|
rateLimitResetsAt: state.rateLimitResetsAt,
|
|
12727
13062
|
...state.rateLimitRejectedType && { rateLimitRejectedType: state.rateLimitRejectedType },
|
|
@@ -12964,25 +13299,6 @@ function handleReviewToolAccess(toolName, input) {
|
|
|
12964
13299
|
}
|
|
12965
13300
|
return handleBuildingToolAccess(toolName, input);
|
|
12966
13301
|
}
|
|
12967
|
-
var CHAT_BLOCKED_BASH = /\bgit\s+push\b|\bgh\s+pr\b|\bhub\s+pull-request\b/;
|
|
12968
|
-
var CREATE_PR_TOOL = /(^|__)create_pull_request$/;
|
|
12969
|
-
var CHAT_PLAN_GATE_MESSAGE = [
|
|
12970
|
-
"This chat card has no saved plan, so it has no PR path yet.",
|
|
12971
|
-
"If the conversation has turned into a development task, save a plan with update_task first \u2014 that identifies the card and moves it to In Progress \u2014 then commit, push, and open the PR.",
|
|
12972
|
-
"If it is still a conversation, deliver the work by attaching files to the card with upload_attachment instead."
|
|
12973
|
-
].join(" ");
|
|
12974
|
-
function isChatPrTool(toolName, input) {
|
|
12975
|
-
if (CREATE_PR_TOOL.test(toolName)) return true;
|
|
12976
|
-
return toolName === "Bash" && CHAT_BLOCKED_BASH.test(String(input.command ?? ""));
|
|
12977
|
-
}
|
|
12978
|
-
async function chatCardHasPlan(host) {
|
|
12979
|
-
try {
|
|
12980
|
-
const props = await host.connection.getTaskProperties();
|
|
12981
|
-
return !!props.plan?.trim();
|
|
12982
|
-
} catch {
|
|
12983
|
-
return false;
|
|
12984
|
-
}
|
|
12985
|
-
}
|
|
12986
13302
|
function handleAutoToolAccess(toolName, input, hasExitedPlanMode, isParentTask) {
|
|
12987
13303
|
if (hasExitedPlanMode) {
|
|
12988
13304
|
return isParentTask ? handleReviewToolAccess(toolName, input) : handleBuildingToolAccess(toolName, input);
|
|
@@ -13162,7 +13478,6 @@ function resolveToolAccess(host, toolName, input) {
|
|
|
13162
13478
|
}
|
|
13163
13479
|
function buildCanUseTool(host) {
|
|
13164
13480
|
let consecutiveDenials = 0;
|
|
13165
|
-
let chatHasPlan = false;
|
|
13166
13481
|
return async (toolName, input) => {
|
|
13167
13482
|
if (toolName === "ExitPlanMode" && (host.agentMode === "auto" || host.agentMode === "discovery") && !host.hasExitedPlanMode) {
|
|
13168
13483
|
return await handleExitPlanMode(host, input);
|
|
@@ -13178,14 +13493,6 @@ function buildCanUseTool(host) {
|
|
|
13178
13493
|
}
|
|
13179
13494
|
const loopResult = checkToolLoop(host, toolName, input);
|
|
13180
13495
|
if (loopResult) return loopResult;
|
|
13181
|
-
if (host.agentMode === "chat" && isChatPrTool(toolName, input)) {
|
|
13182
|
-
if (!chatHasPlan) chatHasPlan = await chatCardHasPlan(host);
|
|
13183
|
-
if (!chatHasPlan) {
|
|
13184
|
-
consecutiveDenials++;
|
|
13185
|
-
handleDenialEscalation(host, consecutiveDenials);
|
|
13186
|
-
return { behavior: "deny", message: CHAT_PLAN_GATE_MESSAGE };
|
|
13187
|
-
}
|
|
13188
|
-
}
|
|
13189
13496
|
const result = resolveToolAccess(host, toolName, input);
|
|
13190
13497
|
if (result.behavior === "deny") {
|
|
13191
13498
|
consecutiveDenials++;
|
|
@@ -13955,11 +14262,13 @@ function handleProcessResult(result, context, host, options) {
|
|
|
13955
14262
|
}
|
|
13956
14263
|
async function runWithRetry(initialQuery, context, host, options) {
|
|
13957
14264
|
let lastErrorWasImage = false;
|
|
14265
|
+
let lastDetail = null;
|
|
13958
14266
|
for (let attempt = 0; attempt <= RETRY_DELAYS_MS.length; attempt++) {
|
|
13959
14267
|
if (host.isStopped()) return;
|
|
13960
14268
|
const agentQuery = attempt === 0 ? initialQuery : await buildRetryQuery(host, context, options, lastErrorWasImage);
|
|
13961
14269
|
try {
|
|
13962
14270
|
const result = await processEvents(agentQuery, context, host);
|
|
14271
|
+
if (result.apiErrorText) lastDetail = result.apiErrorText;
|
|
13963
14272
|
const outcome = handleProcessResult(result, context, host, options);
|
|
13964
14273
|
if (outcome.action === "return") return;
|
|
13965
14274
|
if (outcome.action === "return_promise") return outcome.promise;
|
|
@@ -13968,12 +14277,16 @@ async function runWithRetry(initialQuery, context, host, options) {
|
|
|
13968
14277
|
const outcome = handleRetryError(error, context, host, options, lastErrorWasImage);
|
|
13969
14278
|
if (outcome instanceof Promise) return outcome;
|
|
13970
14279
|
if (outcome.action === "return") return;
|
|
14280
|
+
lastDetail = getErrorMessage(error).slice(0, 300);
|
|
13971
14281
|
lastErrorWasImage = outcome.lastErrorWasImage;
|
|
13972
14282
|
}
|
|
13973
14283
|
if (attempt >= RETRY_DELAYS_MS.length) {
|
|
14284
|
+
const detail = lastDetail ?? "API error";
|
|
13974
14285
|
host.connection.postChatMessage(
|
|
13975
|
-
`
|
|
14286
|
+
`Claude API calls kept failing (\`${detail}\`) through ${RETRY_DELAYS_MS.length} retries over ~${Math.round(RETRY_DELAYS_MS.reduce((a, b) => a + b, 0) / 6e4)} minutes. Handing the card back: it returns to Open and this environment goes to sleep.`
|
|
13976
14287
|
);
|
|
14288
|
+
host.apiOutageExhausted = true;
|
|
14289
|
+
host.apiOutageDetail = detail;
|
|
13977
14290
|
return;
|
|
13978
14291
|
}
|
|
13979
14292
|
await emitRetryStatus(host, attempt, RETRY_DELAYS_MS[attempt]);
|
|
@@ -14043,6 +14356,8 @@ var QueryBridge = class {
|
|
|
14043
14356
|
_isParentTask = false;
|
|
14044
14357
|
_wasRateLimited = false;
|
|
14045
14358
|
_wedgeAborted = false;
|
|
14359
|
+
_apiOutageExhausted = false;
|
|
14360
|
+
_apiOutageDetail = null;
|
|
14046
14361
|
_keyCycleCount = 0;
|
|
14047
14362
|
_abortController = null;
|
|
14048
14363
|
/** Called by SessionRunner when ExitPlanMode triggers a mode transition. */
|
|
@@ -14081,6 +14396,18 @@ var QueryBridge = class {
|
|
|
14081
14396
|
get lastTurnWedgeAborted() {
|
|
14082
14397
|
return this._wedgeAborted;
|
|
14083
14398
|
}
|
|
14399
|
+
/**
|
|
14400
|
+
* Whether the turn that just ran ended with every Claude API retry
|
|
14401
|
+
* exhausted. Reset at the start of every execute(); SessionRunner reads it
|
|
14402
|
+
* to flush WIP and hand the card back to the server.
|
|
14403
|
+
*/
|
|
14404
|
+
get lastTurnApiOutage() {
|
|
14405
|
+
return this._apiOutageExhausted;
|
|
14406
|
+
}
|
|
14407
|
+
/** The API error text behind `lastTurnApiOutage`, or null. */
|
|
14408
|
+
get lastTurnApiOutageDetail() {
|
|
14409
|
+
return this._apiOutageDetail;
|
|
14410
|
+
}
|
|
14084
14411
|
/**
|
|
14085
14412
|
* Ask the live terminal (PTY harness only) to redraw its full screen.
|
|
14086
14413
|
* Safe no-op on the SDK harness or between queries.
|
|
@@ -14155,6 +14482,8 @@ var QueryBridge = class {
|
|
|
14155
14482
|
this._stopped = false;
|
|
14156
14483
|
this._wasRateLimited = false;
|
|
14157
14484
|
this._wedgeAborted = false;
|
|
14485
|
+
this._apiOutageExhausted = false;
|
|
14486
|
+
this._apiOutageDetail = null;
|
|
14158
14487
|
this._abortController = new AbortController();
|
|
14159
14488
|
const host = this.buildHost();
|
|
14160
14489
|
try {
|
|
@@ -14204,7 +14533,7 @@ var QueryBridge = class {
|
|
|
14204
14533
|
// ── QueryHost construction ──────────────────────────────────────────
|
|
14205
14534
|
buildHost() {
|
|
14206
14535
|
const bridge = this;
|
|
14207
|
-
|
|
14536
|
+
const host = {
|
|
14208
14537
|
config: this.runnerConfig,
|
|
14209
14538
|
connection: this.connection,
|
|
14210
14539
|
callbacks: this.callbacks,
|
|
@@ -14247,12 +14576,6 @@ var QueryBridge = class {
|
|
|
14247
14576
|
set wasRateLimited(val) {
|
|
14248
14577
|
bridge._wasRateLimited = val;
|
|
14249
14578
|
},
|
|
14250
|
-
get wedgeAborted() {
|
|
14251
|
-
return bridge._wedgeAborted;
|
|
14252
|
-
},
|
|
14253
|
-
set wedgeAborted(val) {
|
|
14254
|
-
bridge._wedgeAborted = val;
|
|
14255
|
-
},
|
|
14256
14579
|
get keyCycleCount() {
|
|
14257
14580
|
return bridge._keyCycleCount;
|
|
14258
14581
|
},
|
|
@@ -14276,6 +14599,38 @@ var QueryBridge = class {
|
|
|
14276
14599
|
createInputStream: (prompt) => bridge.createInputStream(prompt),
|
|
14277
14600
|
onModeTransition: bridge.onModeTransition
|
|
14278
14601
|
};
|
|
14602
|
+
return Object.defineProperties(host, this.turnFlagDescriptors());
|
|
14603
|
+
}
|
|
14604
|
+
/**
|
|
14605
|
+
* The per-turn recovery flags the executor writes and SessionRunner reads
|
|
14606
|
+
* after the turn (`lastTurnWedgeAborted`, `lastTurnApiOutage`). Live
|
|
14607
|
+
* accessors onto the bridge's backing fields, attached as descriptors
|
|
14608
|
+
* because an object spread would snapshot a getter's value instead.
|
|
14609
|
+
*/
|
|
14610
|
+
turnFlagDescriptors() {
|
|
14611
|
+
return {
|
|
14612
|
+
wedgeAborted: {
|
|
14613
|
+
enumerable: true,
|
|
14614
|
+
get: () => this._wedgeAborted,
|
|
14615
|
+
set: (val) => {
|
|
14616
|
+
this._wedgeAborted = val;
|
|
14617
|
+
}
|
|
14618
|
+
},
|
|
14619
|
+
apiOutageExhausted: {
|
|
14620
|
+
enumerable: true,
|
|
14621
|
+
get: () => this._apiOutageExhausted,
|
|
14622
|
+
set: (val) => {
|
|
14623
|
+
this._apiOutageExhausted = val;
|
|
14624
|
+
}
|
|
14625
|
+
},
|
|
14626
|
+
apiOutageDetail: {
|
|
14627
|
+
enumerable: true,
|
|
14628
|
+
get: () => this._apiOutageDetail,
|
|
14629
|
+
set: (val) => {
|
|
14630
|
+
this._apiOutageDetail = val;
|
|
14631
|
+
}
|
|
14632
|
+
}
|
|
14633
|
+
};
|
|
14279
14634
|
}
|
|
14280
14635
|
// ── Input stream for Claude SDK ─────────────────────────────────────
|
|
14281
14636
|
async *createInputStream(prompt) {
|
|
@@ -15620,6 +15975,27 @@ var SessionRunner = class _SessionRunner {
|
|
|
15620
15975
|
}
|
|
15621
15976
|
throw err;
|
|
15622
15977
|
}
|
|
15978
|
+
await this.handleApiOutageExhausted();
|
|
15979
|
+
}
|
|
15980
|
+
/**
|
|
15981
|
+
* The turn ended with every Claude API retry exhausted (the CLI's own
|
|
15982
|
+
* retries gave up, then `runWithRetry`'s fresh-session backoff did too).
|
|
15983
|
+
* Push WIP first — the server sleeps this pod in response, so the flush
|
|
15984
|
+
* must not race the teardown — then hand the card back. The core loop
|
|
15985
|
+
* then falls into its normal idle wait; the server-driven sleep is what
|
|
15986
|
+
* ends the pod, and nothing here exits the process or re-prompts.
|
|
15987
|
+
*
|
|
15988
|
+
* NOT a stuck nudge: this keys on the CLI's own error record, never on
|
|
15989
|
+
* silence or idleness (see `.claude/rules/agent-runner.md`).
|
|
15990
|
+
*/
|
|
15991
|
+
async handleApiOutageExhausted() {
|
|
15992
|
+
if (!this.queryBridge?.lastTurnApiOutage) return;
|
|
15993
|
+
process.stderr.write("[conveyor-agent] API retries exhausted \u2014 handing the card back\n");
|
|
15994
|
+
await this.flushWipNow("WIP: API outage hand-off");
|
|
15995
|
+
this.connection.reportApiOutage(
|
|
15996
|
+
this.queryBridge.lastTurnApiOutageDetail ?? "API error",
|
|
15997
|
+
RETRY_DELAYS_MS.length
|
|
15998
|
+
);
|
|
15623
15999
|
}
|
|
15624
16000
|
/**
|
|
15625
16001
|
* A human typed into the parked, idle Connected-TUI (keep-alive PTY). Wake the
|