layero 0.10.5 → 0.11.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/logs.js CHANGED
@@ -11,6 +11,15 @@ function colorForStream(stream) {
11
11
  return (s) => s;
12
12
  }
13
13
  }
14
+ /**
15
+ * Строки npm о каждом скачанном пакете (`npm http fetch …`, `npm http cache …`).
16
+ *
17
+ * На проде это почти четверть строк логов сборки: 92 тыс. из последних
18
+ * 400 тыс. строк у 154 сборок (замер 18.09.2026). В `--json` каждая уходила
19
+ * отдельным событием `build_log`, и агент тонул в них, не видя ошибки. Полный
20
+ * лог по-прежнему у `layero logs`.
21
+ */
22
+ const NPM_HTTP_RE = /^npm http (fetch|cache) /;
14
23
  export async function streamDeployLogs(api, deployId) {
15
24
  // In JSON mode stdout must stay a clean JSON-lines stream: build logs go
16
25
  // out as structured `build_log` / `stage` events (N2), never as raw text
@@ -19,22 +28,42 @@ export async function streamDeployLogs(api, deployId) {
19
28
  const json = detectMode().json;
20
29
  let afterId = 0;
21
30
  let lastStage = null;
31
+ let hiddenNoted = false;
32
+ const announce = (name) => {
33
+ if (name === lastStage)
34
+ return;
35
+ lastStage = name;
36
+ if (json) {
37
+ emit({ event: "stage", name });
38
+ }
39
+ else {
40
+ process.stderr.write(chalk.bold.blue(`▶ stage: ${name}\n`));
41
+ }
42
+ };
22
43
  // Loop until terminal — the server's per-stage timeouts bound duration.
23
44
  // eslint-disable-next-line no-constant-condition
24
45
  while (true) {
25
46
  const poll = await api.pollLogs(deployId, afterId);
26
- if (poll.current_stage && poll.current_stage !== lastStage) {
27
- lastStage = poll.current_stage;
28
- if (json) {
29
- emit({ event: "stage", name: poll.current_stage });
30
- }
31
- else {
32
- process.stderr.write(chalk.bold.blue(`▶ stage: ${poll.current_stage}\n`));
33
- }
34
- }
47
+ // 🚨 Этап объявляем по СТРОКЕ, а не по текущему этапу деплоя. Опрос
48
+ // приносит пачку строк, где хвост прошлого этапа идёт вперемешку с
49
+ // началом нового, а `current_stage` — это уже новый: объявленный до
50
+ // пачки, он приписывал ему строки прошлого (симуляция 18.09.2026).
35
51
  for (const line of poll.lines) {
36
52
  afterId = Math.max(afterId, line.id);
53
+ if (line.stage)
54
+ announce(line.stage);
37
55
  if (json) {
56
+ if (NPM_HTTP_RE.test(line.line)) {
57
+ if (!hiddenNoted) {
58
+ hiddenNoted = true;
59
+ emit({
60
+ event: "build_log",
61
+ line: `[layero] "npm http" download lines are hidden in --json; full log: npx layero@latest logs --deploy ${deployId}`,
62
+ stream: "meta",
63
+ });
64
+ }
65
+ continue;
66
+ }
38
67
  emit({ event: "build_log", line: line.line, stream: line.stream });
39
68
  }
40
69
  else {
@@ -42,6 +71,8 @@ export async function streamDeployLogs(api, deployId) {
42
71
  process.stdout.write(paint(line.line) + "\n");
43
72
  }
44
73
  }
74
+ if (poll.current_stage)
75
+ announce(poll.current_stage);
45
76
  if (poll.terminal) {
46
77
  return poll;
47
78
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "layero",
3
- "version": "0.10.5",
3
+ "version": "0.11.1",
4
4
  "description": "Layero CLI — deploy a directory or a repo to hosting with build servers in Russia. JSON events and exit codes for AI agents and CI.",
5
5
  "license": "MIT",
6
6
  "type": "module",