@mikitasazan/notify 1.19.0 → 1.21.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/README.md +7 -4
- package/dist/cli.js +11 -2
- package/dist/events.d.ts +16 -1
- package/dist/events.js +25 -0
- package/dist/render.js +6 -4
- package/dist/routes.d.ts +8 -0
- package/dist/routes.js +32 -26
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -91,8 +91,10 @@ notify report --project playhub --json < payload.json # весь объект
|
|
|
91
91
|
Скобка у слова типа говорит одним словом, чем кончилось: `Deploy (OK)`,
|
|
92
92
|
`CI (Fail)`, `Job (Off)`, `Job (Silent)`, `Issue (Assigned)`, `PR (Merged)`.
|
|
93
93
|
Она стоит там, где у типа исходов больше одного. У `incident` состояние одно,
|
|
94
|
-
поэтому его скобка называет МЕСТО, где горит: `Incident (
|
|
95
|
-
`Incident (Session)` — слово из `--scope`, без него имя
|
|
94
|
+
поэтому его скобка называет МЕСТО, где горит: `Incident (vault)`,
|
|
95
|
+
`Incident (Session)` — слово из `--scope`, без него человеческое имя проекта
|
|
96
|
+
(таблица `DISPLAY` в `src/events.ts`; `vault` и `mac-config` — нарочно со
|
|
97
|
+
строчной, это машина и хранилище, а не бренды). У `report`
|
|
96
98
|
исхода нет вовсе, и скобку занимает день: `Report (2026-08-23 / 2026-08-22)`.
|
|
97
99
|
|
|
98
100
|
У `job` есть ещё два необязательных флага: `--via` — где задача крутилась
|
|
@@ -147,8 +149,9 @@ notify report --project playhub --json < payload.json # весь объект
|
|
|
147
149
|
живому аккаунту, ботом это не сделать.
|
|
148
150
|
2. `notify setup <chat_id> maphub` — заведёт вкладки «⚙️ Ops» и «💬 Dev» и
|
|
149
151
|
напечатает готовую строку.
|
|
150
|
-
3. Вставить строку в `src/routes.ts
|
|
151
|
-
`src/events.ts`), выпустить
|
|
152
|
+
3. Вставить строку в `src/routes.ts`, значение в тип `Project` и человеческое
|
|
153
|
+
имя в `DISPLAY` в `src/events.ts` (тест держит их в одном списке), выпустить
|
|
154
|
+
пакет.
|
|
152
155
|
4. В репозиторий проекта — трёхстрочный `.github/workflows/notify.yml`,
|
|
153
156
|
вызывающий `mikitasazan/notify/.github/workflows/ops-notify.yml@v1`:
|
|
154
157
|
CI, деплой, PR и задачи начинают приходить сами.
|
package/dist/cli.js
CHANGED
|
@@ -23,11 +23,12 @@
|
|
|
23
23
|
* notify setup <forum chat_id> <project key> # create the tabs, see setup.ts
|
|
24
24
|
*/
|
|
25
25
|
import { readFileSync } from 'node:fs';
|
|
26
|
+
import { DISPLAY } from "./events.js";
|
|
26
27
|
import { KNOWN_FLAGS } from "./cli-flags.js";
|
|
27
28
|
import { render, sessionTitle } from "./render.js";
|
|
28
29
|
import { lintCard } from "./lint.js";
|
|
29
30
|
import { notify } from "./send.js";
|
|
30
|
-
import { ROUTES } from "./routes.js";
|
|
31
|
+
import { ROUTES, chatTitle } from "./routes.js";
|
|
31
32
|
import { setupTopic } from "./setup.js";
|
|
32
33
|
const log = (msg) => console.error(`[notify] ${msg}`);
|
|
33
34
|
/**
|
|
@@ -58,7 +59,15 @@ if (command === 'lint-text') {
|
|
|
58
59
|
process.exit(0);
|
|
59
60
|
}
|
|
60
61
|
if (command === 'routes') {
|
|
61
|
-
|
|
62
|
+
// `display`/`title` ride alongside the routing facts, not instead of them —
|
|
63
|
+
// every existing field stays. The avatar scripts and the name-drift check
|
|
64
|
+
// read `title` here rather than asking Telegram, so it must be `chatTitle()`
|
|
65
|
+
// verbatim, not a second guess at the same name.
|
|
66
|
+
const rows = Object.fromEntries(Object.keys(ROUTES).map((p) => [
|
|
67
|
+
p,
|
|
68
|
+
{ ...ROUTES[p], display: DISPLAY[p], title: chatTitle(p) }
|
|
69
|
+
]));
|
|
70
|
+
process.stdout.write(`${JSON.stringify(rows, null, 2)}\n`);
|
|
62
71
|
process.exit(0);
|
|
63
72
|
}
|
|
64
73
|
if (command === 'setup') {
|
package/dist/events.d.ts
CHANGED
|
@@ -10,7 +10,22 @@
|
|
|
10
10
|
* - required fields are never added — only a new event type.
|
|
11
11
|
* That keeps old caller code and a new package compatible both ways.
|
|
12
12
|
*/
|
|
13
|
-
export type Project = 'playhub' | 'one-q' | 'zabukai' | 'game-publisher' | 'vault' | 'mac-config' | 'alitools' | 'htmlg';
|
|
13
|
+
export type Project = 'playhub' | 'one-q' | 'zabukai' | 'game-publisher' | 'vault' | 'mac-config' | 'alitools' | 'htmlg' | '2roles';
|
|
14
|
+
/**
|
|
15
|
+
* The human name of a project, written exactly as the owner writes it.
|
|
16
|
+
* Source of truth is the project card index (`project-index` skill,
|
|
17
|
+
* `site-profiles.md`) in mac-config — a project key is a machine identifier
|
|
18
|
+
* and was never meant to be printed; `cap()` guessed at a name by capitalizing
|
|
19
|
+
* the key, which is how `htmlg` showed up as «Htmlg» on the one card that
|
|
20
|
+
* printed it (the Incident scope fallback, `render.ts`).
|
|
21
|
+
*
|
|
22
|
+
* `mac-config` and `vault` stay lowercase on purpose: a machine and a store,
|
|
23
|
+
* not brands — capitalizing them would invent a name the owner never uses.
|
|
24
|
+
*
|
|
25
|
+
* A Telegram chat title must equal `chatTitle()` in `routes.ts`, which is
|
|
26
|
+
* built out of this table.
|
|
27
|
+
*/
|
|
28
|
+
export declare const DISPLAY: Record<Project, string>;
|
|
14
29
|
/**
|
|
15
30
|
* A stable machine key for the task — the instance tag on the FIRST line of
|
|
16
31
|
* every card, shaped as `#key` (with no project name: the card already sits
|
package/dist/events.js
CHANGED
|
@@ -10,6 +10,31 @@
|
|
|
10
10
|
* - required fields are never added — only a new event type.
|
|
11
11
|
* That keeps old caller code and a new package compatible both ways.
|
|
12
12
|
*/
|
|
13
|
+
/**
|
|
14
|
+
* The human name of a project, written exactly as the owner writes it.
|
|
15
|
+
* Source of truth is the project card index (`project-index` skill,
|
|
16
|
+
* `site-profiles.md`) in mac-config — a project key is a machine identifier
|
|
17
|
+
* and was never meant to be printed; `cap()` guessed at a name by capitalizing
|
|
18
|
+
* the key, which is how `htmlg` showed up as «Htmlg» on the one card that
|
|
19
|
+
* printed it (the Incident scope fallback, `render.ts`).
|
|
20
|
+
*
|
|
21
|
+
* `mac-config` and `vault` stay lowercase on purpose: a machine and a store,
|
|
22
|
+
* not brands — capitalizing them would invent a name the owner never uses.
|
|
23
|
+
*
|
|
24
|
+
* A Telegram chat title must equal `chatTitle()` in `routes.ts`, which is
|
|
25
|
+
* built out of this table.
|
|
26
|
+
*/
|
|
27
|
+
export const DISPLAY = {
|
|
28
|
+
playhub: 'PlayHub',
|
|
29
|
+
'one-q': 'One-Q',
|
|
30
|
+
zabukai: 'Zabukai',
|
|
31
|
+
'game-publisher': 'Game Publisher',
|
|
32
|
+
vault: 'vault',
|
|
33
|
+
'mac-config': 'mac-config',
|
|
34
|
+
alitools: 'Alitools',
|
|
35
|
+
htmlg: 'HTMLG',
|
|
36
|
+
'2roles': '2Roles'
|
|
37
|
+
};
|
|
13
38
|
/** Red = with sound. Everything else is silent. (There is no separate "incidents" topic any more — an incident is visible in the project's feed.) */
|
|
14
39
|
/**
|
|
15
40
|
* The icon dictionary. Two laws, both set by the owner on 25.08.2026:
|
package/dist/render.js
CHANGED
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
* separates BLOCKS BY MEANING (header / body / actions), not mechanically
|
|
20
20
|
* after every line.
|
|
21
21
|
*/
|
|
22
|
-
import { ICON, iconFor } from "./events.js";
|
|
22
|
+
import { DISPLAY, ICON, iconFor } from "./events.js";
|
|
23
23
|
/**
|
|
24
24
|
* A label gets a capital letter — but NOT a name that is deliberately
|
|
25
25
|
* written lowercase: `iOS` was turning into `IOS`. The signal is a capital
|
|
@@ -971,12 +971,14 @@ const renderIncident = (e) => {
|
|
|
971
971
|
const findings = bullets(e.items, false);
|
|
972
972
|
return join([
|
|
973
973
|
// The bracket on an incident names WHERE it burns, not how it ended —
|
|
974
|
-
// it has one ending. `Incident (
|
|
975
|
-
// word from the sender, the project name stands in
|
|
974
|
+
// it has one ending. `Incident (vault):`, `Incident (Session):`; with no
|
|
975
|
+
// word from the sender, the project's own DISPLAY name stands in — the
|
|
976
|
+
// owner's human spelling, not `cap()`'s guess at one (`cap('htmlg')` gave
|
|
977
|
+
// «Htmlg», the one place a project key ever reached a human eye).
|
|
976
978
|
// `filled`, not `??`: `scope: ''` and `scope: ' '` are a sender that
|
|
977
979
|
// named no place, and `??` let the first past the project fallback (no
|
|
978
980
|
// bracket at all) and the second into a visibly empty one.
|
|
979
|
-
typeLine(iconFor(e), 'Incident', e.title, e.url, filled(e.scope) ??
|
|
981
|
+
typeLine(iconFor(e), 'Incident', e.title, e.url, filled(e.scope) ?? DISPLAY[e.project]),
|
|
980
982
|
e.detail && e.detail !== e.title ? note(e.detail) : null,
|
|
981
983
|
// The rows below came from the `session` card when it was folded in
|
|
982
984
|
// (03.09.2026), in the order they had there: which copy, what the guard
|
package/dist/routes.d.ts
CHANGED
|
@@ -44,6 +44,14 @@ type Forum = {
|
|
|
44
44
|
dev?: number;
|
|
45
45
|
};
|
|
46
46
|
export declare const ROUTES: Record<Project, Forum>;
|
|
47
|
+
/**
|
|
48
|
+
* A solo project's chat is «<Name> · Ops»; a team forum is just the name — the
|
|
49
|
+
* forum already carries its own «Ops»/«Dev» tabs, so the chat's own title
|
|
50
|
+
* does not need to repeat the word. The real Telegram chat title and this
|
|
51
|
+
* function must agree: the avatar scripts and the name-drift check both read
|
|
52
|
+
* it through `notify routes --json`, not by asking Telegram.
|
|
53
|
+
*/
|
|
54
|
+
export declare const chatTitle: (p: Project) => string;
|
|
47
55
|
export type Target = {
|
|
48
56
|
chat: string;
|
|
49
57
|
thread?: number;
|
package/dist/routes.js
CHANGED
|
@@ -1,32 +1,38 @@
|
|
|
1
|
-
import { severity } from "./events.js";
|
|
1
|
+
import { DISPLAY, severity } from "./events.js";
|
|
2
2
|
export const ROUTES = {
|
|
3
|
-
//
|
|
4
|
-
//
|
|
5
|
-
//
|
|
6
|
-
// message, it is
|
|
3
|
+
// The only project with a team, and so the only forum left. ops/dev =
|
|
4
|
+
// 22/23, not 3/4: the old tabs were deleted by hand on 27.07.2026, and
|
|
5
|
+
// Telegram removes a topic's messages along with it. A recreated topic
|
|
6
|
+
// gets a NEW id — a topic's id is the id of its first message, it is
|
|
7
|
+
// never reused.
|
|
7
8
|
zabukai: { chat: '-1004299939100', ops: 22, dev: 23 },
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
//
|
|
12
|
-
//
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
//
|
|
20
|
-
//
|
|
21
|
-
//
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
//
|
|
25
|
-
|
|
26
|
-
// 05.09.2026 as «HTMLG · Ops» (HTMLG is the HTML5-games business; the brand
|
|
27
|
-
// and domain of its portal may change, the project name does not).
|
|
28
|
-
htmlg: { chat: '-1004334723487' }
|
|
9
|
+
// Every row below is a project the owner runs alone. Their Topics were
|
|
10
|
+
// turned off on 06.09.2026 and their `ops` numbers went with them: a card
|
|
11
|
+
// now goes to the chat itself. Sending a thread id into a chat that is no
|
|
12
|
+
// longer a forum fails with "message thread not found", so a row here and
|
|
13
|
+
// the chat's own setting must always agree.
|
|
14
|
+
playhub: { chat: '-1004418379613' },
|
|
15
|
+
'game-publisher': { chat: '-1004292453693' },
|
|
16
|
+
'one-q': { chat: '-1004466909784' },
|
|
17
|
+
vault: { chat: '-1004459314999' },
|
|
18
|
+
'mac-config': { chat: '-1004442522004' },
|
|
19
|
+
alitools: { chat: '-1003904331479' },
|
|
20
|
+
// Created 05.09.2026 as «HTMLG · Ops», the first chat built this way
|
|
21
|
+
// (HTMLG is the HTML5-games business; the brand and domain of its portal
|
|
22
|
+
// may change, the project name does not).
|
|
23
|
+
htmlg: { chat: '-1004334723487' },
|
|
24
|
+
// Created 08.09.2026 as «2Roles · Ops»: the third focus project, the owner
|
|
25
|
+
// runs it alone.
|
|
26
|
+
'2roles': { chat: '-1004314188744' }
|
|
29
27
|
};
|
|
28
|
+
/**
|
|
29
|
+
* A solo project's chat is «<Name> · Ops»; a team forum is just the name — the
|
|
30
|
+
* forum already carries its own «Ops»/«Dev» tabs, so the chat's own title
|
|
31
|
+
* does not need to repeat the word. The real Telegram chat title and this
|
|
32
|
+
* function must agree: the avatar scripts and the name-drift check both read
|
|
33
|
+
* it through `notify routes --json`, not by asking Telegram.
|
|
34
|
+
*/
|
|
35
|
+
export const chatTitle = (p) => ROUTES[p].ops === undefined ? `${DISPLAY[p]} · Ops` : DISPLAY[p];
|
|
30
36
|
/**
|
|
31
37
|
* Where an event goes. Everything goes to its own project's "Ops" tab; a
|
|
32
38
|
* red one arrives there too, just with sound.
|
package/package.json
CHANGED