@aistastudio/myc 0.3.4 → 0.3.6

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/README.md CHANGED
@@ -31,9 +31,11 @@ Installation is one command:
31
31
 
32
32
  ```bash
33
33
  bun install -g @aistastudio/myc # 3.20 MB, 10 files, no models pulled at install
34
- myc --version # myc 0.3.4 (schema 1)
34
+ myc --version # myc 0.3.6 (schema 1)
35
35
  ```
36
36
 
37
+ It runs on macOS and Linux; on Windows, use WSL.
38
+
37
39
  The embedding model is **not** downloaded during install. Semantic search is
38
40
  opt-in and explicit: `myc models fetch` (129 MB, ~7 s). Until then search is
39
41
  lexical and says so.
@@ -80,10 +82,27 @@ Before anything else the helper checks, without starting myc, whether there is
80
82
  a workspace here (a git worktree is resolved through its main copy), and stays
81
83
  silent when there is none or the project wires myc itself: in a project without
82
84
  myc the hook costs one node start, and prime never arrives twice. Outside a
83
- workspace the MCP server offers zero tools and no instructions. The user's
84
- `statusLine` is never touched (it belongs to orca), and `--hook-mode replace`
85
- is refused here. The journal is `~/.myc/wire-user.json`; `myc unwire --scope
86
- user` restores the settings node by node and removes the MCP server.
85
+ workspace the MCP server offers zero tools and no instructions. `--hook-mode
86
+ replace` is refused here. The journal is `~/.myc/wire-user.json`; `myc unwire
87
+ --scope user` restores the settings node by node and removes the MCP server.
88
+
89
+ With `--status-line` the user layer also gets myc's status line, `myc
90
+ statusline --scope user`: in a myc workspace — a git worktree of one included —
91
+ it is the full line, outside one it prints nothing of its own. The line that was
92
+ there (orca's, which prints nothing and posts the input to orca) is kept in the
93
+ journal, not in our command, and gets the same stdin on every redraw, never
94
+ waited on: orca takes a line whose command mentions its
95
+ `agent-hooks/claude-statusline.sh` for its own and removes it when it
96
+ uninstalls (a foreign line it leaves alone), so ours never carries the word
97
+ `claude-statusline`. A
98
+ project with its own myc line keeps it, and that line hands the input to the
99
+ same recorded line. If another tool replaces the user line after wire, `myc
100
+ doctor --hooks` says so; `myc wire --scope user --status-line` puts ours back
101
+ and makes the new line the previous one, and `myc unwire --scope user` puts the
102
+ previous line back byte for byte. `myc doctor --hooks` checks the whole user
103
+ layer against the journal: myc's hook entries and rules still in
104
+ `~/.claude/settings.json`, the helpers exactly what this build writes (a stale
105
+ one is named with the build that wrote it), the status line, the MCP server.
87
106
 
88
107
  ## Heavy commands take turns
89
108
 
@@ -117,7 +136,8 @@ myc run: waiting for a 'heavy' slot (1/1 busy, 1 waiting ahead), waited 0.0s of
117
136
 
118
137
  A holder that dies — even by `SIGKILL` — frees its slot; a `myc run` nested
119
138
  inside another one runs at once, in its parent's slot. One slot per lane by
120
- default, `MYC_HEAVY_SLOTS=2` for two.
139
+ default, `MYC_HEAVY_SLOTS=2` for two. myc does not load the project's `.env` or
140
+ `bunfig.toml`: the command gets the caller's environment as is.
121
141
 
122
142
  **Agents don't have to remember it.** `myc wire --queue-hook` installs a Claude
123
143
  Code `PreToolUse` hook that rewrites a heavy Bash command into
package/bin/myc.js CHANGED
@@ -1,4 +1,4 @@
1
- #!/usr/bin/env bun
1
+ #!/usr/bin/env -S bun --no-env-file --config=/dev/null
2
2
  /**
3
3
  * Точка входа npm-пакета @aistastudio/myc.
4
4
  *
@@ -10,6 +10,27 @@
10
10
  * Порядок важен: сначала проверка рантайма, и только потом ДИНАМИЧЕСКИЙ
11
11
  * импорт бандла. Статический импорт Node разрешил бы до первой строки тела
12
12
  * модуля — и мы бы снова упали на `bun:sqlite`, не успев ничего сказать.
13
+ *
14
+ * SHEBANG. Оба флага — про ЧУЖОЙ каталог: myc зовут хуки и MCP в каждом
15
+ * проекте пользователя, и cwd — это его проект. Без них Bun ДО первой строки
16
+ * этого файла грузит .env, .env.local, .env.<NODE_ENV> каталога в process.env
17
+ * (а `myc run` отдавал их команде: 2026-09-11 в cherry `bun test` получил
18
+ * 20 переменных EXPO_PUBLIC_* из .env worktree, которых в оболочке агента не
19
+ * было) и исполняет preload из ./bunfig.toml — happy-dom и моки тестов
20
+ * проекта внутри myc.
21
+ * --no-env-file .env* не грузятся;
22
+ * --config=/dev/null пустой конфиг вместо ./bunfig.toml. «Без конфига» у
23
+ * Bun нет: `--config=` (пусто) молча возвращает
24
+ * ./bunfig.toml, несуществующий путь — фатальная ошибка
25
+ * до старта, а /dev/null есть на любой POSIX. Глобальный
26
+ * ~/.bunfig.toml Bun читает по-прежнему: он не проектный.
27
+ * `env -S` нужен, чтобы флаги дошли до bun раздельно: ядро Linux отдаёт всё
28
+ * после интерпретатора ОДНИМ аргументом. -S есть в GNU coreutils ≥ 8.30 и в
29
+ * env macOS/BSD. На Windows такой shebang не исполним: шим `bun add -g` берёт
30
+ * `-S` за программу, а cmd-shim npm -S понимает, но Bun на Windows не
31
+ * открывает /dev/null — myc там только через WSL (говорит preflight.js).
32
+ * Запуск МИМО shebang (`bun …/myc.js`) флагов не получает; второй рубеж для
33
+ * `myc run` — callerEnv в src/commands/run.ts.
13
34
  */
14
35
 
15
36
  import { spawnSync } from "node:child_process";
package/bin/preflight.js CHANGED
@@ -3,43 +3,66 @@
3
3
  * postinstall-проверка. Запускается тем рантаймом, который ставил пакет —
4
4
  * обычно это node, поэтому здесь снова голый JS без `bun:`.
5
5
  *
6
- * Зачем: shebang у bin/myc.js — `#!/usr/bin/env bun`, и если Bun в системе
7
- * нет вовсе, первая же попытка запустить `myc` даст `env: bun: No such file
8
- * or directory` (код 127) сообщение, по которому нельзя понять ни причину,
9
- * ни что делать. Наша заглушка до этого не доживает: её просто некому
6
+ * Зачем: shebang у bin/myc.js — `#!/usr/bin/env -S bun --no-env-file
7
+ * --config=/dev/null` (зачем флаги в шапке самого bin/myc.js), и если Bun в
8
+ * системе нет вовсе, первая же попытка запустить `myc` даст `env: bun: No such
9
+ * file or directory` (код 127) сообщение, по которому нельзя понять ни
10
+ * причину, ни что делать. Наша заглушка до этого не доживает: её просто некому
10
11
  * выполнить. Значит сказать надо здесь, на установке.
11
12
  *
12
13
  * Установку НЕ роняем: пакет разложен правильно, не хватает только рантайма,
13
14
  * и это чинится `curl … | bash` без переустановки.
15
+ *
16
+ * WINDOWS — та же беда другим путём: там этот shebang не исполним вовсе, даже
17
+ * при установленном Bun. Шим `bun add -g` берёт `-S` за программу
18
+ * (`interpreter executable "-S" not found`), cmd-shim npm передаёт
19
+ * `--config=/dev/null`, а Bun на Windows такого файла не находит (`ENOENT …
20
+ * while reading config`). Оба отказа — до первой строки myc, и сказать
21
+ * человеку, что делать, можно только здесь. Установку тоже не роняем.
22
+ * Предел: `bun add -g` postinstall недоверенного пакета не запускает
23
+ * («Blocked 1 postinstall»), и эту рамку увидит только ставящий через npm —
24
+ * остальным о WSL говорит README.
14
25
  */
15
26
 
16
27
  import { spawnSync } from "node:child_process";
17
28
 
18
- if (typeof process.versions.bun !== "string" && !bunOnPath()) {
29
+ if (process.platform === "win32") {
19
30
  process.stderr.write(
20
- // Рамка собирается по ширине самой длинной строки, а не подгоняется
21
- // руками: после переименования пакета `@myc/cli` -> `@aistastudio/myc`
22
- // верхняя граница разъехалась, и это первое, что видит человек без Bun.
23
- (() => {
24
- const title = "@aistastudio/myc установлен, но запускаться пока не будет";
25
- const body = [
26
- "myc работает только на Bun (хранилище на bun:sqlite).",
27
- "Bun в системе не найден.",
28
- "",
29
- " curl -fsSL https://bun.sh/install | bash",
30
- "",
31
- "После этого: myc --version",
32
- ];
33
- const w = Math.max(title.length + 3, ...body.map((l) => l.length)) + 1;
34
- const top = ` ┌─ ${title} ${"".repeat(Math.max(0, w - title.length - 2))}┐`;
35
- const mid = body.map((l) => ` │ ${l.padEnd(w)}│`);
36
- const bot = ` └${"".repeat(w + 1)}┘`;
37
- return ["", top, ...mid, bot, ""].join("\n");
38
- })(),
39
-
31
+ frame("@aistastudio/myc: Windows is not supported", [
32
+ "myc runs on macOS and Linux; on Windows use WSL.",
33
+ "The `myc` launcher will not start in cmd or PowerShell.",
34
+ "",
35
+ " wsl --install",
36
+ "",
37
+ "Then, inside WSL: install Bun and @aistastudio/myc there.",
38
+ ]),
39
+ );
40
+ } else if (typeof process.versions.bun !== "string" && !bunOnPath()) {
41
+ process.stderr.write(
42
+ frame("@aistastudio/myc установлен, но запускаться пока не будет", [
43
+ "myc работает только на Bun (хранилище на bun:sqlite).",
44
+ "Bun в системе не найден.",
45
+ "",
46
+ " curl -fsSL https://bun.sh/install | bash",
47
+ "",
48
+ "После этого: myc --version",
49
+ ]),
40
50
  );
41
51
  }
42
52
 
53
+ /**
54
+ * Рамка собирается по ширине самой длинной строки, а не подгоняется руками:
55
+ * после переименования пакета `@myc/cli` -> `@aistastudio/myc` верхняя граница
56
+ * разъехалась, и это первое, что видит человек без Bun.
57
+ */
58
+ function frame(title, body) {
59
+ const w = Math.max(title.length + 3, ...body.map((l) => l.length)) + 1;
60
+ const top = ` ┌─ ${title} ${"─".repeat(Math.max(0, w - title.length - 2))}┐`;
61
+ const mid = body.map((l) => ` │ ${l.padEnd(w)}│`);
62
+ const bot = ` └${"─".repeat(w + 1)}┘`;
63
+ return ["", top, ...mid, bot, ""].join("\n");
64
+ }
65
+
43
66
  function bunOnPath() {
44
67
  try {
45
68
  return spawnSync("bun", ["--version"], { stdio: "ignore" }).status === 0;