@letta-ai/letta-code 0.34.18 → 0.34.19

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 (53) hide show
  1. package/dist/gateway-core.js +2 -2
  2. package/dist/gateway-core.js.map +3 -3
  3. package/dist/mcp-client.js +2 -2
  4. package/dist/mcp-client.js.map +1 -1
  5. package/dist/mcp-oauth.js +2 -2
  6. package/dist/mcp-oauth.js.map +1 -1
  7. package/dist/types/agent/approval-execution.d.ts +33 -1
  8. package/dist/types/agent/approval-execution.d.ts.map +1 -1
  9. package/dist/types/agent/parent-memory-note.d.ts +3 -0
  10. package/dist/types/agent/parent-memory-note.d.ts.map +1 -0
  11. package/dist/types/agent/skills.d.ts.map +1 -1
  12. package/dist/types/agent/subagent-state.d.ts +53 -2
  13. package/dist/types/agent/subagent-state.d.ts.map +1 -1
  14. package/dist/types/channels/message-channel-executor.d.ts.map +1 -1
  15. package/dist/types/cli/helpers/agent-info.d.ts +1 -0
  16. package/dist/types/cli/helpers/agent-info.d.ts.map +1 -1
  17. package/dist/types/cli/subcommands/mcp.d.ts +3 -1
  18. package/dist/types/cli/subcommands/mcp.d.ts.map +1 -1
  19. package/dist/types/reminders/engine.d.ts.map +1 -1
  20. package/dist/types/telemetry/channel.d.ts.map +1 -1
  21. package/dist/types/tools/external-tool-background-eligibility.d.ts +2 -1
  22. package/dist/types/tools/external-tool-background-eligibility.d.ts.map +1 -1
  23. package/dist/types/tools/external-tool-background.d.ts +14 -1
  24. package/dist/types/tools/external-tool-background.d.ts.map +1 -1
  25. package/dist/types/tools/external-tool-types.d.ts +1 -0
  26. package/dist/types/tools/external-tool-types.d.ts.map +1 -1
  27. package/dist/types/tools/impl/external-coding-agent.d.ts.map +1 -1
  28. package/dist/types/tools/impl/monitor.d.ts +2 -0
  29. package/dist/types/tools/impl/monitor.d.ts.map +1 -1
  30. package/dist/types/tools/impl/task-abort-hook.d.ts +2 -0
  31. package/dist/types/tools/impl/task-abort-hook.d.ts.map +1 -0
  32. package/dist/types/tools/impl/task.d.ts.map +1 -1
  33. package/dist/types/tools/impl/watch-pr.d.ts +1 -1
  34. package/dist/types/tools/impl/watch-pr.d.ts.map +1 -1
  35. package/dist/types/tools/impl/workflow.d.ts +2 -0
  36. package/dist/types/tools/impl/workflow.d.ts.map +1 -1
  37. package/dist/types/tools/manager.d.ts +1 -1
  38. package/dist/types/tools/manager.d.ts.map +1 -1
  39. package/dist/types/tools/script-tool-scope.d.ts.map +1 -1
  40. package/dist/types/utils/subagent-scope.d.ts +13 -0
  41. package/dist/types/utils/subagent-scope.d.ts.map +1 -0
  42. package/dist/types/utils/task-notifications.d.ts +43 -0
  43. package/dist/types/utils/task-notifications.d.ts.map +1 -1
  44. package/letta.js +835 -288
  45. package/npm-shrinkwrap.json +14 -14
  46. package/package.json +2 -2
  47. package/scripts/claude-watch/docs-snapshot.test.ts +65 -0
  48. package/scripts/claude-watch/docs-snapshot.ts +10 -4
  49. package/scripts/isolated-unit-tests.json +5 -0
  50. package/scripts/source-file-size-baseline.json +8 -8
  51. package/skills/finding-agents/SKILL.md +0 -4
  52. package/skills/curating-memory-palace/SKILL.md +0 -147
  53. package/skills/migrating-memory/SKILL.md +0 -98
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@letta-ai/letta-code",
3
- "version": "0.34.18",
3
+ "version": "0.34.19",
4
4
  "lockfileVersion": 3,
5
5
  "packages": {
6
6
  "node_modules/@alcalzone/ansi-tokenize": {
@@ -2058,15 +2058,15 @@
2058
2058
  }
2059
2059
  },
2060
2060
  "node_modules/@shikijs/vscode-textmate": {
2061
- "version": "10.0.2",
2062
- "resolved": "https://registry.npmjs.org/@shikijs/vscode-textmate/-/vscode-textmate-10.0.2.tgz",
2063
- "integrity": "sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg==",
2061
+ "version": "10.1.0",
2062
+ "resolved": "https://registry.npmjs.org/@shikijs/vscode-textmate/-/vscode-textmate-10.1.0.tgz",
2063
+ "integrity": "sha512-cVBuhDQjBZaNMTwBquYfPydrUP+E3hE6oYGasx8h6ZrODIM7/r+gxLDXdd66oszbrggZHEntdE6j+5gYIVyMWQ==",
2064
2064
  "license": "MIT"
2065
2065
  },
2066
2066
  "node_modules/@smithy/core": {
2067
- "version": "3.36.0",
2068
- "resolved": "https://registry.npmjs.org/@smithy/core/-/core-3.36.0.tgz",
2069
- "integrity": "sha512-3hJiwG1F5t1SoXqp/yOCmYXziyx7ZVqF63S5W6YU201e/qwVaHPex+E/3vvyY9a3ORq/b+BydeNZpP2saQ9X2g==",
2067
+ "version": "3.36.1",
2068
+ "resolved": "https://registry.npmjs.org/@smithy/core/-/core-3.36.1.tgz",
2069
+ "integrity": "sha512-WC5W1Jrsfxu1y6LeqXMie7N14qmcdafij/Haye4feVlyMMXLGpYxBeOX6Ee1iRJbDzGG5LVman8U1rrt9MYFHA==",
2070
2070
  "license": "Apache-2.0",
2071
2071
  "dependencies": {
2072
2072
  "@smithy/types": "^4.19.0",
@@ -3197,9 +3197,9 @@
3197
3197
  "license": "Unlicense"
3198
3198
  },
3199
3199
  "node_modules/fast-uri": {
3200
- "version": "3.1.8",
3201
- "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.8.tgz",
3202
- "integrity": "sha512-GZMtZUTNRpOVIECoXwLNZS5xUGE+mVNbTB8h/7Rwh2TFWcBQiPzTgyZi05BF9UMZKkLJv8XBRJTlU7zg8+ZfMg==",
3200
+ "version": "3.1.9",
3201
+ "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.9.tgz",
3202
+ "integrity": "sha512-hS/0Wt3Ya043oKXs0sIxrMpKQITXhMLIrVAKKXi4gozGC9v7YRWVnXIZzjNPTO02M9BdxLCWqK1yRXgNziVyJQ==",
3203
3203
  "funding": [
3204
3204
  {
3205
3205
  "type": "github",
@@ -3792,9 +3792,9 @@
3792
3792
  "license": "ISC"
3793
3793
  },
3794
3794
  "node_modules/jose": {
3795
- "version": "6.2.12",
3796
- "resolved": "https://registry.npmjs.org/jose/-/jose-6.2.12.tgz",
3797
- "integrity": "sha512-9NiFmJEex0sy2Dk58j2UGBSHgUs2ypF9eZSu4L6vjOX3Dp96Sw1F3uL+H+D1sx02jZZdzUT0HgvCy59CuvXcWw==",
3795
+ "version": "6.2.13",
3796
+ "resolved": "https://registry.npmjs.org/jose/-/jose-6.2.13.tgz",
3797
+ "integrity": "sha512-7TIg10ZE1x82YediN+lcrPNvGMKge9yFHQD+Qho/b8y2adfugU3AsvvHfxV0fzyFllT6l9xCjf4RWY9g/Z9PJQ==",
3798
3798
  "license": "MIT",
3799
3799
  "funding": {
3800
3800
  "url": "https://github.com/sponsors/panva"
@@ -5452,7 +5452,7 @@
5452
5452
  },
5453
5453
  "": {
5454
5454
  "name": "@letta-ai/letta-code",
5455
- "version": "0.34.18",
5455
+ "version": "0.34.19",
5456
5456
  "dependencies": {
5457
5457
  "@earendil-works/pi-ai": "^0.99.1",
5458
5458
  "@janhapke/sharp-electron": "0.35.3-electron.1",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@letta-ai/letta-code",
3
- "version": "0.34.18",
3
+ "version": "0.34.19",
4
4
  "lettaStartupLogProtocol": 1,
5
5
  "description": "Letta Code is a CLI tool for interacting with stateful Letta agents from the terminal.",
6
6
  "type": "module",
@@ -275,5 +275,5 @@
275
275
  },
276
276
  "lettaLifecycleProtocol": 1,
277
277
  "lettaRuntimeGraphProtocol": 1,
278
- "lettaRuntimeGraphSha512": "sha512-cubBaizY8rbgiq9dfHU/uRyZBgkGvLfJc+8+ovpV1raZnQjE+tRsAKFAKP69UHWhNFRE49viVTyqmLIiSK8v8Q=="
278
+ "lettaRuntimeGraphSha512": "sha512-RWgzMK/RLJluHmJEAXwWV7NZe1gpOgg3BYpp8+G8QfqsXUUmzZgQpQz5E9CHogeIwfcGzCaHAUIdboH6Ir7KyA=="
279
279
  }
@@ -1,12 +1,14 @@
1
1
  import { describe, expect, test } from "bun:test";
2
2
  import {
3
3
  captureDocsSnapshot,
4
+ DEFAULT_LLMS_URL,
4
5
  deterministicSourcePath,
5
6
  diffDocsSnapshots,
6
7
  extractNamedChanges,
7
8
  hashDocsMarkdown,
8
9
  isWatchedDocsUrl,
9
10
  normalizeDocsMarkdown,
11
+ OFFICIAL_CHANGELOG_URL,
10
12
  parseLlmsTxt,
11
13
  sha256,
12
14
  unifiedDiff,
@@ -110,6 +112,69 @@ describe("official docs capture", () => {
110
112
  ).rejects.toThrow("outside https://docs.example");
111
113
  });
112
114
 
115
+ test("captures the official Claude Tag redirect without adding a second source", async () => {
116
+ const page = "https://code.claude.com/docs/en/claude-tag.md";
117
+ const target = "https://claude.com/docs/claude-tag";
118
+ const overview = "https://claude.com/docs/claude-tag/overview";
119
+ const calls: string[] = [];
120
+ const fetcher = fixtureFetch(
121
+ {
122
+ [DEFAULT_LLMS_URL]: page,
123
+ [OFFICIAL_CHANGELOG_URL]: "# Changelog\n",
124
+ [overview]: "# Work with Claude Tag\n",
125
+ },
126
+ calls,
127
+ );
128
+ const captured = await captureDocsSnapshot({
129
+ retries: 0,
130
+ fetch: (input, init) =>
131
+ String(input) === page || String(input) === target
132
+ ? Promise.resolve(
133
+ new Response(null, {
134
+ status: 307,
135
+ headers: {
136
+ location: String(input) === page ? target : overview,
137
+ },
138
+ }),
139
+ )
140
+ : fetcher(input, init),
141
+ });
142
+ expect(captured.snapshot.pages[page]?.hash).toBe(
143
+ hashDocsMarkdown("# Work with Claude Tag\n"),
144
+ );
145
+ expect(Object.keys(captured.snapshot.pages).sort()).toEqual(
146
+ [page, OFFICIAL_CHANGELOG_URL].sort(),
147
+ );
148
+ expect(calls.filter((url) => url === overview)).toHaveLength(1);
149
+ });
150
+
151
+ test.each([
152
+ [DEFAULT_LLMS_URL, "https://claude.com/docs/other-page"],
153
+ [DEFAULT_LLMS_URL, "https://claude.com/docs/claude-tag?redirect=other"],
154
+ [INDEX, "https://claude.com/docs/claude-tag"],
155
+ ])("rejects unapproved redirects from %s to %s", async (indexUrl, target) => {
156
+ const calls: string[] = [];
157
+ await expect(
158
+ captureDocsSnapshot({
159
+ indexUrl,
160
+ retries: 0,
161
+ fetch: async (input) => {
162
+ const url = String(input);
163
+ calls.push(url);
164
+ if (url === indexUrl)
165
+ return new Response(new URL("/en/tools.md", indexUrl).toString());
166
+ if (url === OFFICIAL_CHANGELOG_URL)
167
+ return new Response("# Changelog");
168
+ return new Response(null, {
169
+ status: 307,
170
+ headers: { location: target },
171
+ });
172
+ },
173
+ }),
174
+ ).rejects.toThrow("Refusing documentation URL");
175
+ expect(calls).not.toContain(target);
176
+ });
177
+
113
178
  test("detects added, removed, and changed pages with watched source previews", async () => {
114
179
  const oldCapture = await captureDocsSnapshot({
115
180
  indexUrl: INDEX,
@@ -185,9 +185,15 @@ export async function captureDocsSnapshot(
185
185
  const fetcher = options.fetch ?? globalThis.fetch;
186
186
  const indexUrl = options.indexUrl ?? DEFAULT_LLMS_URL;
187
187
  const allowedOrigin = new URL(indexUrl).origin;
188
- const fixedAllowedUrls = new Set(
189
- indexUrl === DEFAULT_LLMS_URL ? [OFFICIAL_CHANGELOG_URL] : [],
190
- );
188
+ const fixedSourceUrls =
189
+ indexUrl === DEFAULT_LLMS_URL ? [OFFICIAL_CHANGELOG_URL] : [];
190
+ const fixedAllowedUrls = new Set(fixedSourceUrls);
191
+ if (indexUrl === DEFAULT_LLMS_URL) {
192
+ // The indexed claude-tag.md page redirects through these two URLs. Do not
193
+ // fetch them separately or trust other URLs on claude.com.
194
+ fixedAllowedUrls.add("https://claude.com/docs/claude-tag");
195
+ fixedAllowedUrls.add("https://claude.com/docs/claude-tag/overview");
196
+ }
191
197
  const now = toDate(options.now ?? new Date());
192
198
  const indexText = await fetchText(
193
199
  indexUrl,
@@ -198,7 +204,7 @@ export async function captureDocsSnapshot(
198
204
  );
199
205
  const normalizedIndex = normalizeDocsMarkdown(indexText);
200
206
  const urls = [
201
- ...new Set([...parseLlmsTxt(indexText), ...fixedAllowedUrls]),
207
+ ...new Set([...parseLlmsTxt(indexText), ...fixedSourceUrls]),
202
208
  ].sort();
203
209
  const fullScan = shouldFullScan(options);
204
210
  const pages: Record<string, ClaudeDocsPageSnapshot> = {};
@@ -86,6 +86,11 @@
86
86
  "timeoutMs": 15000,
87
87
  "reason": "Imports the real media module while Slack adapter tests replace it."
88
88
  },
89
+ {
90
+ "path": "src/channels/message-channel-gateway-routing.test.ts",
91
+ "timeoutMs": 15000,
92
+ "reason": "Swaps the process-global backend via __testSetBackend(new FakeHeadlessBackend()) without restoring it; the fake backend's environmentRouting:false then leaks into every later suite in the same bun process (broke task-tool-assets 'keeps computer for the Cloud server' when test-selection changes co-located them in one shard)."
93
+ },
89
94
  {
90
95
  "path": "src/cli/subcommands/teleport.test.ts",
91
96
  "timeoutMs": 15000,
@@ -4,14 +4,14 @@
4
4
  "src/backend/local-backend.test.ts": 2472,
5
5
  "src/backend/local/local-store.ts": 3261,
6
6
  "src/backend/pi-stream-adapter.test.ts": 1255,
7
- "src/cli/app/AppCoordinator.tsx": 5101,
8
- "src/cli/app/AppView.tsx": 1729,
9
- "src/cli/app/use-approval-flow.ts": 1071,
7
+ "src/cli/app/AppCoordinator.tsx": 5131,
8
+ "src/cli/app/AppView.tsx": 1732,
9
+ "src/cli/app/use-approval-flow.ts": 1099,
10
10
  "src/cli/app/use-configuration-handlers.ts": 1417,
11
- "src/cli/app/use-conversation-loop.ts": 2860,
11
+ "src/cli/app/use-conversation-loop.ts": 2899,
12
12
  "src/cli/app/use-submit-handler.ts": 3797,
13
13
  "src/cli/components/AgentSelector.tsx": 1104,
14
- "src/cli/components/InputRich.tsx": 2116,
14
+ "src/cli/components/InputRich.tsx": 2124,
15
15
  "src/cli/components/ModelSelector.tsx": 1259,
16
16
  "src/cli/components/ProviderSelector.tsx": 1564,
17
17
  "src/cli/helpers/accumulator.ts": 1587,
@@ -19,7 +19,7 @@
19
19
  "src/cli/mods/local-mod-loader.test.ts": 1043,
20
20
  "src/cli/reflection-transcript.test.ts": 1084,
21
21
  "src/cli/subcommands/skills.ts": 1264,
22
- "src/headless.ts": 4771,
22
+ "src/headless.ts": 4851,
23
23
  "src/hooks/integration.test.ts": 1147,
24
24
  "src/index.ts": 2575,
25
25
  "src/mods/learning-harness.ts": 2434,
@@ -33,14 +33,14 @@
33
33
  "src/providers/chatgpt-usage-service.ts": 1112,
34
34
  "src/settings-manager.test.ts": 1635,
35
35
  "src/settings-manager.ts": 2092,
36
- "src/tools/manager.ts": 2606,
36
+ "src/tools/manager.ts": 2609,
37
37
  "src/tools/tool-execution-context.test.ts": 1092,
38
38
  "src/types/protocol_v2.ts": 2532,
39
- "src/websocket/listener/message-router.ts": 1005,
40
39
  "src/websocket/listen-client-concurrency.test.ts": 2557,
41
40
  "src/websocket/listen-client-protocol.test.ts": 5664,
42
41
  "src/websocket/listener/commands/memory.ts": 1114,
43
42
  "src/websocket/listener/file-commands.ts": 1045,
43
+ "src/websocket/listener/message-router.ts": 1005,
44
44
  "src/websocket/listener/protocol-inbound.ts": 2054,
45
45
  "src/websocket/listener/protocol-outbound.ts": 1001
46
46
  }
@@ -97,10 +97,6 @@ Returns the raw API response with full agent details. Key fields:
97
97
  - `tags` - Agent tags
98
98
  - `blocks` - Memory blocks (if `--include-blocks` used)
99
99
 
100
- ## Related Skills
101
-
102
- - **migrating-memory** - Once you find an agent, use this skill to copy/share memory blocks
103
-
104
100
  ### Finding Agents by Topic
105
101
 
106
102
  If you need to find which agent worked on a specific topic:
@@ -1,147 +0,0 @@
1
- ---
2
- name: curating-memory-palace
3
- description: Rules for the Memory Palace (palace/), the view on your Memory page in the Letta dashboard that shows the user where things stand, what you could do next, and how to make you more useful. Load it before creating or editing anything in palace/, when a message starts with "Palace action:" or "Palace reply on", and, when palace/ exists, whenever you notice a blocker, a decision for the user, work you could offer, or a routine that started, broke, or changed.
4
- ---
5
-
6
- # Curating the Memory Palace
7
-
8
- The Memory Palace is the page a user opens to understand you. Someone who has not looked in a week should know within 30 seconds:
9
-
10
- 1. **Where things stand:** what you are working on, which routines are running or broken, and what changed recently.
11
- 2. **What you could do next, and why:** work you noticed you can take on or pick back up.
12
- 3. **How to make you better or more independent:** one click to unblock you, fill a gap, or let you handle something on your own from now on.
13
-
14
- The user acts on it with buttons and replies. It is not a log, a transcript recap, or a page about the Palace itself.
15
-
16
- You can update the Palace yourself, in a conversation or during reflection, or an update can run on a schedule. Either works, and both follow these rules. "You" always means the agent that owns the Palace.
17
-
18
- ## Sections
19
-
20
- Every Palace starts with these three sections, in this order:
21
-
22
- 1. **Overview** (`overview.md`): a snapshot, not a to-do list. What you are working on now; each standing routine (schedules, digests, checks) and whether it is running or broken; one line on what changed since the last update.
23
- 2. **Needs Attention** (`needs-attention.md`): decisions and blockers waiting on the user. Every item has a button. If nothing waits on the user, say so in one line, such as "Nothing needs you right now."
24
- 3. **Suggestions** (`suggestions.md`): work you noticed you can do, including unfinished work to resume and routines you could take over. Each item says what prompted it, with a date, and has a button.
25
-
26
- Add up to three more sections only when they hold something the first three cannot, such as "Recently Learned". Merge or remove sections that overlap. At most six sections and three items per section. Keep the first three even when one has nothing to show, and say so in one line; delete an extra section, and its index line, when it is empty.
27
-
28
- ## Buttons
29
-
30
- A button sends its instruction to you, so offer only what you can do. Each button is one of three kinds:
31
-
32
- - **Do it now:** a one-off task, such as reviewing a PR, or a standing rule you record once when the user keeps approving the same kind of decision.
33
- - **Schedule:** recurring work you run without being asked, such as a weekly report or a daily check. The instruction asks you to set up the schedule. See "Offering a schedule".
34
- - **Fill a gap:** something you lack, such as a tool to connect, access or a permission to grant, or a question only the user can answer.
35
-
36
- Every blocker gets a button. When an item is a decision with real options, give each option its own button, two or three at most, so the user picks one: for example "Make it a ticket", "Assign it to Charles", and "Close it". Otherwise give the item one strong button, not several weak ones. The kinds are only for choosing buttons. Never write a kind's name, or any other caption, above a button.
37
-
38
- When only the user can fix something (raise a quota, attach a tool, log in), the item says what the user needs to do, and the button is still something you can do, such as "Walk me through fixing this" or "I fixed it, check again". For the second, re-run the failing check and clear the item if it passes.
39
-
40
- Offer the most reliable fix first, which usually means moving the work to Cloud. Anything that depends on the user's computer, such as a local schedule or a sign-in that lives on one machine, stops whenever that computer sleeps or Letta Code is closed. Offer to run the schedule in Cloud and to connect the account there before asking the user to keep a computer on. Suggest a fix on the user's computer only when Cloud cannot do the job, and say why.
41
-
42
- The headline says what is going on; the button says what to do. Never repeat the button's label in the headline, and do not end the text with a "Next: ..." sentence that restates the button. Write the headline "**Grok CLI regression may still be live.**" with the button "Verify the Grok CLI regression", not the headline "**Verify the Grok CLI regression.**"
43
-
44
- ### Offering a schedule
45
-
46
- Offer a Schedule button when the evidence shows recurring work: the user asked for the same thing on three or more days or said they want it regularly, you did the same manual check on three or more days, a deadline repeats, or something slipped that a regular check would have caught. If a routine you already run is broken, offer to fix it instead of adding another.
47
-
48
- Do not offer one for one-off work, for work that reports when it finishes (such as CI or a deploy), for anything more often than hourly, for work that needs the user during the run, or for anything on the Dismissed list. Offer at most two at a time.
49
-
50
- The label names the work and when it runs, with a time zone. The instruction asks you to set it up and says what to do, when, where to send results, and when to stay quiet. Set it up in Cloud unless the work truly needs one of the user's computers, record it in memory, and tell the user where it runs.
51
-
52
- ### Button format
53
-
54
- A fenced code block with the language `palace-action` becomes a button. It holds one strict JSON object and nothing else. Put it directly under its item. A Suggestions item with a Schedule button:
55
-
56
- ````markdown
57
- **The dependency report is still manual.** You asked for it on Sep 15, Sep 22, and Sep 29.
58
-
59
- ```palace-action
60
- {"actionId": "schedule-dep-report", "label": "Send the dependency report Mondays at 9am PT", "conversationId": "new", "instruction": "Set up a Cloud schedule for Mondays at 9am PT: run the dependency report, post it to #eng-deps, and skip weeks with no changes. Record it in memory and tell me where it runs."}
61
- ```
62
- ````
63
-
64
- - `actionId` (required): 1 to 64 characters, no spaces, unique within the section.
65
- - `label` (required): the button text, up to 80 characters. Start it with a verb; a confirmation such as "I fixed it, check again" is the one exception.
66
- - `instruction` (optional): what you do when it is clicked. An instruction over 300 characters renders as an error; aim for under 200. Name the work, where to find it, and any limits, not every detail. Count the characters with a short script rather than estimating.
67
- - `conversationId` (optional): one of your real conversation ids, or `new` for a fresh conversation. Leave it out to use the main chat.
68
-
69
- Any other key, or invalid JSON, renders the block as an error instead of a button.
70
-
71
- ## Files
72
-
73
- - Each Markdown file directly inside `palace/` is one section, except `palace/MEMORY.md`. Nested folders and other files are not shown, so do not create them.
74
- - The title comes from the file name: `needs-attention.md` shows as "Needs Attention". Keep the frontmatter `name` equal to the title.
75
- - Frontmatter holds exactly two non-empty keys, `name` and `description`. MemFS rejects any other key. The description shows under the title, so write it as the section's purpose in one short line.
76
- - The body is Markdown. The date beside the title is the file's last commit, so leave a file untouched when nothing in it changed.
77
- - The icon comes from the title: "attention" or "blocker" gives a flag, "overview" or "summary" a house, "learned" or "insight" a lightbulb, and "suggestions" or "next steps" a bolt. Most other titles get a note.
78
-
79
- `palace/MEMORY.md` is the index. It has no frontmatter. It lists the sections in display order, one relative link per line; the first mention of a file sets its place, and unlisted sections follow in file-name order. Keep it in sync when you add, rename, or remove a section, and keep the Feedback and Dismissed lists below the links:
80
-
81
- ```markdown
82
- # Memory Palace
83
-
84
- - [Overview](overview.md) - Where things stand
85
- - [Needs Attention](needs-attention.md) - Decisions and blockers waiting on you
86
- - [Suggestions](suggestions.md) - Work I can do next, and why
87
-
88
- ## Dismissed
89
-
90
- - Summaries of every Slack thread (Sep 20)
91
- ```
92
-
93
- Example `palace/needs-attention.md`:
94
-
95
- ````markdown
96
- ---
97
- name: Needs Attention
98
- description: Decisions and blockers waiting on you.
99
- ---
100
- **The nightly eval run has failed since Sep 24.** The OpenAI key is over its monthly quota. Raise the limit in the OpenAI billing settings; I can't change billing.
101
-
102
- ```palace-action
103
- {"actionId": "recheck-evals", "label": "I fixed it, check again", "instruction": "Re-run the eval smoke test. If it passes, clear this item; if not, say what still fails."}
104
- ```
105
- ````
106
-
107
- ## Writing rules
108
-
109
- - Lead with the point. An item is a short bold headline plus one sentence, two at most; what you need to act goes in the button's instruction.
110
- - Never paste a raw URL into the text. Name the thing and link the name, such as [LET-13139](https://linear.app/...), and never use a link as the headline.
111
- - Write in your own voice to the user: "I" for you, "you" for the user.
112
- - Write absolute dates, with a time zone when it matters, such as "Sep 25, 5pm PT". Never write "today" or "tomorrow": the Palace is read days later.
113
- - Distinguish what the user said, what you infer, and what you propose. Do not present guesses as facts or proposals as work already underway.
114
- - Make continuation offers concrete: name the unfinished work and the next step.
115
- - Outside Needs Attention and Suggestions, add a button only for a specific, useful action. Every section has a Reply button, so a section can exist just to show understanding.
116
- - Do not repeat an item in two sections.
117
- - No transcript restatements, timelines, or logs of your own work.
118
- - Never write secrets, tokens, keys, or credentials. The Palace is shown in the app and sent in messages.
119
-
120
- ## Signals from the user
121
-
122
- The user's reactions to the Palace are the strongest evidence of what they want.
123
-
124
- - A message that starts with "Palace reply on" is a reply to a section. Apply it. A dismissal ("drop this", "I don't care about X") means remove that item and add a short line to the Dismissed list.
125
- - A message that starts with "Palace action:" means the user clicked a button. The work it started shows what the user values. Clear or update the item once that work is done.
126
- - `palace/MEMORY.md` may have a "Feedback" list of notes the user left on sections. Apply each note, then remove it from the list.
127
- - `palace/MEMORY.md` may have a "Dismissed" list. Do not bring back anything on it unless something important has changed. Create the list the first time you need it.
128
-
129
- ## Updating the whole Palace
130
-
131
- For a scheduled update, a reflection, or when the user asks for one:
132
-
133
- 1. Read `palace/MEMORY.md` and every section first. If `palace/` does not exist, create it only when the user asked for a Palace or your instructions for this run say to.
134
- 2. Remove items that are done, no longer true, dismissed, or past a date with nothing left to do.
135
- 3. Add items the evidence supports and the user would want to see.
136
- 4. Edit sections in place and keep what is still true. Keep the first three sections first and in order.
137
- 5. Check each routine's latest runs when you can, not just what memory says. For schedules, find IDs with `letta cron list --agent <agent-id>` and inspect each with `letta cron runs --id <id> --agent <agent-id>`. Report their health in the Overview even when nothing changed.
138
- 6. Check every button against the format above before you save, counting each instruction's characters with a script.
139
-
140
- ## In a conversation
141
-
142
- This section applies only while you are talking with the user.
143
-
144
- - **Keep it current as you work.** If `palace/` exists and you notice a blocker, a decision for the user, work you could do, or a routine that changed, update the right section. Mention it in the conversation too if it matters now. Skip things that only matter inside this conversation.
145
- - **Set up or update.** When the user asks you to set up the Palace, build it from what you already know, starting with the three sections above. For an update, follow "Updating the whole Palace".
146
- - **A clicked button.** The app opens the button's conversation and sends one message. A hidden system reminder in it names the action, the section's path, and the section's current content. Do what the label and instruction ask, in that conversation, then update the item. A schedule you set up leaves Suggestions and joins the routines in the Overview.
147
- - **A reply.** The user's note comes with a hidden system reminder that holds the section's path and content. Apply it as described in "Signals from the user", answer any question in the conversation, and update the section if the answer changes it. Then reply briefly with what you changed.
@@ -1,98 +0,0 @@
1
- ---
2
- name: migrating-memory
3
- description: Migrate memory blocks from an existing agent to the current agent. Use when the user wants to copy or share memory from another agent, or during /init when setting up a new agent that should inherit memory from an existing one.
4
- ---
5
-
6
- # Migrating Memory
7
-
8
- This skill helps migrate memory blocks from an existing agent to a new agent, similar to macOS Migration Assistant for AI agents.
9
-
10
- > **Requires Memory Filesystem (memfs)**
11
- >
12
- > This workflow is memfs-first. If memfs is enabled, do **not** use the legacy block commands — they can conflict with file-based edits.
13
- >
14
- > **To check:** Look for a `memory_filesystem` block in your system prompt. If it shows a tree structure starting with `/memory/` including a `system/` directory, memfs is enabled.
15
- >
16
- > **To enable:** Ask the user to run `/memfs enable`, then reload the CLI.
17
-
18
- ## When to Use This Skill
19
-
20
- - User is setting up a new agent that should inherit memory from an existing one
21
- - User wants to share memory blocks across multiple agents
22
- - User is replacing an old agent with a new one
23
- - User mentions they have an existing agent with useful memory
24
-
25
- ## Migration Method (memfs-first)
26
-
27
- ### Export → Copy → Sync
28
-
29
- This is the recommended flow:
30
-
31
- 1. **Export the source agent's memfs to a temp directory**
32
- ```bash
33
- letta memory export --agent <source-agent-id> --out /tmp/letta-memory-<source-agent-id>
34
- ```
35
-
36
- 2. **Copy the files you want into your own memfs**
37
- - `system/` = attached blocks (always loaded)
38
- - root = detached blocks
39
-
40
- Example:
41
- ```bash
42
- cp -r /tmp/letta-memory-agent-abc123/system/project ~/.letta/agents/$LETTA_AGENT_ID/memory/system/
43
- cp /tmp/letta-memory-agent-abc123/notes.md ~/.letta/agents/$LETTA_AGENT_ID/memory/
44
- ```
45
-
46
- 3. **Commit and push the memory repo**
47
- ```bash
48
- cd ~/.letta/agents/$LETTA_AGENT_ID/memory
49
- git add system/project notes.md
50
- git commit -m "Import memory from source agent"
51
- git push
52
- ```
53
-
54
- This gives you full control over what you bring across and keeps everything consistent with memfs.
55
-
56
- ## If MemFS Is Disabled
57
-
58
- The legacy block-level CLI commands have been removed. Enable MemFS first, then use the export → copy → sync workflow above.
59
-
60
- If you run into duplicate filenames while copying memory files, rename the incoming file or merge its contents manually before committing.
61
-
62
- ## Workflow
63
-
64
- ### Step 1: Identify Source Agent
65
-
66
- Ask the user for the source agent's ID (e.g., `agent-abc123`).
67
-
68
- If they don't know the ID, invoke the **finding-agents** skill to search:
69
- ```
70
- Skill({ skill: "finding-agents" })
71
- ```
72
-
73
- Example: "What's the ID of the agent you want to migrate memory from?"
74
-
75
- ## Example: Migrating Project Memory
76
-
77
- Scenario: You're a new agent and want to inherit memory from an existing agent "ProjectX-v1".
78
-
79
- 1. **Get source agent ID from user:**
80
- User provides: `agent-abc123`
81
-
82
- 2. **Export their memfs:**
83
- ```bash
84
- letta memory export --agent agent-abc123 --out /tmp/letta-memory-agent-abc123
85
- ```
86
-
87
- 3. **Copy the relevant files into your memfs:**
88
- ```bash
89
- cp -r /tmp/letta-memory-agent-abc123/system/project ~/.letta/agents/$LETTA_AGENT_ID/memory/system/
90
- ```
91
-
92
- 4. **Commit and push:**
93
- ```bash
94
- cd ~/.letta/agents/$LETTA_AGENT_ID/memory
95
- git add system/project
96
- git commit -m "Import project memory"
97
- git push
98
- ```