mastracode 0.36.0-alpha.9 → 0.36.1-alpha.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.
- package/CHANGELOG.md +116 -0
- package/dist/cli.cjs +6 -3
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +7 -4
- package/dist/cli.js.map +1 -1
- package/dist/tui/commands/github.d.ts.map +1 -1
- package/dist/{tui-5ivxiFIl.js → tui-BaobOqGM.js} +53 -11
- package/dist/tui-BaobOqGM.js.map +1 -0
- package/dist/{tui-JjrLDEgc.cjs → tui-Dg7vMm5_.cjs} +53 -11
- package/dist/tui-Dg7vMm5_.cjs.map +1 -0
- package/dist/tui.cjs +1 -1
- package/dist/tui.js +1 -1
- package/package.json +15 -15
- package/dist/tui-5ivxiFIl.js.map +0 -1
- package/dist/tui-JjrLDEgc.cjs.map +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,121 @@
|
|
|
1
1
|
# mastracode
|
|
2
2
|
|
|
3
|
+
## 0.36.1-alpha.0
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Cap mastra-crash.log size so it cannot grow without bound ([#22368](https://github.com/mastra-ai/mastra/pull/22368))
|
|
8
|
+
|
|
9
|
+
- Updated dependencies [[`7176362`](https://github.com/mastra-ai/mastra/commit/717636281a3339911a05ea2cc8ae38afe4fd2cef), [`e3b796d`](https://github.com/mastra-ai/mastra/commit/e3b796d29a63f0d5c97dd815aadec40687346d70), [`e3b796d`](https://github.com/mastra-ai/mastra/commit/e3b796d29a63f0d5c97dd815aadec40687346d70), [`49ccd14`](https://github.com/mastra-ai/mastra/commit/49ccd142268a61fb55ea75bc76287643a21f3677), [`3855b38`](https://github.com/mastra-ai/mastra/commit/3855b38c4c25af32ab8e298e148becc963abe92c)]:
|
|
10
|
+
- @mastra/core@1.63.0-alpha.0
|
|
11
|
+
- @mastra/observability@1.17.3-alpha.0
|
|
12
|
+
- @mastra/code-sdk@1.5.1-alpha.0
|
|
13
|
+
- @mastra/mcp@1.17.2
|
|
14
|
+
|
|
15
|
+
## 0.36.0
|
|
16
|
+
|
|
17
|
+
### Minor Changes
|
|
18
|
+
|
|
19
|
+
- Added review and working modes to MastraCode GitHub subscriptions. ([#21542](https://github.com/mastra-ai/mastra/pull/21542))
|
|
20
|
+
|
|
21
|
+
```text
|
|
22
|
+
/github subscribe 42 --mode review
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
- Made language-server (LSP) support opt-in in Mastra Code. By default Mastra Code no longer checks for LSP dependencies, starts language servers, or offers the lsp_inspect tool to the agent. Turn it on by adding "lsp": true (or an LSP config object) to your settings.json; "lsp": false is now also accepted and preserved. ([#22126](https://github.com/mastra-ai/mastra/pull/22126))
|
|
26
|
+
|
|
27
|
+
### Patch Changes
|
|
28
|
+
|
|
29
|
+
- Added browser-safe thinking command helpers so Mastra Code interfaces can share command parsing, model capabilities, and default resolution. ([#22198](https://github.com/mastra-ai/mastra/pull/22198))
|
|
30
|
+
|
|
31
|
+
```ts
|
|
32
|
+
import { parseThinkCommand, resolveDefaultThinkingLevel } from '@mastra/code-sdk/thinking';
|
|
33
|
+
|
|
34
|
+
const action = parseThinkCommand('high');
|
|
35
|
+
const fallback = resolveDefaultThinkingLevel({ globalDefault: 'medium', modeDefaults: { plan: 'high' } }, 'plan');
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
- Improved the provider device-code sign-in dialog. The code is now the main element with an inline copy button, and copy failures show an error instead of failing silently. ([#22186](https://github.com/mastra-ai/mastra/pull/22186))
|
|
39
|
+
|
|
40
|
+
- Improved long-session terminal performance by coalescing background renders, drawing status animations without re-rendering the full component tree, preserving completed component caches, and retaining a smaller rendered scrollback. ([#22073](https://github.com/mastra-ai/mastra/pull/22073))
|
|
41
|
+
|
|
42
|
+
- Added a Web search provider setting to /settings for choosing the default web_search/web_extract provider (Tavily or Parallel). Every provider stays visible in the selector; ones missing their API key are marked unavailable with the env var to set, and Auto uses the first configured key. ([#22216](https://github.com/mastra-ai/mastra/pull/22216))
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
PARALLEL_API_KEY=your-api-key npx mastracode
|
|
46
|
+
# then: /settings → Web search provider → Parallel
|
|
47
|
+
# and in chat: "Use web_search to find the latest Mastra release"
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
- Add a `/context` command (alias `/ctx`) to Mastra Code that reports what is occupying the context window. ([#22131](https://github.com/mastra-ai/mastra/pull/22131))
|
|
51
|
+
|
|
52
|
+
The report separates the startup context — system prompt, AGENTS.md/CLAUDE.md instructions with their source paths, the skills catalog, and MCP tool definitions rolled up per server — from context that accumulates during the session, namely the conversation itself and any observation memory injected into it. Each line carries an estimated token count and its share of the audited total, so it is possible to see which server, instruction file, or skill set is worth pruning.
|
|
53
|
+
|
|
54
|
+
The audit reports only sizes and labels, never the audited content, and is printed to the terminal without being added to the conversation, so running it does not enlarge the context it describes.
|
|
55
|
+
|
|
56
|
+
To support exact measurement, `@mastra/core` now exports `formatSkillsCatalog`, the pure formatter behind the skills processor's `<available_skills>` block, and `@mastra/code-sdk` exposes the assembled system prompt as labeled sections.
|
|
57
|
+
|
|
58
|
+
- Made the slash-command autocomplete dropdown in Mastra Code compact and scannable when many skills are installed. Only the highlighted item now shows its full wrapped description; other items stay on a single line with a truncated description. Fixes https://github.com/mastra-ai/mastra/issues/21967 ([#22101](https://github.com/mastra-ai/mastra/pull/22101))
|
|
59
|
+
|
|
60
|
+
- Fixed background system messages (such as MCP server connection and authentication logs) pushing an active prompt off-screen during startup. Update prompts and plan approvals now stay anchored at the bottom of the conversation while background output is inserted above them, so the prompt stays visible and usable. ([#22109](https://github.com/mastra-ai/mastra/pull/22109))
|
|
61
|
+
|
|
62
|
+
- Updated dependencies [[`79f04a7`](https://github.com/mastra-ai/mastra/commit/79f04a7f6c6829da541139f638f2f1d267916e08), [`65edab1`](https://github.com/mastra-ai/mastra/commit/65edab1c233d17b8f163bad12fca410d0e6f16b1), [`db6940e`](https://github.com/mastra-ai/mastra/commit/db6940ea63b76df2bc0a7c105a493342b9eaf0ec), [`1e47b75`](https://github.com/mastra-ai/mastra/commit/1e47b7520cab4cfaa8daed52f17e2e6d14ff7539), [`ab20a38`](https://github.com/mastra-ai/mastra/commit/ab20a38d0275f8d85e0f3833bd87ef487bcc609f), [`fd4d5fe`](https://github.com/mastra-ai/mastra/commit/fd4d5fe4f943699b85db5e74404f190d5a6b8c2a), [`c5eaec5`](https://github.com/mastra-ai/mastra/commit/c5eaec5a860d80d0e3805e67db0414b87ac8cbed), [`ae8790c`](https://github.com/mastra-ai/mastra/commit/ae8790c4bfaa088d2ab279d1dcc06f326b9fd109), [`2c85f42`](https://github.com/mastra-ai/mastra/commit/2c85f428e04ccd63ea31a7ec80b5b327afdad555), [`04a815f`](https://github.com/mastra-ai/mastra/commit/04a815fc8971d29e97fcdcc5008a1eb472fc00ff), [`11bbeb9`](https://github.com/mastra-ai/mastra/commit/11bbeb9b108ef2264e05acefc6dafb9cbb342921), [`48ef1f1`](https://github.com/mastra-ai/mastra/commit/48ef1f1d24eedafbb07f64e659a81b52b67b8bf6), [`aa3a85d`](https://github.com/mastra-ai/mastra/commit/aa3a85daf094c683bb97efdf4b6a696d2e474af5), [`15f92d0`](https://github.com/mastra-ai/mastra/commit/15f92d02bcacac7506346709d88b8bf11ae11695), [`d29d06f`](https://github.com/mastra-ai/mastra/commit/d29d06fe00bbd35b4571150ea04c59d2ed783c71), [`f9172b3`](https://github.com/mastra-ai/mastra/commit/f9172b35de085f9101348eeb60d7d4712505ed8f), [`e737014`](https://github.com/mastra-ai/mastra/commit/e737014e0fc7035759762bb5b48baef1d6c0f6a7), [`dfb7efa`](https://github.com/mastra-ai/mastra/commit/dfb7efa19e348b5a788be2d954362cbae12379d6), [`e6516df`](https://github.com/mastra-ai/mastra/commit/e6516dfcdae4f4ac0e7971d84359a81385ee602f), [`1a485f3`](https://github.com/mastra-ai/mastra/commit/1a485f3538f5ec64d58bd8b5e1e99de0c695c87b), [`0d37487`](https://github.com/mastra-ai/mastra/commit/0d37487d9f349388a3f1cef6a536cf9dcc4b6273), [`8661d7d`](https://github.com/mastra-ai/mastra/commit/8661d7d7179f0a024456aabdd8679bcecd09ac28), [`dbbfeb8`](https://github.com/mastra-ai/mastra/commit/dbbfeb85ec949dc9ebc0755e1ad262e4f5eba8db), [`575e343`](https://github.com/mastra-ai/mastra/commit/575e343900451021d96110916497d334af7bc252), [`0b2a3d1`](https://github.com/mastra-ai/mastra/commit/0b2a3d1783875c5b97b7b36ab3d03d7360e0dde7), [`8661d7d`](https://github.com/mastra-ai/mastra/commit/8661d7d7179f0a024456aabdd8679bcecd09ac28), [`6bb5d71`](https://github.com/mastra-ai/mastra/commit/6bb5d7193fe9166b219f0fccae17db7a5ae86e65), [`3cc9d00`](https://github.com/mastra-ai/mastra/commit/3cc9d00b2b4333e0377a5e9df5eff92c17ce7630), [`cacb839`](https://github.com/mastra-ai/mastra/commit/cacb8392d9e74189b56d857290b0615f98a2683d), [`57de7d6`](https://github.com/mastra-ai/mastra/commit/57de7d644ba7146edb4e9e6111ec4fa98c3a59e9), [`c8e4cea`](https://github.com/mastra-ai/mastra/commit/c8e4ceac9a390d78c8327dff3cdb2861dd71957f), [`ed01e9a`](https://github.com/mastra-ai/mastra/commit/ed01e9a807514a904374bf687a7b8f18750f6f78), [`b47b26e`](https://github.com/mastra-ai/mastra/commit/b47b26e6fe95cb8a3482be2c5e52de157fe59d0b), [`0d37487`](https://github.com/mastra-ai/mastra/commit/0d37487d9f349388a3f1cef6a536cf9dcc4b6273), [`8661d7d`](https://github.com/mastra-ai/mastra/commit/8661d7d7179f0a024456aabdd8679bcecd09ac28), [`733a537`](https://github.com/mastra-ai/mastra/commit/733a537489a858b5880b2e98809334fba895a221), [`e8e299c`](https://github.com/mastra-ai/mastra/commit/e8e299cc6abdfc39947e2fec25803493015d3882), [`edfc548`](https://github.com/mastra-ai/mastra/commit/edfc548886bc7bae17b681f8b6b41a47eb32bcd2), [`d55807c`](https://github.com/mastra-ai/mastra/commit/d55807cb9f080f3f5d1db06aca02b8fe0992507e), [`b05f486`](https://github.com/mastra-ai/mastra/commit/b05f48612984d5fe2447ea2d6cdd5c604d285b97), [`a981e66`](https://github.com/mastra-ai/mastra/commit/a981e662ed8fc476292375d135cb14a2681efedf), [`a8a4871`](https://github.com/mastra-ai/mastra/commit/a8a4871215f51da95c47129602157ce5372f634a), [`41c24e3`](https://github.com/mastra-ai/mastra/commit/41c24e376e1c61974af9aa0b48d4e0091e476dcc), [`ee0c1a0`](https://github.com/mastra-ai/mastra/commit/ee0c1a097de3acebe7dfc8c136479d4cb5b5b451), [`4bc0650`](https://github.com/mastra-ai/mastra/commit/4bc0650a49114480bf9b5bd318d679941f726823), [`eb9ecaa`](https://github.com/mastra-ai/mastra/commit/eb9ecaa89c36e889749e3b825cfc507ce7f7980b), [`befbfc2`](https://github.com/mastra-ai/mastra/commit/befbfc260d5ec5ece7cdb65a80e94292f428d4c9), [`4ff3ee2`](https://github.com/mastra-ai/mastra/commit/4ff3ee2bff7ed07528b4817f8f49639031c72a4d), [`c7d2ac2`](https://github.com/mastra-ai/mastra/commit/c7d2ac245e6e549f3ee8b6c019fd43fd352fb528), [`e6c3c14`](https://github.com/mastra-ai/mastra/commit/e6c3c14c27fe0b46137c9593b1ad81df1cb46d72), [`9207dfa`](https://github.com/mastra-ai/mastra/commit/9207dfab8062e5fc68b751684797ff86fe0b4e70), [`13c2f97`](https://github.com/mastra-ai/mastra/commit/13c2f979a63ee441834ad0d947b40a82010afb59), [`5165cdc`](https://github.com/mastra-ai/mastra/commit/5165cdcdcf50e144bb8113278535196cc9b07065), [`e737014`](https://github.com/mastra-ai/mastra/commit/e737014e0fc7035759762bb5b48baef1d6c0f6a7), [`6bb5d71`](https://github.com/mastra-ai/mastra/commit/6bb5d7193fe9166b219f0fccae17db7a5ae86e65), [`f591643`](https://github.com/mastra-ai/mastra/commit/f591643becdf0be9bddce6ba1748e64bc30d77f1), [`63796ba`](https://github.com/mastra-ai/mastra/commit/63796ba0fda60253be17535e68f6bbbf1e6ffa09), [`b1ad324`](https://github.com/mastra-ai/mastra/commit/b1ad324d657f3544b0701332aef7eb10e9a36258), [`61c566d`](https://github.com/mastra-ai/mastra/commit/61c566dd2f2cde2b23ed8f139924e530d4202214), [`9a3d352`](https://github.com/mastra-ai/mastra/commit/9a3d352a5ba0c2a9e4f7a9cc4f028a393bc74306), [`c24754c`](https://github.com/mastra-ai/mastra/commit/c24754c1fb6fe144e5051e536e98c8a18b0214ac), [`12c61d2`](https://github.com/mastra-ai/mastra/commit/12c61d280c8cb208bc3c8dbcbe5dcc60cf9d1cd0), [`bbd4486`](https://github.com/mastra-ai/mastra/commit/bbd4486b7296d6fd0de7177344f87fbbc0bb4fff), [`ae2dc20`](https://github.com/mastra-ai/mastra/commit/ae2dc201dbb48466c3cf77e3d4ef04826132b2db), [`9c984f9`](https://github.com/mastra-ai/mastra/commit/9c984f9152c0ded45453f21cb1f517fe12f8beae), [`6bb5d71`](https://github.com/mastra-ai/mastra/commit/6bb5d7193fe9166b219f0fccae17db7a5ae86e65), [`c46eb09`](https://github.com/mastra-ai/mastra/commit/c46eb09ce4987509af57a0ac582c61241a6dd2f1), [`9ee8120`](https://github.com/mastra-ai/mastra/commit/9ee8120ce17f76b9f617489e05a283353742690a), [`cd7683d`](https://github.com/mastra-ai/mastra/commit/cd7683d3040bc322ec6f6efb6f9c1e8e40f062a1), [`e737014`](https://github.com/mastra-ai/mastra/commit/e737014e0fc7035759762bb5b48baef1d6c0f6a7), [`d975e92`](https://github.com/mastra-ai/mastra/commit/d975e924d4936f46c386bd3dee39c671720289f6), [`45dd6ee`](https://github.com/mastra-ai/mastra/commit/45dd6ee089bd7df0d0c98a10098e483fd388e04a), [`4e9a228`](https://github.com/mastra-ai/mastra/commit/4e9a2283d5fd6ed1b70a2751eb3dc2cbf82ada20), [`d6ce34a`](https://github.com/mastra-ai/mastra/commit/d6ce34aeceb06ddf3d595a1eed5cc74f481a46a1), [`f95f468`](https://github.com/mastra-ai/mastra/commit/f95f468cf1e7c2b924a13826494f98b8f2ccd581), [`30ed33e`](https://github.com/mastra-ai/mastra/commit/30ed33ee14084a26019aba15fceadda6d6ddefaf), [`cb0291c`](https://github.com/mastra-ai/mastra/commit/cb0291cca0f8a769495375ff213cbda2512bb542), [`04a815f`](https://github.com/mastra-ai/mastra/commit/04a815fc8971d29e97fcdcc5008a1eb472fc00ff), [`1cfa878`](https://github.com/mastra-ai/mastra/commit/1cfa8784d8da0dfaa0317e5048bc48b6084a5ea5), [`997cf5b`](https://github.com/mastra-ai/mastra/commit/997cf5bb3fc600b30aa20e048b663e48e0e1305a), [`9a12ef3`](https://github.com/mastra-ai/mastra/commit/9a12ef3fccf3f4186db0f294f4ee1f02cf4d8db2), [`db6940e`](https://github.com/mastra-ai/mastra/commit/db6940ea63b76df2bc0a7c105a493342b9eaf0ec), [`32d3583`](https://github.com/mastra-ai/mastra/commit/32d358332cb8ac2306b83b73cf3536e74dbd435e), [`7960688`](https://github.com/mastra-ai/mastra/commit/7960688828e04eaf3106e34f7758fa580257eef6), [`91ad69d`](https://github.com/mastra-ai/mastra/commit/91ad69d64994c89199b0c55399e64ed91c61df2f), [`c4e2364`](https://github.com/mastra-ai/mastra/commit/c4e2364742bc37beebfa995db2d42efce6cfc7b8), [`8dc408d`](https://github.com/mastra-ai/mastra/commit/8dc408d34438f9e13297f792c11a5cfd6cf952e1), [`c92def1`](https://github.com/mastra-ai/mastra/commit/c92def10a13c822972c96f0a4ca6ffc1f4258aed), [`63041eb`](https://github.com/mastra-ai/mastra/commit/63041eb4c50b520a0a80e03d4cd6ea99f67715a0), [`c118318`](https://github.com/mastra-ai/mastra/commit/c1183181c9804303db4b511c2e2648f8b714712b), [`c5eaec5`](https://github.com/mastra-ai/mastra/commit/c5eaec5a860d80d0e3805e67db0414b87ac8cbed), [`fc07c64`](https://github.com/mastra-ai/mastra/commit/fc07c6465043e08e99193a6751a01c56ffc2e7a1), [`cced745`](https://github.com/mastra-ai/mastra/commit/cced745a056ec2225c5bc702e32d848847aa8b65), [`542dee2`](https://github.com/mastra-ai/mastra/commit/542dee254167f974ff8cbbbfc0ce10f9a2616a7b), [`b05f486`](https://github.com/mastra-ai/mastra/commit/b05f48612984d5fe2447ea2d6cdd5c604d285b97), [`3c19dce`](https://github.com/mastra-ai/mastra/commit/3c19dcef8e73062a80627a4927eae3ec11145afd), [`aca2869`](https://github.com/mastra-ai/mastra/commit/aca2869b2031982f3c4a2f52525c9be7cf123ef8), [`8dcd635`](https://github.com/mastra-ai/mastra/commit/8dcd6357f0d9557cebc727d7abc6901af6231e4f), [`a58483c`](https://github.com/mastra-ai/mastra/commit/a58483cff1a9d41fce7c931843f48cb0ac450f64), [`a58483c`](https://github.com/mastra-ai/mastra/commit/a58483cff1a9d41fce7c931843f48cb0ac450f64), [`e6f8450`](https://github.com/mastra-ai/mastra/commit/e6f845074d478527026b18d85031b23353e1d0a4), [`895e9df`](https://github.com/mastra-ai/mastra/commit/895e9dfc17d6f34299eca64e317ded9e5f5e5ef8), [`e66b2ba`](https://github.com/mastra-ai/mastra/commit/e66b2ba100db63eaeab6e21e1ea34b113f2ec781), [`3e8727e`](https://github.com/mastra-ai/mastra/commit/3e8727e11ec1a5d733acedb5c872896394be18c1)]:
|
|
63
|
+
- @mastra/core@1.62.0
|
|
64
|
+
- @mastra/libsql@1.22.0
|
|
65
|
+
- @mastra/pg@1.22.0
|
|
66
|
+
- @mastra/code-sdk@1.5.0
|
|
67
|
+
- @mastra/github-signals@0.3.0
|
|
68
|
+
- @mastra/duckdb@1.6.3
|
|
69
|
+
- @mastra/mcp@1.17.2
|
|
70
|
+
- @mastra/memory@1.28.0
|
|
71
|
+
- @mastra/fastembed@1.3.0
|
|
72
|
+
- @mastra/observability@1.17.2
|
|
73
|
+
|
|
74
|
+
## 0.36.0-alpha.12
|
|
75
|
+
|
|
76
|
+
### Patch Changes
|
|
77
|
+
|
|
78
|
+
- Updated dependencies [[`48ef1f1`](https://github.com/mastra-ai/mastra/commit/48ef1f1d24eedafbb07f64e659a81b52b67b8bf6), [`63796ba`](https://github.com/mastra-ai/mastra/commit/63796ba0fda60253be17535e68f6bbbf1e6ffa09), [`3c19dce`](https://github.com/mastra-ai/mastra/commit/3c19dcef8e73062a80627a4927eae3ec11145afd)]:
|
|
79
|
+
- @mastra/core@1.62.0-alpha.12
|
|
80
|
+
- @mastra/code-sdk@1.5.0-alpha.12
|
|
81
|
+
|
|
82
|
+
## 0.36.0-alpha.11
|
|
83
|
+
|
|
84
|
+
### Minor Changes
|
|
85
|
+
|
|
86
|
+
- Added review and working modes to MastraCode GitHub subscriptions. ([#21542](https://github.com/mastra-ai/mastra/pull/21542))
|
|
87
|
+
|
|
88
|
+
```text
|
|
89
|
+
/github subscribe 42 --mode review
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### Patch Changes
|
|
93
|
+
|
|
94
|
+
- Updated dependencies [[`15f92d0`](https://github.com/mastra-ai/mastra/commit/15f92d02bcacac7506346709d88b8bf11ae11695), [`4ff3ee2`](https://github.com/mastra-ai/mastra/commit/4ff3ee2bff7ed07528b4817f8f49639031c72a4d), [`c24754c`](https://github.com/mastra-ai/mastra/commit/c24754c1fb6fe144e5051e536e98c8a18b0214ac), [`cd7683d`](https://github.com/mastra-ai/mastra/commit/cd7683d3040bc322ec6f6efb6f9c1e8e40f062a1), [`45dd6ee`](https://github.com/mastra-ai/mastra/commit/45dd6ee089bd7df0d0c98a10098e483fd388e04a), [`32d3583`](https://github.com/mastra-ai/mastra/commit/32d358332cb8ac2306b83b73cf3536e74dbd435e), [`aca2869`](https://github.com/mastra-ai/mastra/commit/aca2869b2031982f3c4a2f52525c9be7cf123ef8)]:
|
|
95
|
+
- @mastra/github-signals@0.3.0-alpha.0
|
|
96
|
+
- @mastra/core@1.62.0-alpha.11
|
|
97
|
+
- @mastra/memory@1.28.0-alpha.4
|
|
98
|
+
- @mastra/code-sdk@1.5.0-alpha.11
|
|
99
|
+
|
|
100
|
+
## 0.36.0-alpha.10
|
|
101
|
+
|
|
102
|
+
### Patch Changes
|
|
103
|
+
|
|
104
|
+
- Added a Web search provider setting to /settings for choosing the default web_search/web_extract provider (Tavily or Parallel). Every provider stays visible in the selector; ones missing their API key are marked unavailable with the env var to set, and Auto uses the first configured key. ([#22216](https://github.com/mastra-ai/mastra/pull/22216))
|
|
105
|
+
|
|
106
|
+
```bash
|
|
107
|
+
PARALLEL_API_KEY=your-api-key npx mastracode
|
|
108
|
+
# then: /settings → Web search provider → Parallel
|
|
109
|
+
# and in chat: "Use web_search to find the latest Mastra release"
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
- Updated dependencies [[`b05f486`](https://github.com/mastra-ai/mastra/commit/b05f48612984d5fe2447ea2d6cdd5c604d285b97), [`41c24e3`](https://github.com/mastra-ai/mastra/commit/41c24e376e1c61974af9aa0b48d4e0091e476dcc), [`4bc0650`](https://github.com/mastra-ai/mastra/commit/4bc0650a49114480bf9b5bd318d679941f726823), [`7960688`](https://github.com/mastra-ai/mastra/commit/7960688828e04eaf3106e34f7758fa580257eef6), [`b05f486`](https://github.com/mastra-ai/mastra/commit/b05f48612984d5fe2447ea2d6cdd5c604d285b97)]:
|
|
113
|
+
- @mastra/core@1.62.0-alpha.10
|
|
114
|
+
- @mastra/code-sdk@1.5.0-alpha.10
|
|
115
|
+
- @mastra/fastembed@1.3.0-alpha.0
|
|
116
|
+
- @mastra/observability@1.17.2-alpha.2
|
|
117
|
+
- @mastra/mcp@1.17.2-alpha.2
|
|
118
|
+
|
|
3
119
|
## 0.36.0-alpha.9
|
|
4
120
|
|
|
5
121
|
### Patch Changes
|
package/dist/cli.cjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
const require_tui = require("./tui-
|
|
2
|
+
const require_tui = require("./tui-Dg7vMm5_.cjs");
|
|
3
3
|
let _mastra_code_sdk = require("@mastra/code-sdk");
|
|
4
4
|
let fs = require("fs");
|
|
5
5
|
fs = require_tui.__toESM(fs, 1);
|
|
@@ -33,7 +33,7 @@ function createShutdownCoordinator(cleanup, exit, timeoutMs = 5e3) {
|
|
|
33
33
|
//#endregion
|
|
34
34
|
//#region src/version.ts
|
|
35
35
|
function getCurrentVersion() {
|
|
36
|
-
return "0.36.
|
|
36
|
+
return "0.36.1-alpha.0";
|
|
37
37
|
}
|
|
38
38
|
//#endregion
|
|
39
39
|
//#region src/main.ts
|
|
@@ -52,6 +52,7 @@ let tui;
|
|
|
52
52
|
let processMemoryDiagnostics;
|
|
53
53
|
let storageClosed = false;
|
|
54
54
|
let cleanupPromise = null;
|
|
55
|
+
const CRASH_LOG_PATH = "/tmp/mastra-crash.log";
|
|
55
56
|
function isTruthyEnv(name) {
|
|
56
57
|
return [
|
|
57
58
|
"1",
|
|
@@ -248,7 +249,9 @@ function handleFatalError(error) {
|
|
|
248
249
|
write(msg);
|
|
249
250
|
try {
|
|
250
251
|
const crashLog = `[${(/* @__PURE__ */ new Date()).toISOString()}] ${msg}\n${error instanceof Error && error.stack ? error.stack + "\n" : ""}`;
|
|
251
|
-
|
|
252
|
+
(0, _mastra_code_sdk_utils_debug_log.truncateLogFile)(CRASH_LOG_PATH);
|
|
253
|
+
fs.default.appendFileSync(CRASH_LOG_PATH, crashLog);
|
|
254
|
+
(0, _mastra_code_sdk_utils_debug_log.truncateLogFile)(CRASH_LOG_PATH);
|
|
252
255
|
} catch {}
|
|
253
256
|
if (error instanceof Error && error.stack) write(error.stack);
|
|
254
257
|
asyncCleanup();
|
package/dist/cli.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.cjs","names":["createProcessMemoryDiagnosticsFromEnvironment","detectTerminalTheme","MastraTUI"],"sources":["../src/process-memory-diagnostics-lifecycle.ts","../src/version.ts","../src/main.ts"],"sourcesContent":["import {\n createProcessMemoryDiagnosticsFromEnvironment,\n startConfiguredProcessMemoryDiagnostics,\n type ProcessMemoryDiagnostics,\n type ProcessMemoryDiagnosticsEnvironment,\n type ProcessMemoryDiagnosticsSetup,\n} from '@mastra/code-sdk/process-memory-diagnostics';\n\nexport async function startTuiProcessMemoryDiagnostics(\n env: ProcessMemoryDiagnosticsEnvironment,\n warn: (message: string) => void,\n createSetup: (\n env: ProcessMemoryDiagnosticsEnvironment,\n ) => ProcessMemoryDiagnosticsSetup = createProcessMemoryDiagnosticsFromEnvironment,\n): Promise<ProcessMemoryDiagnostics> {\n return startConfiguredProcessMemoryDiagnostics(createSetup(env), warn);\n}\n\nexport function createShutdownCoordinator(\n cleanup: () => Promise<void>,\n exit: (exitCode: number) => never,\n timeoutMs = 5_000,\n): (exitCode: number) => Promise<void> {\n let shutdownPromise: Promise<void> | null = null;\n return exitCode => {\n shutdownPromise ??= (async () => {\n let timeout: ReturnType<typeof setTimeout> | undefined;\n await Promise.race([\n cleanup().catch(() => undefined),\n new Promise<void>(resolve => {\n timeout = setTimeout(resolve, timeoutMs);\n }),\n ]);\n if (timeout) clearTimeout(timeout);\n exit(exitCode);\n })();\n return shutdownPromise;\n };\n}\n","import { readFileSync } from 'node:fs';\n\ndeclare const MASTRACODE_VERSION: string | undefined;\n\nexport function getCurrentVersion(): string {\n if (typeof MASTRACODE_VERSION !== 'undefined') {\n return MASTRACODE_VERSION;\n }\n\n const pkg = JSON.parse(readFileSync(new URL('../package.json', import.meta.url), 'utf8')) as { version: string };\n return pkg.version;\n}\n","#!/usr/bin/env node\n/**\n * Main entry point for Mastra Code TUI.\n */\nimport fs from 'node:fs';\n\nimport { createMastraCode } from '@mastra/code-sdk';\nimport { createMastraCodeAnalytics } from '@mastra/code-sdk/analytics';\nimport { isStreamDestroyedError } from '@mastra/code-sdk/error-classification';\nimport { hasHeadlessFlag, runMCCli } from '@mastra/code-sdk/headless/index';\nimport { createBrowserFromSettings, loadSettings } from '@mastra/code-sdk/onboarding/settings';\nimport { formatScaffoldSuccess, scaffoldPlugin } from '@mastra/code-sdk/plugins/scaffold';\nimport {\n stopProcessMemoryDiagnosticsWithTimeout,\n type ProcessMemoryDiagnostics,\n} from '@mastra/code-sdk/process-memory-diagnostics';\nimport { setupDebugLogging } from '@mastra/code-sdk/utils/debug-log';\nimport { drainPipedStdin, reopenStdinFromTTY } from '@mastra/code-sdk/utils/stdin-pipe';\nimport { releaseAllThreadLocks } from '@mastra/code-sdk/utils/thread-lock';\nimport { createShutdownCoordinator, startTuiProcessMemoryDiagnostics } from './process-memory-diagnostics-lifecycle.js';\nimport { detectTerminalTheme } from './tui/detect-theme.js';\nimport { MastraTUI } from './tui/index.js';\nimport { applyThemeMode, restoreTerminalForeground } from './tui/theme.js';\nimport { getCurrentVersion } from './version.js';\n\nlet controller: Awaited<ReturnType<typeof createMastraCode>>['controller'];\nlet mcpManager: Awaited<ReturnType<typeof createMastraCode>>['mcpManager'];\nlet hookManager: Awaited<ReturnType<typeof createMastraCode>>['hookManager'];\nlet authStorage: Awaited<ReturnType<typeof createMastraCode>>['authStorage'];\nlet signalsPubSub: Awaited<ReturnType<typeof createMastraCode>>['signalsPubSub'];\nlet storageMaintenance: Awaited<ReturnType<typeof createMastraCode>>['storageMaintenance'];\nlet stopPluginSignalProviders: Awaited<ReturnType<typeof createMastraCode>>['stopPluginSignalProviders'] | undefined;\nlet analytics: ReturnType<typeof createMastraCodeAnalytics> | undefined;\nlet tui: MastraTUI | undefined;\nlet processMemoryDiagnostics: ProcessMemoryDiagnostics | undefined;\nlet storageClosed = false;\nlet cleanupPromise: Promise<void> | null = null;\n\nfunction isTruthyEnv(name: string): boolean {\n return ['1', 'true', 'yes', 'on'].includes(process.env[name]?.trim().toLowerCase() ?? '');\n}\n\nfunction resolveInitialStateFromEnv() {\n const currentModelId = process.env.MASTRACODE_MODEL_ID?.trim();\n const initialState: Record<string, unknown> = {};\n if (currentModelId) initialState.currentModelId = currentModelId;\n if (isTruthyEnv('MASTRACODE_YOLO')) initialState.yolo = true;\n return Object.keys(initialState).length > 0 ? initialState : undefined;\n}\n\n// Global safety nets — catch any uncaught errors from storage init, etc.\nprocess.on('uncaughtException', error => {\n // ERR_STREAM_DESTROYED is non-fatal — happens routinely when streams close\n // during shutdown, cancelled LLM requests, or LSP/subprocess exits (#13548, #13549)\n if (isStreamDestroyedError(error)) return;\n handleFatalError(error);\n});\nprocess.on('unhandledRejection', reason => {\n if (isStreamDestroyedError(reason)) return;\n handleFatalError(reason instanceof Error ? reason : new Error(String(reason)));\n});\n\nasync function tuiMain(pipedInput?: string | null) {\n const settings = loadSettings();\n processMemoryDiagnostics = await startTuiProcessMemoryDiagnostics(process.env, warning => {\n console.info(`⚠ ${warning}`);\n });\n let browserPromise: ReturnType<typeof createBrowserFromSettings> | undefined;\n const loadBrowser = () => {\n browserPromise ??= createBrowserFromSettings(settings.browser);\n return browserPromise;\n };\n\n const initialState = resolveInitialStateFromEnv();\n const result = await createMastraCode({\n unixSocketPubSub: !isTruthyEnv('MASTRACODE_DISABLE_UNIX_SOCKET_PUBSUB'),\n disableMcp: isTruthyEnv('MASTRACODE_DISABLE_MCP'),\n disableHooks: isTruthyEnv('MASTRACODE_DISABLE_HOOKS'),\n ...(isTruthyEnv('MASTRACODE_DISABLE_MEMORY') ? { memory: false as never } : {}),\n ...(initialState ? { initialState: initialState as never } : {}),\n });\n controller = result.controller;\n mcpManager = result.mcpManager;\n hookManager = result.hookManager;\n authStorage = result.authStorage;\n signalsPubSub = result.signalsPubSub;\n storageMaintenance = result.storageMaintenance;\n stopPluginSignalProviders = result.stopPluginSignalProviders;\n\n if (result.storageWarning) {\n console.info(`⚠ ${result.storageWarning}`);\n }\n if (result.observabilityWarning) {\n console.info(`⚠ ${result.observabilityWarning}`);\n }\n\n // MCP connection is deferred to TUI.init() (after ui.start()) so that\n // status messages use showInfo() instead of console.info(), which would\n // corrupt the terminal. Headless mode still inits from headless/cli.ts.\n\n setupDebugLogging();\n\n // Detect and apply terminal theme\n // MASTRA_THEME env var is the highest-priority override\n const envTheme = process.env.MASTRA_THEME?.toLowerCase();\n let themeMode: 'dark' | 'light';\n let detectedBgHex: string | undefined;\n if (envTheme === 'dark' || envTheme === 'light') {\n themeMode = envTheme;\n } else {\n const settings = loadSettings();\n const themePref = settings.preferences.theme;\n if (themePref === 'dark' || themePref === 'light') {\n themeMode = themePref;\n } else {\n const detection = await detectTerminalTheme();\n themeMode = detection.mode;\n detectedBgHex = detection.detectedBgHex;\n }\n }\n applyThemeMode(themeMode, detectedBgHex);\n\n // createMastraCode() brought up shared resources and minted the single\n // session that all work runs through. The AgentController owns no session of its own.\n const session = result.session;\n\n analytics = createMastraCodeAnalytics({ version: getCurrentVersion() });\n analytics.capture('mastracode_session_started', {\n mode: session.mode.get(),\n resourceId: session.identity.getResourceId(),\n hasAuthStorage: Boolean(authStorage),\n hasMcp: Boolean(mcpManager),\n theme: themeMode,\n });\n\n tui = new MastraTUI({\n controller: controller,\n session,\n hookManager,\n analytics,\n authStorage,\n mcpManager,\n pluginManager: result.pluginManager,\n storageMaintenance: result.storageMaintenance,\n processMemoryDiagnostics,\n knowledgeInspector: result.knowledgeInspector,\n appName: 'Mastra Code',\n version: getCurrentVersion(),\n inlineQuestions: true,\n githubSignals: result.githubSignals,\n exit: exitCode => void shutdownAndExit(exitCode),\n ...(pipedInput ? { initialMessage: `The following was piped via stdin:\\n\\n${pipedInput}` } : {}),\n });\n tui.run().catch(error => {\n handleFatalError(error);\n });\n\n if (settings.browser.enabled) {\n void loadBrowser()\n .then(browser => {\n if (!browser) return;\n controller.setBrowser(browser);\n void session.state.set({ activeBrowserSettings: settings.browser } as any).catch(() => {});\n })\n .catch(() => {});\n }\n}\n\nconst asyncCleanup = (): Promise<void> => {\n cleanupPromise ??= (async () => {\n releaseAllThreadLocks();\n // Stop plugin-contributed signal providers (and the plugin reload listener)\n // before quiescing workers: a provider that keeps polling past this point\n // could dispatch into a controller that is shutting down.\n try {\n stopPluginSignalProviders?.();\n } catch {\n // Best-effort — the process is exiting.\n }\n const diagnosticsShutdown = processMemoryDiagnostics\n ? stopProcessMemoryDiagnosticsWithTimeout(processMemoryDiagnostics, message => console.warn(message))\n : undefined;\n const closeSignalsPubSub = (signalsPubSub as { close?: () => Promise<void> | void } | undefined)?.close;\n await Promise.allSettled([mcpManager?.disconnect(), controller?.stopIntervals(), closeSignalsPubSub?.()]);\n // Mastra owns the workspaces and must destroy them to stop retained language\n // servers before storage is closed.\n await Promise.allSettled([controller?.getMastra()?.shutdown(), analytics?.shutdown()]);\n // Checkpoint WAL and close the local storage connection after all producers\n // and timers are quiesced. Idempotent — repeated signals (SIGINT then SIGHUP)\n // close only once. LibSQLStore.close()/LibSQLVector.close() truncate the WAL\n // and switch back to DELETE journal mode for a clean shutdown.\n if (!storageClosed) {\n storageClosed = true;\n await storageMaintenance?.closeStorage?.().catch(() => {\n // Swallow — best-effort cleanup during shutdown. The process is exiting.\n });\n }\n await diagnosticsShutdown;\n })();\n return cleanupPromise;\n};\n\nconst shutdownAndExit = createShutdownCoordinator(asyncCleanup, exitCode => process.exit(exitCode));\n\nprocess.on('beforeExit', () => {\n void asyncCleanup();\n});\nprocess.on('exit', () => {\n // Ensure terminal protocols (kitty keyboard, modifyOtherKeys, bracketed paste,\n // raw mode) are disabled on ANY exit path. Without this, killing the process\n // via SIGINT/SIGTERM leaves the terminal in a corrupted state where keypresses\n // produce escape sequences like \"5;99~\" instead of normal characters.\n try {\n tui?.stop();\n } catch {\n // Failsafe: even if MastraTUI.stop() throws, write raw terminal reset\n // sequences to disable Kitty keyboard protocol, bracketed paste, and\n // modifyOtherKeys. These are the exact sequences pi-tui's terminal.stop()\n // would write.\n }\n // Belt-and-suspenders: always write terminal reset sequences directly,\n // regardless of whether tui.stop() succeeded. Writing them twice is harmless\n // but missing them leaves the terminal in a corrupted state.\n try {\n process.stdout.write(\n '\\x1b[?2004l' + // disable bracketed paste\n '\\x1b[<u' + // pop kitty keyboard protocol\n '\\x1b[>4;0m' + // disable modifyOtherKeys\n '\\x1b[?25h', // show cursor\n );\n if (process.stdin.setRawMode) {\n process.stdin.setRawMode(false);\n }\n } catch {\n // stdout may already be closed during exit\n }\n restoreTerminalForeground();\n releaseAllThreadLocks();\n});\n\n// Start durable diagnostics shutdown before synchronous TUI teardown so a stalled\n// terminal cleanup cannot prevent the final profile capture. The exit handler still\n// provides a failsafe terminal reset if teardown throws.\nconst handleTermSignal = () => {\n void asyncCleanup();\n try {\n tui?.stop();\n } catch {\n // ignored — exit handler has failsafe reset\n }\n void shutdownAndExit(0);\n};\nprocess.on('SIGINT', handleTermSignal);\nprocess.on('SIGTERM', handleTermSignal);\nprocess.on('SIGHUP', handleTermSignal);\n\nfunction hasEconnrefused(err: unknown, depth = 0): boolean {\n if (!err || depth > 5) return false;\n const e = err as any;\n if (e.code === 'ECONNREFUSED') return true;\n if (e.cause) return hasEconnrefused(e.cause, depth + 1);\n // AggregateError has .errors array\n if (Array.isArray(e.errors)) return e.errors.some((inner: unknown) => hasEconnrefused(inner, depth + 1));\n return false;\n}\n\nfunction pluginMain(args: string[]): void {\n if (args[0] !== 'scaffold') {\n process.stderr.write('Usage: mastracode plugin scaffold <dir> [--id acme.foo] [--name \"Foo Tools\"]\\n');\n process.exit(1);\n }\n\n const dir = args[1];\n if (!dir) {\n process.stderr.write('Usage: mastracode plugin scaffold <dir> [--id acme.foo] [--name \"Foo Tools\"]\\n');\n process.exit(1);\n }\n\n const id = readFlag(args, '--id');\n const name = readFlag(args, '--name');\n const targetDir = scaffoldPlugin(dir, { ...(id ? { id } : {}), ...(name ? { name } : {}) });\n process.stdout.write(`${formatScaffoldSuccess(targetDir)}\\n`);\n}\n\nfunction readFlag(args: string[], flag: string): string | undefined {\n const index = args.indexOf(flag);\n if (index === -1) return undefined;\n const value = args[index + 1];\n if (!value || value.startsWith('--')) {\n throw new Error(`Missing value for ${flag}`);\n }\n return value;\n}\n\nfunction handleFatalError(error: unknown): void {\n // Always write to real stderr, even if console.error was overridden\n const write = (msg: string) => process.stderr.write(msg + '\\n');\n\n if (hasEconnrefused(error)) {\n const settings = loadSettings();\n const connStr = settings.storage?.pg?.connectionString;\n const target = connStr ?? 'localhost:5432';\n write(\n `\\nFailed to connect to PostgreSQL at ${target}.` +\n `\\nMake sure the database is running and accessible.` +\n `\\n\\nTo switch back to LibSQL:` +\n `\\n Set MASTRA_STORAGE_BACKEND=libsql or change the backend in /settings\\n`,\n );\n void asyncCleanup();\n try {\n tui?.stop();\n } catch {}\n void shutdownAndExit(1);\n return;\n }\n\n const msg = `Fatal error: ${error instanceof Error ? error.message : String(error)}`;\n write(msg);\n // Write crash log to file so it persists even if terminal closes\n try {\n const crashLog = `[${new Date().toISOString()}] ${msg}\\n${error instanceof Error && error.stack ? error.stack + '\\n' : ''}`;\n fs.appendFileSync('/tmp/mastra-crash.log', crashLog);\n } catch {}\n if (error instanceof Error && error.stack) {\n write(error.stack);\n }\n void asyncCleanup();\n try {\n tui?.stop();\n } catch {}\n void shutdownAndExit(1);\n}\n\nasync function main() {\n if (process.argv[2] === 'plugin') {\n return pluginMain(process.argv.slice(3));\n }\n\n if (hasHeadlessFlag(process.argv) || process.argv.includes('--help') || process.argv.includes('-h')) {\n return runMCCli();\n }\n\n if (process.argv.includes('--acp')) {\n const { acpMain } = await import('@mastra/code-sdk/acp/index');\n return acpMain({ dangerousAutoApprove: process.argv.includes('--dangerous-auto-approve') });\n }\n\n // When stdin is piped (e.g. `cat foo | mastracode`), drain the pipe fully\n // before starting the TUI. The drain blocks until the sender process exits\n // and closes its stdout, so we never see partial output.\n let pipedInput: string | null = null;\n if (!process.stdin.isTTY) {\n process.stderr.write('Reading piped input...\\n');\n pipedInput = await drainPipedStdin();\n\n // Always reopen a real TTY — even if the pipe was empty, the original\n // stdin is consumed/closed and the TUI needs a live TTY for keyboard input.\n const reopenedStdin = reopenStdinFromTTY();\n if (!reopenedStdin) {\n process.stderr.write('No TTY available — falling back to headless mode.\\n');\n return runMCCli(pipedInput);\n }\n }\n\n return tuiMain(pipedInput);\n}\n\nmain().catch(error => {\n handleFatalError(error);\n});\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"cli.cjs","names":["createProcessMemoryDiagnosticsFromEnvironment","detectTerminalTheme","MastraTUI"],"sources":["../src/process-memory-diagnostics-lifecycle.ts","../src/version.ts","../src/main.ts"],"sourcesContent":["import {\n createProcessMemoryDiagnosticsFromEnvironment,\n startConfiguredProcessMemoryDiagnostics,\n type ProcessMemoryDiagnostics,\n type ProcessMemoryDiagnosticsEnvironment,\n type ProcessMemoryDiagnosticsSetup,\n} from '@mastra/code-sdk/process-memory-diagnostics';\n\nexport async function startTuiProcessMemoryDiagnostics(\n env: ProcessMemoryDiagnosticsEnvironment,\n warn: (message: string) => void,\n createSetup: (\n env: ProcessMemoryDiagnosticsEnvironment,\n ) => ProcessMemoryDiagnosticsSetup = createProcessMemoryDiagnosticsFromEnvironment,\n): Promise<ProcessMemoryDiagnostics> {\n return startConfiguredProcessMemoryDiagnostics(createSetup(env), warn);\n}\n\nexport function createShutdownCoordinator(\n cleanup: () => Promise<void>,\n exit: (exitCode: number) => never,\n timeoutMs = 5_000,\n): (exitCode: number) => Promise<void> {\n let shutdownPromise: Promise<void> | null = null;\n return exitCode => {\n shutdownPromise ??= (async () => {\n let timeout: ReturnType<typeof setTimeout> | undefined;\n await Promise.race([\n cleanup().catch(() => undefined),\n new Promise<void>(resolve => {\n timeout = setTimeout(resolve, timeoutMs);\n }),\n ]);\n if (timeout) clearTimeout(timeout);\n exit(exitCode);\n })();\n return shutdownPromise;\n };\n}\n","import { readFileSync } from 'node:fs';\n\ndeclare const MASTRACODE_VERSION: string | undefined;\n\nexport function getCurrentVersion(): string {\n if (typeof MASTRACODE_VERSION !== 'undefined') {\n return MASTRACODE_VERSION;\n }\n\n const pkg = JSON.parse(readFileSync(new URL('../package.json', import.meta.url), 'utf8')) as { version: string };\n return pkg.version;\n}\n","#!/usr/bin/env node\n/**\n * Main entry point for Mastra Code TUI.\n */\nimport fs from 'node:fs';\n\nimport { createMastraCode } from '@mastra/code-sdk';\nimport { createMastraCodeAnalytics } from '@mastra/code-sdk/analytics';\nimport { isStreamDestroyedError } from '@mastra/code-sdk/error-classification';\nimport { hasHeadlessFlag, runMCCli } from '@mastra/code-sdk/headless/index';\nimport { createBrowserFromSettings, loadSettings } from '@mastra/code-sdk/onboarding/settings';\nimport { formatScaffoldSuccess, scaffoldPlugin } from '@mastra/code-sdk/plugins/scaffold';\nimport {\n stopProcessMemoryDiagnosticsWithTimeout,\n type ProcessMemoryDiagnostics,\n} from '@mastra/code-sdk/process-memory-diagnostics';\nimport { setupDebugLogging, truncateLogFile } from '@mastra/code-sdk/utils/debug-log';\nimport { drainPipedStdin, reopenStdinFromTTY } from '@mastra/code-sdk/utils/stdin-pipe';\nimport { releaseAllThreadLocks } from '@mastra/code-sdk/utils/thread-lock';\nimport { createShutdownCoordinator, startTuiProcessMemoryDiagnostics } from './process-memory-diagnostics-lifecycle.js';\nimport { detectTerminalTheme } from './tui/detect-theme.js';\nimport { MastraTUI } from './tui/index.js';\nimport { applyThemeMode, restoreTerminalForeground } from './tui/theme.js';\nimport { getCurrentVersion } from './version.js';\n\nlet controller: Awaited<ReturnType<typeof createMastraCode>>['controller'];\nlet mcpManager: Awaited<ReturnType<typeof createMastraCode>>['mcpManager'];\nlet hookManager: Awaited<ReturnType<typeof createMastraCode>>['hookManager'];\nlet authStorage: Awaited<ReturnType<typeof createMastraCode>>['authStorage'];\nlet signalsPubSub: Awaited<ReturnType<typeof createMastraCode>>['signalsPubSub'];\nlet storageMaintenance: Awaited<ReturnType<typeof createMastraCode>>['storageMaintenance'];\nlet stopPluginSignalProviders: Awaited<ReturnType<typeof createMastraCode>>['stopPluginSignalProviders'] | undefined;\nlet analytics: ReturnType<typeof createMastraCodeAnalytics> | undefined;\nlet tui: MastraTUI | undefined;\nlet processMemoryDiagnostics: ProcessMemoryDiagnostics | undefined;\nlet storageClosed = false;\nlet cleanupPromise: Promise<void> | null = null;\n\nconst CRASH_LOG_PATH = '/tmp/mastra-crash.log';\n\nfunction isTruthyEnv(name: string): boolean {\n return ['1', 'true', 'yes', 'on'].includes(process.env[name]?.trim().toLowerCase() ?? '');\n}\n\nfunction resolveInitialStateFromEnv() {\n const currentModelId = process.env.MASTRACODE_MODEL_ID?.trim();\n const initialState: Record<string, unknown> = {};\n if (currentModelId) initialState.currentModelId = currentModelId;\n if (isTruthyEnv('MASTRACODE_YOLO')) initialState.yolo = true;\n return Object.keys(initialState).length > 0 ? initialState : undefined;\n}\n\n// Global safety nets — catch any uncaught errors from storage init, etc.\nprocess.on('uncaughtException', error => {\n // ERR_STREAM_DESTROYED is non-fatal — happens routinely when streams close\n // during shutdown, cancelled LLM requests, or LSP/subprocess exits (#13548, #13549)\n if (isStreamDestroyedError(error)) return;\n handleFatalError(error);\n});\nprocess.on('unhandledRejection', reason => {\n if (isStreamDestroyedError(reason)) return;\n handleFatalError(reason instanceof Error ? reason : new Error(String(reason)));\n});\n\nasync function tuiMain(pipedInput?: string | null) {\n const settings = loadSettings();\n processMemoryDiagnostics = await startTuiProcessMemoryDiagnostics(process.env, warning => {\n console.info(`⚠ ${warning}`);\n });\n let browserPromise: ReturnType<typeof createBrowserFromSettings> | undefined;\n const loadBrowser = () => {\n browserPromise ??= createBrowserFromSettings(settings.browser);\n return browserPromise;\n };\n\n const initialState = resolveInitialStateFromEnv();\n const result = await createMastraCode({\n unixSocketPubSub: !isTruthyEnv('MASTRACODE_DISABLE_UNIX_SOCKET_PUBSUB'),\n disableMcp: isTruthyEnv('MASTRACODE_DISABLE_MCP'),\n disableHooks: isTruthyEnv('MASTRACODE_DISABLE_HOOKS'),\n ...(isTruthyEnv('MASTRACODE_DISABLE_MEMORY') ? { memory: false as never } : {}),\n ...(initialState ? { initialState: initialState as never } : {}),\n });\n controller = result.controller;\n mcpManager = result.mcpManager;\n hookManager = result.hookManager;\n authStorage = result.authStorage;\n signalsPubSub = result.signalsPubSub;\n storageMaintenance = result.storageMaintenance;\n stopPluginSignalProviders = result.stopPluginSignalProviders;\n\n if (result.storageWarning) {\n console.info(`⚠ ${result.storageWarning}`);\n }\n if (result.observabilityWarning) {\n console.info(`⚠ ${result.observabilityWarning}`);\n }\n\n // MCP connection is deferred to TUI.init() (after ui.start()) so that\n // status messages use showInfo() instead of console.info(), which would\n // corrupt the terminal. Headless mode still inits from headless/cli.ts.\n\n setupDebugLogging();\n\n // Detect and apply terminal theme\n // MASTRA_THEME env var is the highest-priority override\n const envTheme = process.env.MASTRA_THEME?.toLowerCase();\n let themeMode: 'dark' | 'light';\n let detectedBgHex: string | undefined;\n if (envTheme === 'dark' || envTheme === 'light') {\n themeMode = envTheme;\n } else {\n const settings = loadSettings();\n const themePref = settings.preferences.theme;\n if (themePref === 'dark' || themePref === 'light') {\n themeMode = themePref;\n } else {\n const detection = await detectTerminalTheme();\n themeMode = detection.mode;\n detectedBgHex = detection.detectedBgHex;\n }\n }\n applyThemeMode(themeMode, detectedBgHex);\n\n // createMastraCode() brought up shared resources and minted the single\n // session that all work runs through. The AgentController owns no session of its own.\n const session = result.session;\n\n analytics = createMastraCodeAnalytics({ version: getCurrentVersion() });\n analytics.capture('mastracode_session_started', {\n mode: session.mode.get(),\n resourceId: session.identity.getResourceId(),\n hasAuthStorage: Boolean(authStorage),\n hasMcp: Boolean(mcpManager),\n theme: themeMode,\n });\n\n tui = new MastraTUI({\n controller: controller,\n session,\n hookManager,\n analytics,\n authStorage,\n mcpManager,\n pluginManager: result.pluginManager,\n storageMaintenance: result.storageMaintenance,\n processMemoryDiagnostics,\n knowledgeInspector: result.knowledgeInspector,\n appName: 'Mastra Code',\n version: getCurrentVersion(),\n inlineQuestions: true,\n githubSignals: result.githubSignals,\n exit: exitCode => void shutdownAndExit(exitCode),\n ...(pipedInput ? { initialMessage: `The following was piped via stdin:\\n\\n${pipedInput}` } : {}),\n });\n tui.run().catch(error => {\n handleFatalError(error);\n });\n\n if (settings.browser.enabled) {\n void loadBrowser()\n .then(browser => {\n if (!browser) return;\n controller.setBrowser(browser);\n void session.state.set({ activeBrowserSettings: settings.browser } as any).catch(() => {});\n })\n .catch(() => {});\n }\n}\n\nconst asyncCleanup = (): Promise<void> => {\n cleanupPromise ??= (async () => {\n releaseAllThreadLocks();\n // Stop plugin-contributed signal providers (and the plugin reload listener)\n // before quiescing workers: a provider that keeps polling past this point\n // could dispatch into a controller that is shutting down.\n try {\n stopPluginSignalProviders?.();\n } catch {\n // Best-effort — the process is exiting.\n }\n const diagnosticsShutdown = processMemoryDiagnostics\n ? stopProcessMemoryDiagnosticsWithTimeout(processMemoryDiagnostics, message => console.warn(message))\n : undefined;\n const closeSignalsPubSub = (signalsPubSub as { close?: () => Promise<void> | void } | undefined)?.close;\n await Promise.allSettled([mcpManager?.disconnect(), controller?.stopIntervals(), closeSignalsPubSub?.()]);\n // Mastra owns the workspaces and must destroy them to stop retained language\n // servers before storage is closed.\n await Promise.allSettled([controller?.getMastra()?.shutdown(), analytics?.shutdown()]);\n // Checkpoint WAL and close the local storage connection after all producers\n // and timers are quiesced. Idempotent — repeated signals (SIGINT then SIGHUP)\n // close only once. LibSQLStore.close()/LibSQLVector.close() truncate the WAL\n // and switch back to DELETE journal mode for a clean shutdown.\n if (!storageClosed) {\n storageClosed = true;\n await storageMaintenance?.closeStorage?.().catch(() => {\n // Swallow — best-effort cleanup during shutdown. The process is exiting.\n });\n }\n await diagnosticsShutdown;\n })();\n return cleanupPromise;\n};\n\nconst shutdownAndExit = createShutdownCoordinator(asyncCleanup, exitCode => process.exit(exitCode));\n\nprocess.on('beforeExit', () => {\n void asyncCleanup();\n});\nprocess.on('exit', () => {\n // Ensure terminal protocols (kitty keyboard, modifyOtherKeys, bracketed paste,\n // raw mode) are disabled on ANY exit path. Without this, killing the process\n // via SIGINT/SIGTERM leaves the terminal in a corrupted state where keypresses\n // produce escape sequences like \"5;99~\" instead of normal characters.\n try {\n tui?.stop();\n } catch {\n // Failsafe: even if MastraTUI.stop() throws, write raw terminal reset\n // sequences to disable Kitty keyboard protocol, bracketed paste, and\n // modifyOtherKeys. These are the exact sequences pi-tui's terminal.stop()\n // would write.\n }\n // Belt-and-suspenders: always write terminal reset sequences directly,\n // regardless of whether tui.stop() succeeded. Writing them twice is harmless\n // but missing them leaves the terminal in a corrupted state.\n try {\n process.stdout.write(\n '\\x1b[?2004l' + // disable bracketed paste\n '\\x1b[<u' + // pop kitty keyboard protocol\n '\\x1b[>4;0m' + // disable modifyOtherKeys\n '\\x1b[?25h', // show cursor\n );\n if (process.stdin.setRawMode) {\n process.stdin.setRawMode(false);\n }\n } catch {\n // stdout may already be closed during exit\n }\n restoreTerminalForeground();\n releaseAllThreadLocks();\n});\n\n// Start durable diagnostics shutdown before synchronous TUI teardown so a stalled\n// terminal cleanup cannot prevent the final profile capture. The exit handler still\n// provides a failsafe terminal reset if teardown throws.\nconst handleTermSignal = () => {\n void asyncCleanup();\n try {\n tui?.stop();\n } catch {\n // ignored — exit handler has failsafe reset\n }\n void shutdownAndExit(0);\n};\nprocess.on('SIGINT', handleTermSignal);\nprocess.on('SIGTERM', handleTermSignal);\nprocess.on('SIGHUP', handleTermSignal);\n\nfunction hasEconnrefused(err: unknown, depth = 0): boolean {\n if (!err || depth > 5) return false;\n const e = err as any;\n if (e.code === 'ECONNREFUSED') return true;\n if (e.cause) return hasEconnrefused(e.cause, depth + 1);\n // AggregateError has .errors array\n if (Array.isArray(e.errors)) return e.errors.some((inner: unknown) => hasEconnrefused(inner, depth + 1));\n return false;\n}\n\nfunction pluginMain(args: string[]): void {\n if (args[0] !== 'scaffold') {\n process.stderr.write('Usage: mastracode plugin scaffold <dir> [--id acme.foo] [--name \"Foo Tools\"]\\n');\n process.exit(1);\n }\n\n const dir = args[1];\n if (!dir) {\n process.stderr.write('Usage: mastracode plugin scaffold <dir> [--id acme.foo] [--name \"Foo Tools\"]\\n');\n process.exit(1);\n }\n\n const id = readFlag(args, '--id');\n const name = readFlag(args, '--name');\n const targetDir = scaffoldPlugin(dir, { ...(id ? { id } : {}), ...(name ? { name } : {}) });\n process.stdout.write(`${formatScaffoldSuccess(targetDir)}\\n`);\n}\n\nfunction readFlag(args: string[], flag: string): string | undefined {\n const index = args.indexOf(flag);\n if (index === -1) return undefined;\n const value = args[index + 1];\n if (!value || value.startsWith('--')) {\n throw new Error(`Missing value for ${flag}`);\n }\n return value;\n}\n\nfunction handleFatalError(error: unknown): void {\n // Always write to real stderr, even if console.error was overridden\n const write = (msg: string) => process.stderr.write(msg + '\\n');\n\n if (hasEconnrefused(error)) {\n const settings = loadSettings();\n const connStr = settings.storage?.pg?.connectionString;\n const target = connStr ?? 'localhost:5432';\n write(\n `\\nFailed to connect to PostgreSQL at ${target}.` +\n `\\nMake sure the database is running and accessible.` +\n `\\n\\nTo switch back to LibSQL:` +\n `\\n Set MASTRA_STORAGE_BACKEND=libsql or change the backend in /settings\\n`,\n );\n void asyncCleanup();\n try {\n tui?.stop();\n } catch {}\n void shutdownAndExit(1);\n return;\n }\n\n const msg = `Fatal error: ${error instanceof Error ? error.message : String(error)}`;\n write(msg);\n // Write crash log to file so it persists even if terminal closes\n try {\n const crashLog = `[${new Date().toISOString()}] ${msg}\\n${error instanceof Error && error.stack ? error.stack + '\\n' : ''}`;\n truncateLogFile(CRASH_LOG_PATH);\n fs.appendFileSync(CRASH_LOG_PATH, crashLog);\n truncateLogFile(CRASH_LOG_PATH);\n } catch {}\n if (error instanceof Error && error.stack) {\n write(error.stack);\n }\n void asyncCleanup();\n try {\n tui?.stop();\n } catch {}\n void shutdownAndExit(1);\n}\n\nasync function main() {\n if (process.argv[2] === 'plugin') {\n return pluginMain(process.argv.slice(3));\n }\n\n if (hasHeadlessFlag(process.argv) || process.argv.includes('--help') || process.argv.includes('-h')) {\n return runMCCli();\n }\n\n if (process.argv.includes('--acp')) {\n const { acpMain } = await import('@mastra/code-sdk/acp/index');\n return acpMain({ dangerousAutoApprove: process.argv.includes('--dangerous-auto-approve') });\n }\n\n // When stdin is piped (e.g. `cat foo | mastracode`), drain the pipe fully\n // before starting the TUI. The drain blocks until the sender process exits\n // and closes its stdout, so we never see partial output.\n let pipedInput: string | null = null;\n if (!process.stdin.isTTY) {\n process.stderr.write('Reading piped input...\\n');\n pipedInput = await drainPipedStdin();\n\n // Always reopen a real TTY — even if the pipe was empty, the original\n // stdin is consumed/closed and the TUI needs a live TTY for keyboard input.\n const reopenedStdin = reopenStdinFromTTY();\n if (!reopenedStdin) {\n process.stderr.write('No TTY available — falling back to headless mode.\\n');\n return runMCCli(pipedInput);\n }\n }\n\n return tuiMain(pipedInput);\n}\n\nmain().catch(error => {\n handleFatalError(error);\n});\n"],"mappings":"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"}
|
package/dist/cli.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { d as detectTerminalTheme, f as applyThemeMode, t as MastraTUI, v as restoreTerminalForeground } from "./tui-
|
|
2
|
+
import { d as detectTerminalTheme, f as applyThemeMode, t as MastraTUI, v as restoreTerminalForeground } from "./tui-BaobOqGM.js";
|
|
3
3
|
import { createMastraCode } from "@mastra/code-sdk";
|
|
4
4
|
import fs from "fs";
|
|
5
5
|
import { createMastraCodeAnalytics } from "@mastra/code-sdk/analytics";
|
|
@@ -8,7 +8,7 @@ import { hasHeadlessFlag, runMCCli } from "@mastra/code-sdk/headless/index";
|
|
|
8
8
|
import { createBrowserFromSettings, loadSettings } from "@mastra/code-sdk/onboarding/settings";
|
|
9
9
|
import { formatScaffoldSuccess, scaffoldPlugin } from "@mastra/code-sdk/plugins/scaffold";
|
|
10
10
|
import { createProcessMemoryDiagnosticsFromEnvironment, startConfiguredProcessMemoryDiagnostics, stopProcessMemoryDiagnosticsWithTimeout } from "@mastra/code-sdk/process-memory-diagnostics";
|
|
11
|
-
import { setupDebugLogging } from "@mastra/code-sdk/utils/debug-log";
|
|
11
|
+
import { setupDebugLogging, truncateLogFile } from "@mastra/code-sdk/utils/debug-log";
|
|
12
12
|
import { drainPipedStdin, reopenStdinFromTTY } from "@mastra/code-sdk/utils/stdin-pipe";
|
|
13
13
|
import { releaseAllThreadLocks } from "@mastra/code-sdk/utils/thread-lock";
|
|
14
14
|
//#region src/process-memory-diagnostics-lifecycle.ts
|
|
@@ -32,7 +32,7 @@ function createShutdownCoordinator(cleanup, exit, timeoutMs = 5e3) {
|
|
|
32
32
|
//#endregion
|
|
33
33
|
//#region src/version.ts
|
|
34
34
|
function getCurrentVersion() {
|
|
35
|
-
return "0.36.
|
|
35
|
+
return "0.36.1-alpha.0";
|
|
36
36
|
}
|
|
37
37
|
//#endregion
|
|
38
38
|
//#region src/main.ts
|
|
@@ -51,6 +51,7 @@ let tui;
|
|
|
51
51
|
let processMemoryDiagnostics;
|
|
52
52
|
let storageClosed = false;
|
|
53
53
|
let cleanupPromise = null;
|
|
54
|
+
const CRASH_LOG_PATH = "/tmp/mastra-crash.log";
|
|
54
55
|
function isTruthyEnv(name) {
|
|
55
56
|
return [
|
|
56
57
|
"1",
|
|
@@ -247,7 +248,9 @@ function handleFatalError(error) {
|
|
|
247
248
|
write(msg);
|
|
248
249
|
try {
|
|
249
250
|
const crashLog = `[${(/* @__PURE__ */ new Date()).toISOString()}] ${msg}\n${error instanceof Error && error.stack ? error.stack + "\n" : ""}`;
|
|
250
|
-
|
|
251
|
+
truncateLogFile(CRASH_LOG_PATH);
|
|
252
|
+
fs.appendFileSync(CRASH_LOG_PATH, crashLog);
|
|
253
|
+
truncateLogFile(CRASH_LOG_PATH);
|
|
251
254
|
} catch {}
|
|
252
255
|
if (error instanceof Error && error.stack) write(error.stack);
|
|
253
256
|
asyncCleanup();
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","names":[],"sources":["../src/process-memory-diagnostics-lifecycle.ts","../src/version.ts","../src/main.ts"],"sourcesContent":["import {\n createProcessMemoryDiagnosticsFromEnvironment,\n startConfiguredProcessMemoryDiagnostics,\n type ProcessMemoryDiagnostics,\n type ProcessMemoryDiagnosticsEnvironment,\n type ProcessMemoryDiagnosticsSetup,\n} from '@mastra/code-sdk/process-memory-diagnostics';\n\nexport async function startTuiProcessMemoryDiagnostics(\n env: ProcessMemoryDiagnosticsEnvironment,\n warn: (message: string) => void,\n createSetup: (\n env: ProcessMemoryDiagnosticsEnvironment,\n ) => ProcessMemoryDiagnosticsSetup = createProcessMemoryDiagnosticsFromEnvironment,\n): Promise<ProcessMemoryDiagnostics> {\n return startConfiguredProcessMemoryDiagnostics(createSetup(env), warn);\n}\n\nexport function createShutdownCoordinator(\n cleanup: () => Promise<void>,\n exit: (exitCode: number) => never,\n timeoutMs = 5_000,\n): (exitCode: number) => Promise<void> {\n let shutdownPromise: Promise<void> | null = null;\n return exitCode => {\n shutdownPromise ??= (async () => {\n let timeout: ReturnType<typeof setTimeout> | undefined;\n await Promise.race([\n cleanup().catch(() => undefined),\n new Promise<void>(resolve => {\n timeout = setTimeout(resolve, timeoutMs);\n }),\n ]);\n if (timeout) clearTimeout(timeout);\n exit(exitCode);\n })();\n return shutdownPromise;\n };\n}\n","import { readFileSync } from 'node:fs';\n\ndeclare const MASTRACODE_VERSION: string | undefined;\n\nexport function getCurrentVersion(): string {\n if (typeof MASTRACODE_VERSION !== 'undefined') {\n return MASTRACODE_VERSION;\n }\n\n const pkg = JSON.parse(readFileSync(new URL('../package.json', import.meta.url), 'utf8')) as { version: string };\n return pkg.version;\n}\n","#!/usr/bin/env node\n/**\n * Main entry point for Mastra Code TUI.\n */\nimport fs from 'node:fs';\n\nimport { createMastraCode } from '@mastra/code-sdk';\nimport { createMastraCodeAnalytics } from '@mastra/code-sdk/analytics';\nimport { isStreamDestroyedError } from '@mastra/code-sdk/error-classification';\nimport { hasHeadlessFlag, runMCCli } from '@mastra/code-sdk/headless/index';\nimport { createBrowserFromSettings, loadSettings } from '@mastra/code-sdk/onboarding/settings';\nimport { formatScaffoldSuccess, scaffoldPlugin } from '@mastra/code-sdk/plugins/scaffold';\nimport {\n stopProcessMemoryDiagnosticsWithTimeout,\n type ProcessMemoryDiagnostics,\n} from '@mastra/code-sdk/process-memory-diagnostics';\nimport { setupDebugLogging } from '@mastra/code-sdk/utils/debug-log';\nimport { drainPipedStdin, reopenStdinFromTTY } from '@mastra/code-sdk/utils/stdin-pipe';\nimport { releaseAllThreadLocks } from '@mastra/code-sdk/utils/thread-lock';\nimport { createShutdownCoordinator, startTuiProcessMemoryDiagnostics } from './process-memory-diagnostics-lifecycle.js';\nimport { detectTerminalTheme } from './tui/detect-theme.js';\nimport { MastraTUI } from './tui/index.js';\nimport { applyThemeMode, restoreTerminalForeground } from './tui/theme.js';\nimport { getCurrentVersion } from './version.js';\n\nlet controller: Awaited<ReturnType<typeof createMastraCode>>['controller'];\nlet mcpManager: Awaited<ReturnType<typeof createMastraCode>>['mcpManager'];\nlet hookManager: Awaited<ReturnType<typeof createMastraCode>>['hookManager'];\nlet authStorage: Awaited<ReturnType<typeof createMastraCode>>['authStorage'];\nlet signalsPubSub: Awaited<ReturnType<typeof createMastraCode>>['signalsPubSub'];\nlet storageMaintenance: Awaited<ReturnType<typeof createMastraCode>>['storageMaintenance'];\nlet stopPluginSignalProviders: Awaited<ReturnType<typeof createMastraCode>>['stopPluginSignalProviders'] | undefined;\nlet analytics: ReturnType<typeof createMastraCodeAnalytics> | undefined;\nlet tui: MastraTUI | undefined;\nlet processMemoryDiagnostics: ProcessMemoryDiagnostics | undefined;\nlet storageClosed = false;\nlet cleanupPromise: Promise<void> | null = null;\n\nfunction isTruthyEnv(name: string): boolean {\n return ['1', 'true', 'yes', 'on'].includes(process.env[name]?.trim().toLowerCase() ?? '');\n}\n\nfunction resolveInitialStateFromEnv() {\n const currentModelId = process.env.MASTRACODE_MODEL_ID?.trim();\n const initialState: Record<string, unknown> = {};\n if (currentModelId) initialState.currentModelId = currentModelId;\n if (isTruthyEnv('MASTRACODE_YOLO')) initialState.yolo = true;\n return Object.keys(initialState).length > 0 ? initialState : undefined;\n}\n\n// Global safety nets — catch any uncaught errors from storage init, etc.\nprocess.on('uncaughtException', error => {\n // ERR_STREAM_DESTROYED is non-fatal — happens routinely when streams close\n // during shutdown, cancelled LLM requests, or LSP/subprocess exits (#13548, #13549)\n if (isStreamDestroyedError(error)) return;\n handleFatalError(error);\n});\nprocess.on('unhandledRejection', reason => {\n if (isStreamDestroyedError(reason)) return;\n handleFatalError(reason instanceof Error ? reason : new Error(String(reason)));\n});\n\nasync function tuiMain(pipedInput?: string | null) {\n const settings = loadSettings();\n processMemoryDiagnostics = await startTuiProcessMemoryDiagnostics(process.env, warning => {\n console.info(`⚠ ${warning}`);\n });\n let browserPromise: ReturnType<typeof createBrowserFromSettings> | undefined;\n const loadBrowser = () => {\n browserPromise ??= createBrowserFromSettings(settings.browser);\n return browserPromise;\n };\n\n const initialState = resolveInitialStateFromEnv();\n const result = await createMastraCode({\n unixSocketPubSub: !isTruthyEnv('MASTRACODE_DISABLE_UNIX_SOCKET_PUBSUB'),\n disableMcp: isTruthyEnv('MASTRACODE_DISABLE_MCP'),\n disableHooks: isTruthyEnv('MASTRACODE_DISABLE_HOOKS'),\n ...(isTruthyEnv('MASTRACODE_DISABLE_MEMORY') ? { memory: false as never } : {}),\n ...(initialState ? { initialState: initialState as never } : {}),\n });\n controller = result.controller;\n mcpManager = result.mcpManager;\n hookManager = result.hookManager;\n authStorage = result.authStorage;\n signalsPubSub = result.signalsPubSub;\n storageMaintenance = result.storageMaintenance;\n stopPluginSignalProviders = result.stopPluginSignalProviders;\n\n if (result.storageWarning) {\n console.info(`⚠ ${result.storageWarning}`);\n }\n if (result.observabilityWarning) {\n console.info(`⚠ ${result.observabilityWarning}`);\n }\n\n // MCP connection is deferred to TUI.init() (after ui.start()) so that\n // status messages use showInfo() instead of console.info(), which would\n // corrupt the terminal. Headless mode still inits from headless/cli.ts.\n\n setupDebugLogging();\n\n // Detect and apply terminal theme\n // MASTRA_THEME env var is the highest-priority override\n const envTheme = process.env.MASTRA_THEME?.toLowerCase();\n let themeMode: 'dark' | 'light';\n let detectedBgHex: string | undefined;\n if (envTheme === 'dark' || envTheme === 'light') {\n themeMode = envTheme;\n } else {\n const settings = loadSettings();\n const themePref = settings.preferences.theme;\n if (themePref === 'dark' || themePref === 'light') {\n themeMode = themePref;\n } else {\n const detection = await detectTerminalTheme();\n themeMode = detection.mode;\n detectedBgHex = detection.detectedBgHex;\n }\n }\n applyThemeMode(themeMode, detectedBgHex);\n\n // createMastraCode() brought up shared resources and minted the single\n // session that all work runs through. The AgentController owns no session of its own.\n const session = result.session;\n\n analytics = createMastraCodeAnalytics({ version: getCurrentVersion() });\n analytics.capture('mastracode_session_started', {\n mode: session.mode.get(),\n resourceId: session.identity.getResourceId(),\n hasAuthStorage: Boolean(authStorage),\n hasMcp: Boolean(mcpManager),\n theme: themeMode,\n });\n\n tui = new MastraTUI({\n controller: controller,\n session,\n hookManager,\n analytics,\n authStorage,\n mcpManager,\n pluginManager: result.pluginManager,\n storageMaintenance: result.storageMaintenance,\n processMemoryDiagnostics,\n knowledgeInspector: result.knowledgeInspector,\n appName: 'Mastra Code',\n version: getCurrentVersion(),\n inlineQuestions: true,\n githubSignals: result.githubSignals,\n exit: exitCode => void shutdownAndExit(exitCode),\n ...(pipedInput ? { initialMessage: `The following was piped via stdin:\\n\\n${pipedInput}` } : {}),\n });\n tui.run().catch(error => {\n handleFatalError(error);\n });\n\n if (settings.browser.enabled) {\n void loadBrowser()\n .then(browser => {\n if (!browser) return;\n controller.setBrowser(browser);\n void session.state.set({ activeBrowserSettings: settings.browser } as any).catch(() => {});\n })\n .catch(() => {});\n }\n}\n\nconst asyncCleanup = (): Promise<void> => {\n cleanupPromise ??= (async () => {\n releaseAllThreadLocks();\n // Stop plugin-contributed signal providers (and the plugin reload listener)\n // before quiescing workers: a provider that keeps polling past this point\n // could dispatch into a controller that is shutting down.\n try {\n stopPluginSignalProviders?.();\n } catch {\n // Best-effort — the process is exiting.\n }\n const diagnosticsShutdown = processMemoryDiagnostics\n ? stopProcessMemoryDiagnosticsWithTimeout(processMemoryDiagnostics, message => console.warn(message))\n : undefined;\n const closeSignalsPubSub = (signalsPubSub as { close?: () => Promise<void> | void } | undefined)?.close;\n await Promise.allSettled([mcpManager?.disconnect(), controller?.stopIntervals(), closeSignalsPubSub?.()]);\n // Mastra owns the workspaces and must destroy them to stop retained language\n // servers before storage is closed.\n await Promise.allSettled([controller?.getMastra()?.shutdown(), analytics?.shutdown()]);\n // Checkpoint WAL and close the local storage connection after all producers\n // and timers are quiesced. Idempotent — repeated signals (SIGINT then SIGHUP)\n // close only once. LibSQLStore.close()/LibSQLVector.close() truncate the WAL\n // and switch back to DELETE journal mode for a clean shutdown.\n if (!storageClosed) {\n storageClosed = true;\n await storageMaintenance?.closeStorage?.().catch(() => {\n // Swallow — best-effort cleanup during shutdown. The process is exiting.\n });\n }\n await diagnosticsShutdown;\n })();\n return cleanupPromise;\n};\n\nconst shutdownAndExit = createShutdownCoordinator(asyncCleanup, exitCode => process.exit(exitCode));\n\nprocess.on('beforeExit', () => {\n void asyncCleanup();\n});\nprocess.on('exit', () => {\n // Ensure terminal protocols (kitty keyboard, modifyOtherKeys, bracketed paste,\n // raw mode) are disabled on ANY exit path. Without this, killing the process\n // via SIGINT/SIGTERM leaves the terminal in a corrupted state where keypresses\n // produce escape sequences like \"5;99~\" instead of normal characters.\n try {\n tui?.stop();\n } catch {\n // Failsafe: even if MastraTUI.stop() throws, write raw terminal reset\n // sequences to disable Kitty keyboard protocol, bracketed paste, and\n // modifyOtherKeys. These are the exact sequences pi-tui's terminal.stop()\n // would write.\n }\n // Belt-and-suspenders: always write terminal reset sequences directly,\n // regardless of whether tui.stop() succeeded. Writing them twice is harmless\n // but missing them leaves the terminal in a corrupted state.\n try {\n process.stdout.write(\n '\\x1b[?2004l' + // disable bracketed paste\n '\\x1b[<u' + // pop kitty keyboard protocol\n '\\x1b[>4;0m' + // disable modifyOtherKeys\n '\\x1b[?25h', // show cursor\n );\n if (process.stdin.setRawMode) {\n process.stdin.setRawMode(false);\n }\n } catch {\n // stdout may already be closed during exit\n }\n restoreTerminalForeground();\n releaseAllThreadLocks();\n});\n\n// Start durable diagnostics shutdown before synchronous TUI teardown so a stalled\n// terminal cleanup cannot prevent the final profile capture. The exit handler still\n// provides a failsafe terminal reset if teardown throws.\nconst handleTermSignal = () => {\n void asyncCleanup();\n try {\n tui?.stop();\n } catch {\n // ignored — exit handler has failsafe reset\n }\n void shutdownAndExit(0);\n};\nprocess.on('SIGINT', handleTermSignal);\nprocess.on('SIGTERM', handleTermSignal);\nprocess.on('SIGHUP', handleTermSignal);\n\nfunction hasEconnrefused(err: unknown, depth = 0): boolean {\n if (!err || depth > 5) return false;\n const e = err as any;\n if (e.code === 'ECONNREFUSED') return true;\n if (e.cause) return hasEconnrefused(e.cause, depth + 1);\n // AggregateError has .errors array\n if (Array.isArray(e.errors)) return e.errors.some((inner: unknown) => hasEconnrefused(inner, depth + 1));\n return false;\n}\n\nfunction pluginMain(args: string[]): void {\n if (args[0] !== 'scaffold') {\n process.stderr.write('Usage: mastracode plugin scaffold <dir> [--id acme.foo] [--name \"Foo Tools\"]\\n');\n process.exit(1);\n }\n\n const dir = args[1];\n if (!dir) {\n process.stderr.write('Usage: mastracode plugin scaffold <dir> [--id acme.foo] [--name \"Foo Tools\"]\\n');\n process.exit(1);\n }\n\n const id = readFlag(args, '--id');\n const name = readFlag(args, '--name');\n const targetDir = scaffoldPlugin(dir, { ...(id ? { id } : {}), ...(name ? { name } : {}) });\n process.stdout.write(`${formatScaffoldSuccess(targetDir)}\\n`);\n}\n\nfunction readFlag(args: string[], flag: string): string | undefined {\n const index = args.indexOf(flag);\n if (index === -1) return undefined;\n const value = args[index + 1];\n if (!value || value.startsWith('--')) {\n throw new Error(`Missing value for ${flag}`);\n }\n return value;\n}\n\nfunction handleFatalError(error: unknown): void {\n // Always write to real stderr, even if console.error was overridden\n const write = (msg: string) => process.stderr.write(msg + '\\n');\n\n if (hasEconnrefused(error)) {\n const settings = loadSettings();\n const connStr = settings.storage?.pg?.connectionString;\n const target = connStr ?? 'localhost:5432';\n write(\n `\\nFailed to connect to PostgreSQL at ${target}.` +\n `\\nMake sure the database is running and accessible.` +\n `\\n\\nTo switch back to LibSQL:` +\n `\\n Set MASTRA_STORAGE_BACKEND=libsql or change the backend in /settings\\n`,\n );\n void asyncCleanup();\n try {\n tui?.stop();\n } catch {}\n void shutdownAndExit(1);\n return;\n }\n\n const msg = `Fatal error: ${error instanceof Error ? error.message : String(error)}`;\n write(msg);\n // Write crash log to file so it persists even if terminal closes\n try {\n const crashLog = `[${new Date().toISOString()}] ${msg}\\n${error instanceof Error && error.stack ? error.stack + '\\n' : ''}`;\n fs.appendFileSync('/tmp/mastra-crash.log', crashLog);\n } catch {}\n if (error instanceof Error && error.stack) {\n write(error.stack);\n }\n void asyncCleanup();\n try {\n tui?.stop();\n } catch {}\n void shutdownAndExit(1);\n}\n\nasync function main() {\n if (process.argv[2] === 'plugin') {\n return pluginMain(process.argv.slice(3));\n }\n\n if (hasHeadlessFlag(process.argv) || process.argv.includes('--help') || process.argv.includes('-h')) {\n return runMCCli();\n }\n\n if (process.argv.includes('--acp')) {\n const { acpMain } = await import('@mastra/code-sdk/acp/index');\n return acpMain({ dangerousAutoApprove: process.argv.includes('--dangerous-auto-approve') });\n }\n\n // When stdin is piped (e.g. `cat foo | mastracode`), drain the pipe fully\n // before starting the TUI. The drain blocks until the sender process exits\n // and closes its stdout, so we never see partial output.\n let pipedInput: string | null = null;\n if (!process.stdin.isTTY) {\n process.stderr.write('Reading piped input...\\n');\n pipedInput = await drainPipedStdin();\n\n // Always reopen a real TTY — even if the pipe was empty, the original\n // stdin is consumed/closed and the TUI needs a live TTY for keyboard input.\n const reopenedStdin = reopenStdinFromTTY();\n if (!reopenedStdin) {\n process.stderr.write('No TTY available — falling back to headless mode.\\n');\n return runMCCli(pipedInput);\n }\n }\n\n return tuiMain(pipedInput);\n}\n\nmain().catch(error => {\n handleFatalError(error);\n});\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"cli.js","names":[],"sources":["../src/process-memory-diagnostics-lifecycle.ts","../src/version.ts","../src/main.ts"],"sourcesContent":["import {\n createProcessMemoryDiagnosticsFromEnvironment,\n startConfiguredProcessMemoryDiagnostics,\n type ProcessMemoryDiagnostics,\n type ProcessMemoryDiagnosticsEnvironment,\n type ProcessMemoryDiagnosticsSetup,\n} from '@mastra/code-sdk/process-memory-diagnostics';\n\nexport async function startTuiProcessMemoryDiagnostics(\n env: ProcessMemoryDiagnosticsEnvironment,\n warn: (message: string) => void,\n createSetup: (\n env: ProcessMemoryDiagnosticsEnvironment,\n ) => ProcessMemoryDiagnosticsSetup = createProcessMemoryDiagnosticsFromEnvironment,\n): Promise<ProcessMemoryDiagnostics> {\n return startConfiguredProcessMemoryDiagnostics(createSetup(env), warn);\n}\n\nexport function createShutdownCoordinator(\n cleanup: () => Promise<void>,\n exit: (exitCode: number) => never,\n timeoutMs = 5_000,\n): (exitCode: number) => Promise<void> {\n let shutdownPromise: Promise<void> | null = null;\n return exitCode => {\n shutdownPromise ??= (async () => {\n let timeout: ReturnType<typeof setTimeout> | undefined;\n await Promise.race([\n cleanup().catch(() => undefined),\n new Promise<void>(resolve => {\n timeout = setTimeout(resolve, timeoutMs);\n }),\n ]);\n if (timeout) clearTimeout(timeout);\n exit(exitCode);\n })();\n return shutdownPromise;\n };\n}\n","import { readFileSync } from 'node:fs';\n\ndeclare const MASTRACODE_VERSION: string | undefined;\n\nexport function getCurrentVersion(): string {\n if (typeof MASTRACODE_VERSION !== 'undefined') {\n return MASTRACODE_VERSION;\n }\n\n const pkg = JSON.parse(readFileSync(new URL('../package.json', import.meta.url), 'utf8')) as { version: string };\n return pkg.version;\n}\n","#!/usr/bin/env node\n/**\n * Main entry point for Mastra Code TUI.\n */\nimport fs from 'node:fs';\n\nimport { createMastraCode } from '@mastra/code-sdk';\nimport { createMastraCodeAnalytics } from '@mastra/code-sdk/analytics';\nimport { isStreamDestroyedError } from '@mastra/code-sdk/error-classification';\nimport { hasHeadlessFlag, runMCCli } from '@mastra/code-sdk/headless/index';\nimport { createBrowserFromSettings, loadSettings } from '@mastra/code-sdk/onboarding/settings';\nimport { formatScaffoldSuccess, scaffoldPlugin } from '@mastra/code-sdk/plugins/scaffold';\nimport {\n stopProcessMemoryDiagnosticsWithTimeout,\n type ProcessMemoryDiagnostics,\n} from '@mastra/code-sdk/process-memory-diagnostics';\nimport { setupDebugLogging, truncateLogFile } from '@mastra/code-sdk/utils/debug-log';\nimport { drainPipedStdin, reopenStdinFromTTY } from '@mastra/code-sdk/utils/stdin-pipe';\nimport { releaseAllThreadLocks } from '@mastra/code-sdk/utils/thread-lock';\nimport { createShutdownCoordinator, startTuiProcessMemoryDiagnostics } from './process-memory-diagnostics-lifecycle.js';\nimport { detectTerminalTheme } from './tui/detect-theme.js';\nimport { MastraTUI } from './tui/index.js';\nimport { applyThemeMode, restoreTerminalForeground } from './tui/theme.js';\nimport { getCurrentVersion } from './version.js';\n\nlet controller: Awaited<ReturnType<typeof createMastraCode>>['controller'];\nlet mcpManager: Awaited<ReturnType<typeof createMastraCode>>['mcpManager'];\nlet hookManager: Awaited<ReturnType<typeof createMastraCode>>['hookManager'];\nlet authStorage: Awaited<ReturnType<typeof createMastraCode>>['authStorage'];\nlet signalsPubSub: Awaited<ReturnType<typeof createMastraCode>>['signalsPubSub'];\nlet storageMaintenance: Awaited<ReturnType<typeof createMastraCode>>['storageMaintenance'];\nlet stopPluginSignalProviders: Awaited<ReturnType<typeof createMastraCode>>['stopPluginSignalProviders'] | undefined;\nlet analytics: ReturnType<typeof createMastraCodeAnalytics> | undefined;\nlet tui: MastraTUI | undefined;\nlet processMemoryDiagnostics: ProcessMemoryDiagnostics | undefined;\nlet storageClosed = false;\nlet cleanupPromise: Promise<void> | null = null;\n\nconst CRASH_LOG_PATH = '/tmp/mastra-crash.log';\n\nfunction isTruthyEnv(name: string): boolean {\n return ['1', 'true', 'yes', 'on'].includes(process.env[name]?.trim().toLowerCase() ?? '');\n}\n\nfunction resolveInitialStateFromEnv() {\n const currentModelId = process.env.MASTRACODE_MODEL_ID?.trim();\n const initialState: Record<string, unknown> = {};\n if (currentModelId) initialState.currentModelId = currentModelId;\n if (isTruthyEnv('MASTRACODE_YOLO')) initialState.yolo = true;\n return Object.keys(initialState).length > 0 ? initialState : undefined;\n}\n\n// Global safety nets — catch any uncaught errors from storage init, etc.\nprocess.on('uncaughtException', error => {\n // ERR_STREAM_DESTROYED is non-fatal — happens routinely when streams close\n // during shutdown, cancelled LLM requests, or LSP/subprocess exits (#13548, #13549)\n if (isStreamDestroyedError(error)) return;\n handleFatalError(error);\n});\nprocess.on('unhandledRejection', reason => {\n if (isStreamDestroyedError(reason)) return;\n handleFatalError(reason instanceof Error ? reason : new Error(String(reason)));\n});\n\nasync function tuiMain(pipedInput?: string | null) {\n const settings = loadSettings();\n processMemoryDiagnostics = await startTuiProcessMemoryDiagnostics(process.env, warning => {\n console.info(`⚠ ${warning}`);\n });\n let browserPromise: ReturnType<typeof createBrowserFromSettings> | undefined;\n const loadBrowser = () => {\n browserPromise ??= createBrowserFromSettings(settings.browser);\n return browserPromise;\n };\n\n const initialState = resolveInitialStateFromEnv();\n const result = await createMastraCode({\n unixSocketPubSub: !isTruthyEnv('MASTRACODE_DISABLE_UNIX_SOCKET_PUBSUB'),\n disableMcp: isTruthyEnv('MASTRACODE_DISABLE_MCP'),\n disableHooks: isTruthyEnv('MASTRACODE_DISABLE_HOOKS'),\n ...(isTruthyEnv('MASTRACODE_DISABLE_MEMORY') ? { memory: false as never } : {}),\n ...(initialState ? { initialState: initialState as never } : {}),\n });\n controller = result.controller;\n mcpManager = result.mcpManager;\n hookManager = result.hookManager;\n authStorage = result.authStorage;\n signalsPubSub = result.signalsPubSub;\n storageMaintenance = result.storageMaintenance;\n stopPluginSignalProviders = result.stopPluginSignalProviders;\n\n if (result.storageWarning) {\n console.info(`⚠ ${result.storageWarning}`);\n }\n if (result.observabilityWarning) {\n console.info(`⚠ ${result.observabilityWarning}`);\n }\n\n // MCP connection is deferred to TUI.init() (after ui.start()) so that\n // status messages use showInfo() instead of console.info(), which would\n // corrupt the terminal. Headless mode still inits from headless/cli.ts.\n\n setupDebugLogging();\n\n // Detect and apply terminal theme\n // MASTRA_THEME env var is the highest-priority override\n const envTheme = process.env.MASTRA_THEME?.toLowerCase();\n let themeMode: 'dark' | 'light';\n let detectedBgHex: string | undefined;\n if (envTheme === 'dark' || envTheme === 'light') {\n themeMode = envTheme;\n } else {\n const settings = loadSettings();\n const themePref = settings.preferences.theme;\n if (themePref === 'dark' || themePref === 'light') {\n themeMode = themePref;\n } else {\n const detection = await detectTerminalTheme();\n themeMode = detection.mode;\n detectedBgHex = detection.detectedBgHex;\n }\n }\n applyThemeMode(themeMode, detectedBgHex);\n\n // createMastraCode() brought up shared resources and minted the single\n // session that all work runs through. The AgentController owns no session of its own.\n const session = result.session;\n\n analytics = createMastraCodeAnalytics({ version: getCurrentVersion() });\n analytics.capture('mastracode_session_started', {\n mode: session.mode.get(),\n resourceId: session.identity.getResourceId(),\n hasAuthStorage: Boolean(authStorage),\n hasMcp: Boolean(mcpManager),\n theme: themeMode,\n });\n\n tui = new MastraTUI({\n controller: controller,\n session,\n hookManager,\n analytics,\n authStorage,\n mcpManager,\n pluginManager: result.pluginManager,\n storageMaintenance: result.storageMaintenance,\n processMemoryDiagnostics,\n knowledgeInspector: result.knowledgeInspector,\n appName: 'Mastra Code',\n version: getCurrentVersion(),\n inlineQuestions: true,\n githubSignals: result.githubSignals,\n exit: exitCode => void shutdownAndExit(exitCode),\n ...(pipedInput ? { initialMessage: `The following was piped via stdin:\\n\\n${pipedInput}` } : {}),\n });\n tui.run().catch(error => {\n handleFatalError(error);\n });\n\n if (settings.browser.enabled) {\n void loadBrowser()\n .then(browser => {\n if (!browser) return;\n controller.setBrowser(browser);\n void session.state.set({ activeBrowserSettings: settings.browser } as any).catch(() => {});\n })\n .catch(() => {});\n }\n}\n\nconst asyncCleanup = (): Promise<void> => {\n cleanupPromise ??= (async () => {\n releaseAllThreadLocks();\n // Stop plugin-contributed signal providers (and the plugin reload listener)\n // before quiescing workers: a provider that keeps polling past this point\n // could dispatch into a controller that is shutting down.\n try {\n stopPluginSignalProviders?.();\n } catch {\n // Best-effort — the process is exiting.\n }\n const diagnosticsShutdown = processMemoryDiagnostics\n ? stopProcessMemoryDiagnosticsWithTimeout(processMemoryDiagnostics, message => console.warn(message))\n : undefined;\n const closeSignalsPubSub = (signalsPubSub as { close?: () => Promise<void> | void } | undefined)?.close;\n await Promise.allSettled([mcpManager?.disconnect(), controller?.stopIntervals(), closeSignalsPubSub?.()]);\n // Mastra owns the workspaces and must destroy them to stop retained language\n // servers before storage is closed.\n await Promise.allSettled([controller?.getMastra()?.shutdown(), analytics?.shutdown()]);\n // Checkpoint WAL and close the local storage connection after all producers\n // and timers are quiesced. Idempotent — repeated signals (SIGINT then SIGHUP)\n // close only once. LibSQLStore.close()/LibSQLVector.close() truncate the WAL\n // and switch back to DELETE journal mode for a clean shutdown.\n if (!storageClosed) {\n storageClosed = true;\n await storageMaintenance?.closeStorage?.().catch(() => {\n // Swallow — best-effort cleanup during shutdown. The process is exiting.\n });\n }\n await diagnosticsShutdown;\n })();\n return cleanupPromise;\n};\n\nconst shutdownAndExit = createShutdownCoordinator(asyncCleanup, exitCode => process.exit(exitCode));\n\nprocess.on('beforeExit', () => {\n void asyncCleanup();\n});\nprocess.on('exit', () => {\n // Ensure terminal protocols (kitty keyboard, modifyOtherKeys, bracketed paste,\n // raw mode) are disabled on ANY exit path. Without this, killing the process\n // via SIGINT/SIGTERM leaves the terminal in a corrupted state where keypresses\n // produce escape sequences like \"5;99~\" instead of normal characters.\n try {\n tui?.stop();\n } catch {\n // Failsafe: even if MastraTUI.stop() throws, write raw terminal reset\n // sequences to disable Kitty keyboard protocol, bracketed paste, and\n // modifyOtherKeys. These are the exact sequences pi-tui's terminal.stop()\n // would write.\n }\n // Belt-and-suspenders: always write terminal reset sequences directly,\n // regardless of whether tui.stop() succeeded. Writing them twice is harmless\n // but missing them leaves the terminal in a corrupted state.\n try {\n process.stdout.write(\n '\\x1b[?2004l' + // disable bracketed paste\n '\\x1b[<u' + // pop kitty keyboard protocol\n '\\x1b[>4;0m' + // disable modifyOtherKeys\n '\\x1b[?25h', // show cursor\n );\n if (process.stdin.setRawMode) {\n process.stdin.setRawMode(false);\n }\n } catch {\n // stdout may already be closed during exit\n }\n restoreTerminalForeground();\n releaseAllThreadLocks();\n});\n\n// Start durable diagnostics shutdown before synchronous TUI teardown so a stalled\n// terminal cleanup cannot prevent the final profile capture. The exit handler still\n// provides a failsafe terminal reset if teardown throws.\nconst handleTermSignal = () => {\n void asyncCleanup();\n try {\n tui?.stop();\n } catch {\n // ignored — exit handler has failsafe reset\n }\n void shutdownAndExit(0);\n};\nprocess.on('SIGINT', handleTermSignal);\nprocess.on('SIGTERM', handleTermSignal);\nprocess.on('SIGHUP', handleTermSignal);\n\nfunction hasEconnrefused(err: unknown, depth = 0): boolean {\n if (!err || depth > 5) return false;\n const e = err as any;\n if (e.code === 'ECONNREFUSED') return true;\n if (e.cause) return hasEconnrefused(e.cause, depth + 1);\n // AggregateError has .errors array\n if (Array.isArray(e.errors)) return e.errors.some((inner: unknown) => hasEconnrefused(inner, depth + 1));\n return false;\n}\n\nfunction pluginMain(args: string[]): void {\n if (args[0] !== 'scaffold') {\n process.stderr.write('Usage: mastracode plugin scaffold <dir> [--id acme.foo] [--name \"Foo Tools\"]\\n');\n process.exit(1);\n }\n\n const dir = args[1];\n if (!dir) {\n process.stderr.write('Usage: mastracode plugin scaffold <dir> [--id acme.foo] [--name \"Foo Tools\"]\\n');\n process.exit(1);\n }\n\n const id = readFlag(args, '--id');\n const name = readFlag(args, '--name');\n const targetDir = scaffoldPlugin(dir, { ...(id ? { id } : {}), ...(name ? { name } : {}) });\n process.stdout.write(`${formatScaffoldSuccess(targetDir)}\\n`);\n}\n\nfunction readFlag(args: string[], flag: string): string | undefined {\n const index = args.indexOf(flag);\n if (index === -1) return undefined;\n const value = args[index + 1];\n if (!value || value.startsWith('--')) {\n throw new Error(`Missing value for ${flag}`);\n }\n return value;\n}\n\nfunction handleFatalError(error: unknown): void {\n // Always write to real stderr, even if console.error was overridden\n const write = (msg: string) => process.stderr.write(msg + '\\n');\n\n if (hasEconnrefused(error)) {\n const settings = loadSettings();\n const connStr = settings.storage?.pg?.connectionString;\n const target = connStr ?? 'localhost:5432';\n write(\n `\\nFailed to connect to PostgreSQL at ${target}.` +\n `\\nMake sure the database is running and accessible.` +\n `\\n\\nTo switch back to LibSQL:` +\n `\\n Set MASTRA_STORAGE_BACKEND=libsql or change the backend in /settings\\n`,\n );\n void asyncCleanup();\n try {\n tui?.stop();\n } catch {}\n void shutdownAndExit(1);\n return;\n }\n\n const msg = `Fatal error: ${error instanceof Error ? error.message : String(error)}`;\n write(msg);\n // Write crash log to file so it persists even if terminal closes\n try {\n const crashLog = `[${new Date().toISOString()}] ${msg}\\n${error instanceof Error && error.stack ? error.stack + '\\n' : ''}`;\n truncateLogFile(CRASH_LOG_PATH);\n fs.appendFileSync(CRASH_LOG_PATH, crashLog);\n truncateLogFile(CRASH_LOG_PATH);\n } catch {}\n if (error instanceof Error && error.stack) {\n write(error.stack);\n }\n void asyncCleanup();\n try {\n tui?.stop();\n } catch {}\n void shutdownAndExit(1);\n}\n\nasync function main() {\n if (process.argv[2] === 'plugin') {\n return pluginMain(process.argv.slice(3));\n }\n\n if (hasHeadlessFlag(process.argv) || process.argv.includes('--help') || process.argv.includes('-h')) {\n return runMCCli();\n }\n\n if (process.argv.includes('--acp')) {\n const { acpMain } = await import('@mastra/code-sdk/acp/index');\n return acpMain({ dangerousAutoApprove: process.argv.includes('--dangerous-auto-approve') });\n }\n\n // When stdin is piped (e.g. `cat foo | mastracode`), drain the pipe fully\n // before starting the TUI. The drain blocks until the sender process exits\n // and closes its stdout, so we never see partial output.\n let pipedInput: string | null = null;\n if (!process.stdin.isTTY) {\n process.stderr.write('Reading piped input...\\n');\n pipedInput = await drainPipedStdin();\n\n // Always reopen a real TTY — even if the pipe was empty, the original\n // stdin is consumed/closed and the TUI needs a live TTY for keyboard input.\n const reopenedStdin = reopenStdinFromTTY();\n if (!reopenedStdin) {\n process.stderr.write('No TTY available — falling back to headless mode.\\n');\n return runMCCli(pipedInput);\n }\n }\n\n return tuiMain(pipedInput);\n}\n\nmain().catch(error => {\n handleFatalError(error);\n});\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"github.d.ts","sourceRoot":"","sources":["../../../src/tui/commands/github.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"github.d.ts","sourceRoot":"","sources":["../../../src/tui/commands/github.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAuMtD,wBAAsB,mBAAmB,CAAC,GAAG,EAAE,mBAAmB,EAAE,IAAI,GAAE,MAAM,EAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAmFtG"}
|
|
@@ -2310,7 +2310,7 @@ function getCommands(modes) {
|
|
|
2310
2310
|
},
|
|
2311
2311
|
{
|
|
2312
2312
|
key: "/github",
|
|
2313
|
-
description: "Subscribe/sync GitHub PR signals"
|
|
2313
|
+
description: "Subscribe in review/working mode or sync GitHub PR signals"
|
|
2314
2314
|
},
|
|
2315
2315
|
{
|
|
2316
2316
|
key: "/goal",
|
|
@@ -16656,6 +16656,7 @@ function formatPollInterval(value) {
|
|
|
16656
16656
|
if (value % 6e4 === 0) return `${value / 6e4}m`;
|
|
16657
16657
|
return `${Math.round(value / 1e3)}s`;
|
|
16658
16658
|
}
|
|
16659
|
+
const GITHUB_USAGE = "Usage: /github subscribe <PR> [--mode review|working], /github <PR> [--mode review|working], /github unsubscribe <PR>, /github sync, or /github debug. <PR> can be 123, owner/repo#123, or a GitHub pull request URL.";
|
|
16659
16660
|
function parseGithubPRReference(input) {
|
|
16660
16661
|
const trimmed = input.trim();
|
|
16661
16662
|
if (!trimmed) return void 0;
|
|
@@ -16668,6 +16669,27 @@ function parseGithubPRReference(input) {
|
|
|
16668
16669
|
number: Number(repoReference[3])
|
|
16669
16670
|
};
|
|
16670
16671
|
}
|
|
16672
|
+
function extractGithubSubscriptionMode(args, action) {
|
|
16673
|
+
if (args.some((arg) => arg.startsWith("--mode="))) return { error: `Use the spaced form --mode review or --mode working; --mode=... is not supported. ${GITHUB_USAGE}` };
|
|
16674
|
+
const modeIndexes = args.flatMap((arg, index) => arg === "--mode" ? [index] : []);
|
|
16675
|
+
if (modeIndexes.length > 1) return { error: `Specify --mode only once. ${GITHUB_USAGE}` };
|
|
16676
|
+
if (modeIndexes.length === 0) return {
|
|
16677
|
+
referenceArgs: args,
|
|
16678
|
+
mode: "working"
|
|
16679
|
+
};
|
|
16680
|
+
if (action === "unsubscribe") return { error: `--mode applies only when subscribing. ${GITHUB_USAGE}` };
|
|
16681
|
+
const modeIndex = modeIndexes[0];
|
|
16682
|
+
const mode = args[modeIndex + 1];
|
|
16683
|
+
if (!mode) return { error: `Missing value for --mode. Use review or working. ${GITHUB_USAGE}` };
|
|
16684
|
+
if (mode !== "review" && mode !== "working") return { error: `Unknown GitHub subscription mode "${mode}". Use review or working. ${GITHUB_USAGE}` };
|
|
16685
|
+
return {
|
|
16686
|
+
referenceArgs: args.filter((_, index) => index !== modeIndex && index !== modeIndex + 1),
|
|
16687
|
+
mode
|
|
16688
|
+
};
|
|
16689
|
+
}
|
|
16690
|
+
function normalizeGithubSubscriptionMode(value) {
|
|
16691
|
+
return value === "review" ? "review" : "working";
|
|
16692
|
+
}
|
|
16671
16693
|
async function getCurrentGithubThread(ctx) {
|
|
16672
16694
|
const session = ctx.state.session;
|
|
16673
16695
|
const threadId = session?.thread?.getId?.();
|
|
@@ -16711,6 +16733,7 @@ async function describeGithubSubscriptions(ctx) {
|
|
|
16711
16733
|
return [`GitHub Signals debug for ${threadId}: ${subscriptions.length} subscription${subscriptions.length === 1 ? "" : "s"}, polling=${pollingActive ? "active" : "inactive"}${pollIntervalMs ? `, interval=${formatPollInterval(pollIntervalMs)}` : ""}`, ...subscriptions.map((subscription) => {
|
|
16712
16734
|
if (!isPlainObject(subscription)) return "- invalid subscription metadata";
|
|
16713
16735
|
const pr = `${subscription.owner}/${subscription.repo}#${subscription.number}`;
|
|
16736
|
+
const mode = `mode=${normalizeGithubSubscriptionMode(subscription.mode)}`;
|
|
16714
16737
|
const sync = subscription.lastSyncStatus ? `sync=${subscription.lastSyncStatus}` : "sync=unknown";
|
|
16715
16738
|
const poll = subscription.lastSyncAt ? `lastPoll=${formatLocalTimestamp(subscription.lastSyncAt)}` : "lastPoll=never";
|
|
16716
16739
|
const observed = [
|
|
@@ -16722,7 +16745,7 @@ async function describeGithubSubscriptions(ctx) {
|
|
|
16722
16745
|
].filter(Boolean);
|
|
16723
16746
|
const notificationTime = formatLocalTimestamp(subscription.lastNotificationAt) ?? "unknown time";
|
|
16724
16747
|
const notification = subscription.lastNotificationKind ? `lastNotification=${subscription.lastNotificationKind}/${subscription.lastNotificationPriority ?? "unknown"} at ${notificationTime}: ${subscription.lastNotificationSummary ?? ""}` : "lastNotification=none";
|
|
16725
|
-
return `- ${pr} ${sync} ${poll}${subscription.lastSyncError ? ` error=${subscription.lastSyncError}` : ""}${subscription.lastSnapshotError ? ` snapshotError=${subscription.lastSnapshotError}` : ""}${observed.length ? ` (${observed.join(", ")})` : ""}\n ${notification}`;
|
|
16748
|
+
return `- ${pr} ${mode} ${sync} ${poll}${subscription.lastSyncError ? ` error=${subscription.lastSyncError}` : ""}${subscription.lastSnapshotError ? ` snapshotError=${subscription.lastSnapshotError}` : ""}${observed.length ? ` (${observed.join(", ")})` : ""}\n ${notification}`;
|
|
16726
16749
|
})].join("\n");
|
|
16727
16750
|
}
|
|
16728
16751
|
async function syncGithubSubscriptions(ctx) {
|
|
@@ -16776,7 +16799,13 @@ async function handleGithubCommand(ctx, args = []) {
|
|
|
16776
16799
|
}
|
|
16777
16800
|
const explicitSubscribe = maybeAction === "subscribe" || maybeAction === "sub";
|
|
16778
16801
|
const action = maybeAction === "unsubscribe" || maybeAction === "unsub" ? "unsubscribe" : "subscribe";
|
|
16779
|
-
const
|
|
16802
|
+
const parsedMode = extractGithubSubscriptionMode(action === "unsubscribe" || explicitSubscribe ? restArgs : args, action);
|
|
16803
|
+
if ("error" in parsedMode) {
|
|
16804
|
+
ctx.showError(parsedMode.error);
|
|
16805
|
+
return;
|
|
16806
|
+
}
|
|
16807
|
+
const { referenceArgs, mode } = parsedMode;
|
|
16808
|
+
const inlineReference = referenceArgs.join(" ").trim();
|
|
16780
16809
|
const currentThread = await getCurrentGithubThread(ctx);
|
|
16781
16810
|
const existingSubscriptions = getGithubSubscriptionsFromThreadMetadata(currentThread.metadata);
|
|
16782
16811
|
const reference = inlineReference ? inlineReference : action === "unsubscribe" && existingSubscriptions.length === 1 ? existingSubscriptions[0] : await askModalQuestion(ctx.state.ui, {
|
|
@@ -16786,7 +16815,7 @@ async function handleGithubCommand(ctx, args = []) {
|
|
|
16786
16815
|
if (reference === null) return;
|
|
16787
16816
|
const parsed = typeof reference === "string" ? parseGithubPRReference(reference) : reference;
|
|
16788
16817
|
if (!parsed) {
|
|
16789
|
-
ctx.showError(
|
|
16818
|
+
ctx.showError(GITHUB_USAGE);
|
|
16790
16819
|
return;
|
|
16791
16820
|
}
|
|
16792
16821
|
if (!currentThread.threadId || !currentThread.resourceId) {
|
|
@@ -16794,19 +16823,32 @@ async function handleGithubCommand(ctx, args = []) {
|
|
|
16794
16823
|
return;
|
|
16795
16824
|
}
|
|
16796
16825
|
const githubSignalsProcessor = ctx.state.options?.githubSignals;
|
|
16797
|
-
|
|
16798
|
-
if (!runOperation) {
|
|
16826
|
+
if (!githubSignalsProcessor) {
|
|
16799
16827
|
ctx.showError("GitHub signals are not available. Enable them in /settings and restart MastraCode.");
|
|
16800
16828
|
return;
|
|
16801
16829
|
}
|
|
16802
16830
|
try {
|
|
16803
|
-
|
|
16831
|
+
if (action === "unsubscribe") {
|
|
16832
|
+
const result = await githubSignalsProcessor.unsubscribeThreadFromPR({
|
|
16833
|
+
threadId: currentThread.threadId,
|
|
16834
|
+
resourceId: currentThread.resourceId,
|
|
16835
|
+
pr: parsed
|
|
16836
|
+
});
|
|
16837
|
+
const prefix = result.removed ? "Unsubscribed from" : "No subscription found for";
|
|
16838
|
+
ctx.showInfo(`${prefix} ${result.owner}/${result.repo}#${result.number}.`);
|
|
16839
|
+
return;
|
|
16840
|
+
}
|
|
16841
|
+
const result = await githubSignalsProcessor.subscribeThreadToPR({
|
|
16804
16842
|
threadId: currentThread.threadId,
|
|
16805
16843
|
resourceId: currentThread.resourceId,
|
|
16806
|
-
pr: parsed
|
|
16844
|
+
pr: parsed,
|
|
16845
|
+
mode
|
|
16807
16846
|
});
|
|
16808
|
-
|
|
16809
|
-
|
|
16847
|
+
if (result.terminalState) {
|
|
16848
|
+
ctx.showInfo(`Not subscribed to ${result.owner}/${result.repo}#${result.number} in review mode because it is already ${result.terminalState}.`);
|
|
16849
|
+
return;
|
|
16850
|
+
}
|
|
16851
|
+
ctx.showInfo(`Subscribed to ${result.owner}/${result.repo}#${result.number} in ${normalizeGithubSubscriptionMode(result.mode)} mode.`);
|
|
16810
16852
|
} catch (error) {
|
|
16811
16853
|
ctx.showError(`Failed to ${action} GitHub PR: ${error instanceof Error ? error.message : String(error)}`);
|
|
16812
16854
|
}
|
|
@@ -23959,4 +24001,4 @@ var MastraTUI = class MastraTUI {
|
|
|
23959
24001
|
//#endregion
|
|
23960
24002
|
export { mastraBrand as _, OMProgressComponent as a, ToolExecutionComponentEnhanced as c, detectTerminalTheme as d, applyThemeMode as f, mastra as g, getThemeMode as h, LoginDialogComponent as i, ModelSelectorComponent as l, getMarkdownTheme as m, createTUIState as n, formatOMStatus as o, getEditorTheme as p, LoginSelectorComponent as r, UserMessageComponent as s, MastraTUI as t, AssistantMessageComponent as u, restoreTerminalForeground as v, theme as y };
|
|
23961
24003
|
|
|
23962
|
-
//# sourceMappingURL=tui-
|
|
24004
|
+
//# sourceMappingURL=tui-BaobOqGM.js.map
|