@letta-ai/letta-code 0.30.32 → 0.31.0

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.
Files changed (61) hide show
  1. package/dist/agent-presets-agent-presets.js +11 -0
  2. package/dist/agent-presets-agent-presets.js.map +9 -0
  3. package/dist/agent-presets-personality-asset-content.js +42 -0
  4. package/dist/agent-presets-personality-asset-content.js.map +10 -0
  5. package/dist/agent-presets.js +17 -2
  6. package/dist/agent-presets.js.map +3 -3
  7. package/dist/channels-public.js +16 -1
  8. package/dist/channels-public.js.map +5 -4
  9. package/dist/gateway-core.js +5 -4
  10. package/dist/gateway-core.js.map +3 -3
  11. package/dist/mcp-client.js +2 -2
  12. package/dist/mcp-client.js.map +1 -1
  13. package/dist/types/agent/create-agent-request.d.ts +3 -0
  14. package/dist/types/agent/create-agent-request.d.ts.map +1 -1
  15. package/dist/types/agent/model.d.ts.map +1 -1
  16. package/dist/types/agent/personality-asset-content.d.ts +3 -0
  17. package/dist/types/agent/personality-asset-content.d.ts.map +1 -0
  18. package/dist/types/agent/skills.d.ts.map +1 -1
  19. package/dist/types/channels/gateway-core.d.ts.map +1 -1
  20. package/dist/types/channels/route-thread-key.d.ts +20 -0
  21. package/dist/types/channels/route-thread-key.d.ts.map +1 -0
  22. package/dist/types/channels-public.d.ts +1 -0
  23. package/dist/types/channels-public.d.ts.map +1 -1
  24. package/dist/types/tools/impl/skill.d.ts.map +1 -1
  25. package/dist/types/types/protocol_v2.d.ts +3 -144
  26. package/dist/types/types/protocol_v2.d.ts.map +1 -1
  27. package/dist/types/types/schedule-protocol.d.ts +151 -1
  28. package/dist/types/types/schedule-protocol.d.ts.map +1 -1
  29. package/dist/types/utils/frontmatter.d.ts.map +1 -1
  30. package/dist/types/websocket/listener/cwd-change.d.ts.map +1 -1
  31. package/letta.js +238 -86
  32. package/package.json +4 -2
  33. package/scripts/builtin-skills-watch/agent-watch.test.ts +104 -0
  34. package/scripts/builtin-skills-watch/agent-watch.ts +337 -0
  35. package/scripts/builtin-skills-watch/aggregate-results.test.ts +79 -0
  36. package/scripts/builtin-skills-watch/aggregate-results.ts +326 -0
  37. package/scripts/builtin-skills-watch/analysis.test.ts +70 -0
  38. package/scripts/builtin-skills-watch/analysis.ts +228 -0
  39. package/scripts/builtin-skills-watch/evidence.test.ts +114 -0
  40. package/scripts/builtin-skills-watch/evidence.ts +145 -0
  41. package/scripts/builtin-skills-watch/github.ts +161 -0
  42. package/scripts/builtin-skills-watch/tracker.test.ts +249 -0
  43. package/scripts/builtin-skills-watch/tracker.ts +506 -0
  44. package/scripts/builtin-skills-watch/update-tracker.test.ts +234 -0
  45. package/scripts/builtin-skills-watch/update-tracker.ts +508 -0
  46. package/scripts/claude-watch/release-source.test.ts +16 -4
  47. package/scripts/claude-watch/release-source.ts +41 -2
  48. package/scripts/codex-watch/agent-watch.ts +8 -5
  49. package/scripts/codex-watch/release-analysis.test.ts +18 -16
  50. package/scripts/codex-watch/release-analysis.ts +31 -9
  51. package/scripts/codex-watch/tracker.test.ts +5 -5
  52. package/scripts/codex-watch/tracker.ts +7 -8
  53. package/scripts/pi-ai-watch/agent-watch.ts +9 -14
  54. package/scripts/pi-ai-watch/release-analysis.test.ts +24 -18
  55. package/scripts/pi-ai-watch/release-analysis.ts +85 -45
  56. package/scripts/pi-ai-watch/tracker.test.ts +25 -18
  57. package/scripts/pi-ai-watch/tracker.ts +7 -19
  58. package/scripts/pi-ai-watch/update-tracker.ts +2 -2
  59. package/scripts/source-file-size-baseline.json +2 -2
  60. package/skills/dispatching-coding-agents/SKILL.md +16 -7
  61. package/skills/syncing-memory-filesystem/SKILL.md +118 -226
@@ -0,0 +1,234 @@
1
+ import { describe, expect, test } from "bun:test";
2
+ import type { BuiltinSkillWatchAnalysis } from "./analysis.ts";
3
+ import {
4
+ assertAnalysisIdentity,
5
+ type PullRequestView,
6
+ parseReviewResult,
7
+ type TrackerIssueView,
8
+ validatePullRequestView,
9
+ validateTrackerIssueView,
10
+ } from "./update-tracker.ts";
11
+
12
+ const URL = "https://github.com/letta-ai/letta-code/pull/123";
13
+ const CANDIDATE = "creating-skills@aaaaaaaaaaaa-abcdef0123456789";
14
+ const LOGIN = "watcher-agent";
15
+
16
+ describe("watcher PR validation", () => {
17
+ test("accepts an open draft with the exact candidate marker", () => {
18
+ expect(() =>
19
+ validatePullRequestView(validPullRequest(), URL, analysis(), LOGIN),
20
+ ).not.toThrow();
21
+ });
22
+
23
+ test("rejects the wrong author", () => {
24
+ expect(() =>
25
+ validatePullRequestView(
26
+ validPullRequest({ author: { login: "someone-else" } }),
27
+ URL,
28
+ analysis(),
29
+ LOGIN,
30
+ ),
31
+ ).toThrow("does not match");
32
+ });
33
+
34
+ test("rejects a ready or closed PR", () => {
35
+ expect(() =>
36
+ validatePullRequestView(
37
+ validPullRequest({ isDraft: false }),
38
+ URL,
39
+ analysis(),
40
+ LOGIN,
41
+ ),
42
+ ).toThrow("open and draft");
43
+ expect(() =>
44
+ validatePullRequestView(
45
+ validPullRequest({ state: "CLOSED" }),
46
+ URL,
47
+ analysis(),
48
+ LOGIN,
49
+ ),
50
+ ).toThrow("open and draft");
51
+ });
52
+
53
+ test("rejects a PR without the exact candidate marker", () => {
54
+ expect(() =>
55
+ validatePullRequestView(
56
+ validPullRequest({ body: "Builtin-skill-watch: another-candidate" }),
57
+ URL,
58
+ analysis(),
59
+ LOGIN,
60
+ ),
61
+ ).toThrow("missing Builtin-skill-watch");
62
+ });
63
+
64
+ test("rejects the wrong base or unrelated files", () => {
65
+ expect(() =>
66
+ validatePullRequestView(
67
+ validPullRequest({ baseRefName: "release" }),
68
+ URL,
69
+ analysis(),
70
+ LOGIN,
71
+ ),
72
+ ).toThrow("target main");
73
+ expect(() =>
74
+ validatePullRequestView(
75
+ validPullRequest({ files: [{ path: "src/cli/args.ts" }] }),
76
+ URL,
77
+ analysis(),
78
+ LOGIN,
79
+ ),
80
+ ).toThrow("outside the selected skill scope");
81
+ });
82
+ });
83
+
84
+ describe("watcher analysis validation", () => {
85
+ test("rejects a changed inventory even when the candidate ID is unchanged", () => {
86
+ const rebuilt = analysis();
87
+ const received = {
88
+ ...rebuilt,
89
+ skill_inventory: ["creating-skills"],
90
+ };
91
+
92
+ expect(() => assertAnalysisIdentity(received, rebuilt)).toThrow(
93
+ "skill_inventory",
94
+ );
95
+ });
96
+
97
+ test("rejects a changed skill digest", () => {
98
+ const rebuilt = analysis();
99
+ const received = { ...rebuilt, skill_digest: "f".repeat(64) };
100
+
101
+ expect(() => assertAnalysisIdentity(received, rebuilt)).toThrow(
102
+ "skill_digest",
103
+ );
104
+ });
105
+ });
106
+
107
+ describe("watcher result validation", () => {
108
+ test("accepts a terminal result bound to the candidate", () => {
109
+ const current = analysis();
110
+ const result = parseReviewResult(
111
+ {
112
+ schema_version: 1,
113
+ candidate_id: current.candidate_id,
114
+ skill: current.skill,
115
+ outcome: "no_drift",
116
+ notes: "current source and docs agree",
117
+ pr_url: null,
118
+ evidence: evidence(current),
119
+ },
120
+ current,
121
+ );
122
+
123
+ expect(result.outcome).toBe("no_drift");
124
+ });
125
+
126
+ test("rejects extra fields and PR URL mismatches", () => {
127
+ const current = analysis();
128
+ const base = {
129
+ schema_version: 1,
130
+ candidate_id: current.candidate_id,
131
+ skill: current.skill,
132
+ outcome: "no_drift",
133
+ notes: "current source and docs agree",
134
+ pr_url: null,
135
+ evidence: evidence(current),
136
+ };
137
+ expect(() => parseReviewResult({ ...base, secret: "no" }, current)).toThrow(
138
+ "does not match",
139
+ );
140
+ expect(() =>
141
+ parseReviewResult(
142
+ { ...base, pr_url: "https://github.com/letta-ai/letta-code/pull/1" },
143
+ current,
144
+ ),
145
+ ).toThrow("PR URL does not match");
146
+ });
147
+ });
148
+
149
+ describe("watcher tracker validation", () => {
150
+ test("accepts only the open Actions-owned tracker", () => {
151
+ const tracker = trackerIssue();
152
+ expect(() => validateTrackerIssueView(tracker)).not.toThrow();
153
+ expect(() =>
154
+ validateTrackerIssueView({ ...tracker, state: "CLOSED" }),
155
+ ).toThrow("closed or invalid");
156
+ expect(() =>
157
+ validateTrackerIssueView({
158
+ ...tracker,
159
+ author: { login: "someone-else" },
160
+ }),
161
+ ).toThrow("closed or invalid");
162
+ });
163
+ });
164
+
165
+ function validPullRequest(
166
+ overrides: Partial<PullRequestView> = {},
167
+ ): PullRequestView {
168
+ return {
169
+ author: { login: LOGIN },
170
+ baseRefName: "main",
171
+ body: `Builtin-skill-watch: ${CANDIDATE}`,
172
+ files: [
173
+ { path: "src/skills/builtin/creating-skills/SKILL.md" },
174
+ { path: "src/agent/skills-discovery.test.ts" },
175
+ ],
176
+ headRefOid: "c".repeat(40),
177
+ isDraft: true,
178
+ state: "OPEN",
179
+ url: URL,
180
+ ...overrides,
181
+ };
182
+ }
183
+
184
+ function analysis(): BuiltinSkillWatchAnalysis {
185
+ return {
186
+ schema_version: 1,
187
+ candidate_id: CANDIDATE,
188
+ skill: "creating-skills",
189
+ skill_path: "src/skills/builtin/creating-skills",
190
+ skill_files: ["src/skills/builtin/creating-skills/SKILL.md"],
191
+ skill_digest: "b".repeat(64),
192
+ current_sha: "a".repeat(40),
193
+ audit_at: "2026-08-26T00:00:00.000Z",
194
+ previous_audit: null,
195
+ repository_changes: {
196
+ previous_sha: null,
197
+ changed_files: [],
198
+ commits: [],
199
+ history_available: false,
200
+ truncated: false,
201
+ },
202
+ skill_inventory: ["creating-skills", "syncing-memory-filesystem"],
203
+ workflow_run_url: "https://github.com/letta-ai/letta-code/actions/runs/1",
204
+ };
205
+ }
206
+
207
+ function evidence(current: BuiltinSkillWatchAnalysis) {
208
+ return {
209
+ schema_version: 1,
210
+ candidate_id: current.candidate_id,
211
+ skill: current.skill,
212
+ sources: [
213
+ {
214
+ locator: current.skill_path,
215
+ revision: current.current_sha,
216
+ content_digest: current.skill_digest,
217
+ retrieved_at: current.audit_at,
218
+ excerpt: "the skill claim matches current source",
219
+ claims: ["checked current source"],
220
+ },
221
+ ],
222
+ probes: [],
223
+ };
224
+ }
225
+
226
+ function trackerIssue(): TrackerIssueView {
227
+ return {
228
+ author: { login: "app/github-actions" },
229
+ body: "tracker",
230
+ labels: [{ name: "builtin-skills-watch" }],
231
+ state: "OPEN",
232
+ title: "Built-in skill staleness tracker",
233
+ };
234
+ }