Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 35 additions & 0 deletions apps/website/i18n/agents.ru.json
Original file line number Diff line number Diff line change
Expand Up @@ -674,6 +674,41 @@
},
"gHashTag/trinity:tri/wallet": {
"SUMMARY": "Баланс кошелька DePIN."
},
"crm-proactive-sweep": {
"SUMMARY": "Каждые полчаса определяет продавцов, которых обслуживает зарегистрированный носитель, и обходит каждого: по HTTP вызывает CRM-инструменты рендера, спрашивает модель, что делать дальше, и присылает продавцу в его собственный чат карточку для связи. В безопасном режиме прогон пропускается целиком.",
"NAME": "CRM: проактивный обход продавцов"
},
"ton-pending-watch": {
"SUMMARY": "Каждый час читает незакрытые TON-счета, спрашивает у сети, действительно ли монеты пришли, и пишет в журнал рендера одну строку: либо что невостребованных нет, либо что человек заплатил, а зачисления не было. Только читает: платёж никогда не закрывает.",
"NAME": "Деньги: TON пришёл, но не зачислен"
},
"robokassa-unclaimed-watch": {
"SUMMARY": "Каждое утро читает незакрытые счета Robokassa за последние тридцать дней, спрашивает у провайдера состояние каждого и пишет в журнал рендера одну строку: либо что невостребованных нет, либо что человек заплатил, а зачисления не было. Только читает: платёж никогда не закрывает.",
"NAME": "Деньги: рубли пришли, но не зачислены"
},
"club-invoice-abandoned-watch": {
"SUMMARY": "Каждый час помечает как брошенные те клубные счета, которым больше часа и после которых не было оплаты, записывая по одной строке воронки на счёт, чтобы путь от карточки к счёту и дальше к оплате или отказу читался без ручного соединения таблиц. Ничего не списывает и никому не пишет.",
"NAME": "Воронка: клубные счета, которые никто не оплатил"
},
"client-telemetry-daily": {
"SUMMARY": "Каждый день в 07:00 UTC собирает отчёт о том, куда дошли клиенты и где остановились, отправляет его владельцу и удаляет уже учтённые события. Там, где ежедневный советник отчитывается о деньгах, этот отчитывается о пользовании продуктом.",
"NAME": "Клиенты: ежедневный отчёт о пользовании владельцу"
},
"inngest/999-multibots-telegraf/crm-proactive-sweep": {
"SUMMARY": "Обходит каждого продавца, которого обслуживает зарегистрированный носитель, и может прислать в его собственный чат по одной карточке для связи."
},
"inngest/999-multibots-telegraf/ton-pending-watch": {
"SUMMARY": "Каждый час спрашивает у сети, пришли ли монеты по незакрытому TON-счёту, который так и не зачислили."
},
"inngest/999-multibots-telegraf/robokassa-unclaimed-watch": {
"SUMMARY": "Каждое утро спрашивает Robokassa о незакрытых счетах за последние тридцать дней и сообщает о тех, что оплачены, но не зачислены."
},
"inngest/999-multibots-telegraf/club-invoice-abandoned-watch": {
"SUMMARY": "Помечает как брошенные клубные счета, после которых час не было оплаты, по одному разу на счёт."
},
"inngest/999-multibots-telegraf/client-telemetry-daily": {
"SUMMARY": "Отправляет владельцу ежедневный отчёт о том, куда дошли клиенты и где остановились, затем удаляет учтённые события."
}
}
}
2 changes: 1 addition & 1 deletion apps/website/public/agents/spec-agents.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion apps/website/public/crons/spec-crons.json

Large diffs are not rendered by default.

152 changes: 149 additions & 3 deletions apps/website/public/functions/manifest.json
Original file line number Diff line number Diff line change
@@ -1,17 +1,29 @@
{
"$source": "design/inngest-spec-first.md + functions-manifest.json (28 functions), the code witness for specs/functions",
"$source": "design/inngest-spec-first.md + functions-manifest.json (33 functions), the code witness for specs/functions",
"repo": "gHashTag/999-multibots-telegraf",
"generatedFrom": {
"branch": "main",
"commit": "a9c08b4",
"note": "Extracted from the source tree by the spec-first design pass of 2026-09-09; three entries carry no file/steps and eight carry retries null because the extractor did not resolve them. Copied by hand into this repository -- no sync script produces it yet."
"note": "Extracted from the source tree by the spec-first design pass of 2026-09-09; three entries carry no file/steps and eight carry retries null because the extractor did not resolve them. Copied by hand into this repository -- no sync script produces it yet.",
"addendum": {
"commit": "05fd960f1fef35d09e9ec04e642fcbe0b8c5610a",
"read_at": "2026-09-22",
"functions": [
"crm-proactive-sweep",
"ton-pending-watch",
"club-invoice-abandoned-watch",
"robokassa-unclaimed-watch",
"client-telemetry-daily"
],
"note": "Five functions registered after the 2026-09-09 pass were absent from this witness, so the site could draw no card for any of them -- including crm-proactive-sweep, which carried every failed run in the project over the week of 2026-09-22. Their rows are copied from the bot's own src/inngest_app/functions.manifest.json at this commit and carry read_at. probe_result is empty and deployed_2026_09_09 is null because no safe probe was sent to them and the 2026-09-09 deployment reading predates their registration; the deployed_2026_09_09 false the bot manifest still carries for three of them is that same stale pass, while the live status endpoint answered for all five on 2026-09-22. The 28 older rows are still as read at a9c08b4 and have drifted from this commit in about forty fields; re-pinning them is a separate pass."
}
},
"probedAt": "2026-09-09",
"deployedApp": {
"name": "telegram-bot-client",
"sdk": "js v3.54.2",
"baseFunctions": 24,
"mainRegisters": 28
"mainRegisters": 33
},
"functions": [
{
Expand Down Expand Up @@ -873,6 +885,140 @@
"probe_result": "not-deployed",
"deployed_2026_09_09": false,
"control": "spec+code"
},
{
"id": "crm-proactive-sweep",
"legacy_id": "",
"domain": "crm",
"trigger": "cron",
"event": "",
"legacy_events": [],
"cron": "*/30 * * * *",
"tz": "UTC",
"file": "src/inngest_app/functions/crm/crmProactiveSweep.ts",
"steps": [
"resolve-sellers",
"sweep-${owner}"
],
"retries": 0,
"on_failure": "admin-telegram",
"side_effects": [
"messages-user",
"paid-api",
"db-write"
],
"guard": "none",
"safe_probe": "{}",
"probe_result": "",
"deployed_2026_09_09": null,
"control": "spec+code",
"read_at": "05fd960"
},
{
"id": "ton-pending-watch",
"legacy_id": "",
"domain": "money",
"trigger": "cron",
"event": "",
"legacy_events": [],
"cron": "0 * * * *",
"tz": "UTC",
"file": "src/inngest_app/functions/money/tonPendingWatch.ts",
"steps": [
"look"
],
"retries": 0,
"on_failure": "admin-telegram",
"side_effects": [
"db-read",
"paid-api"
],
"guard": "none",
"safe_probe": "{}",
"probe_result": "",
"deployed_2026_09_09": null,
"control": "spec+code",
"read_at": "05fd960"
},
{
"id": "club-invoice-abandoned-watch",
"legacy_id": "",
"domain": "analytics",
"trigger": "cron",
"event": "",
"legacy_events": [],
"cron": "20 * * * *",
"tz": "UTC",
"file": "src/inngest_app/functions/analytics/clubInvoiceAbandonedWatch.ts",
"steps": [
"mark"
],
"retries": 0,
"on_failure": "admin-telegram",
"side_effects": [
"db-read",
"db-write"
],
"guard": "safe-mode",
"safe_probe": "{\"e2e_test\":true}",
"probe_result": "",
"deployed_2026_09_09": null,
"control": "spec+code",
"read_at": "05fd960"
},
{
"id": "robokassa-unclaimed-watch",
"legacy_id": "",
"domain": "money",
"trigger": "cron",
"event": "",
"legacy_events": [],
"cron": "20 7 * * *",
"tz": "UTC",
"file": "src/inngest_app/functions/money/robokassaUnclaimedWatch.ts",
"steps": [
"ask the provider"
],
"retries": 0,
"on_failure": "admin-telegram",
"side_effects": [
"db-read",
"paid-api"
],
"guard": "none",
"safe_probe": "{}",
"probe_result": "",
"deployed_2026_09_09": null,
"control": "spec+code",
"read_at": "05fd960"
},
{
"id": "client-telemetry-daily",
"legacy_id": "client-telemetry-daily",
"domain": "analytics",
"trigger": "cron",
"event": "",
"legacy_events": [],
"cron": "0 7 * * *",
"tz": "UTC",
"file": "src/inngest_app/functions/analytics/clientTelemetryDaily.ts",
"steps": [
"build-report",
"send",
"prune"
],
"retries": 0,
"on_failure": "admin-telegram",
"side_effects": [
"messages-owners",
"db-write"
],
"guard": "safe-mode",
"safe_probe": "{\"e2e_test\":true}",
"probe_result": "",
"deployed_2026_09_09": null,
"control": "spec+code",
"read_at": "05fd960"
}
]
}
2 changes: 1 addition & 1 deletion apps/website/public/functions/spec-functions.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion apps/website/public/providers/spec-providers.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion apps/website/public/skills/spec-skills.json

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// SPDX-License-Identifier: Apache-2.0
; specs/crons/999-multibots-telegraf-client-telemetry-daily.t27 -- cron inngest/999-multibots-telegraf/client-telemetry-daily
; Source of truth for the job card on t27.ai (#/crons?cron=inngest/999-multibots-telegraf/client-telemetry-daily).
; The schedule was read from 999-multibots-telegraf:src/inngest_app/functions/analytics/clientTelemetryDaily.ts#L62 (main @05fd960).
; A cron CONTROLS skills: RUNS names the skill IDs it launches. It is empty
; unless the source evidently invokes one -- nothing here is inferred from a name.
; phi^2 + 1/phi^2 = 3 | TRINITY

module cron_999_multibots_telegraf_client_telemetry_daily;

pub const KIND : str = "cron";
pub const ID : str = "inngest/999-multibots-telegraf/client-telemetry-daily";
pub const NAME : str = "client-telemetry-daily";
pub const HOST : str = "inngest";
pub const REPO : str = "999-multibots-telegraf";
pub const SERVICE : str = "src/inngest_app/functions/analytics/clientTelemetryDaily.ts";
pub const SUMMARY_EN : str = "Sends the owner a daily report of where clients went and where they stopped, then prunes the events it accounted for.";
pub const SCHEDULE : str = "0 7 * * *";
pub const TZ : str = "UTC";
pub const RUNS : [0]str = [];
pub const RUNS_NOTE : str = "no skill invocation found in source";
pub const ENABLED : bool = true;
pub const ON_FAILURE : str = "log";
pub const CONTROL : str = "inngest-dashboard";
pub const NOTE : str = "This job is not in public/crons/manifest.json, which is produced by scripts/sync-crons.mjs from on-disk checkouts, so the card reads spec-only until that sync runs again. A failure does not open an issue; the Inngest registration carries a failure handler that messages the admin channel, which the function card states as ON_FAILURE admin-telegram.";
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// SPDX-License-Identifier: Apache-2.0
; specs/crons/999-multibots-telegraf-club-invoice-abandoned-watch.t27 -- cron inngest/999-multibots-telegraf/club-invoice-abandoned-watch
; Source of truth for the job card on t27.ai (#/crons?cron=inngest/999-multibots-telegraf/club-invoice-abandoned-watch).
; The schedule was read from 999-multibots-telegraf:src/inngest_app/functions/analytics/clubInvoiceAbandonedWatch.ts#L22 (main @05fd960).
; A cron CONTROLS skills: RUNS names the skill IDs it launches. It is empty
; unless the source evidently invokes one -- nothing here is inferred from a name.
; phi^2 + 1/phi^2 = 3 | TRINITY

module cron_999_multibots_telegraf_club_invoice_abandoned_watch;

pub const KIND : str = "cron";
pub const ID : str = "inngest/999-multibots-telegraf/club-invoice-abandoned-watch";
pub const NAME : str = "club-invoice-abandoned-watch";
pub const HOST : str = "inngest";
pub const REPO : str = "999-multibots-telegraf";
pub const SERVICE : str = "src/inngest_app/functions/analytics/clubInvoiceAbandonedWatch.ts";
pub const SUMMARY_EN : str = "Marks the club invoices that went an hour with no charge after them as abandoned, once per invoice.";
pub const SCHEDULE : str = "20 * * * *";
pub const TZ : str = "UTC";
pub const RUNS : [0]str = [];
pub const RUNS_NOTE : str = "no skill invocation found in source";
pub const ENABLED : bool = true;
pub const ON_FAILURE : str = "log";
pub const CONTROL : str = "inngest-dashboard";
pub const NOTE : str = "This job is not in public/crons/manifest.json, which is produced by scripts/sync-crons.mjs from on-disk checkouts, so the card reads spec-only until that sync runs again. A failure does not open an issue; the Inngest registration carries a failure handler that messages the admin channel, which the function card states as ON_FAILURE admin-telegram.";
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// SPDX-License-Identifier: Apache-2.0
; specs/crons/999-multibots-telegraf-crm-proactive-sweep.t27 -- cron inngest/999-multibots-telegraf/crm-proactive-sweep
; Source of truth for the job card on t27.ai (#/crons?cron=inngest/999-multibots-telegraf/crm-proactive-sweep).
; The schedule was read from 999-multibots-telegraf:src/inngest_app/functions/crm/crmProactiveSweep.ts#L101 (main @05fd960).
; A cron CONTROLS skills: RUNS names the skill IDs it launches. It is empty
; unless the source evidently invokes one -- nothing here is inferred from a name.
; phi^2 + 1/phi^2 = 3 | TRINITY

module cron_999_multibots_telegraf_crm_proactive_sweep;

pub const KIND : str = "cron";
pub const ID : str = "inngest/999-multibots-telegraf/crm-proactive-sweep";
pub const NAME : str = "crm-proactive-sweep";
pub const HOST : str = "inngest";
pub const REPO : str = "999-multibots-telegraf";
pub const SERVICE : str = "src/inngest_app/functions/crm/crmProactiveSweep.ts";
pub const SUMMARY_EN : str = "Sweeps every seller a registered carrier serves and may push one outreach card per seller to that seller's own chat.";
pub const SCHEDULE : str = "*/30 * * * *";
pub const TZ : str = "UTC";
pub const RUNS : [0]str = [];
pub const RUNS_NOTE : str = "no skill invocation found in source";
pub const ENABLED : bool = true;
pub const ON_FAILURE : str = "log";
pub const CONTROL : str = "inngest-dashboard";
pub const NOTE : str = "This job is not in public/crons/manifest.json, which is produced by scripts/sync-crons.mjs from on-disk checkouts, so the card reads spec-only until that sync runs again. A failure does not open an issue; the Inngest registration carries a failure handler that messages the admin channel, which the function card states as ON_FAILURE admin-telegram. The same half hour is also stated by timer/999-multibots-telegraf/crmProactive-L375, the in-process interval this cron replaced on 2026-09-12; CRM_SWEEP_DRIVER=timer restores that one.";
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// SPDX-License-Identifier: Apache-2.0
; specs/crons/999-multibots-telegraf-robokassa-unclaimed-watch.t27 -- cron inngest/999-multibots-telegraf/robokassa-unclaimed-watch
; Source of truth for the job card on t27.ai (#/crons?cron=inngest/999-multibots-telegraf/robokassa-unclaimed-watch).
; The schedule was read from 999-multibots-telegraf:src/inngest_app/functions/money/robokassaUnclaimedWatch.ts#L44 (main @05fd960).
; A cron CONTROLS skills: RUNS names the skill IDs it launches. It is empty
; unless the source evidently invokes one -- nothing here is inferred from a name.
; phi^2 + 1/phi^2 = 3 | TRINITY

module cron_999_multibots_telegraf_robokassa_unclaimed_watch;

pub const KIND : str = "cron";
pub const ID : str = "inngest/999-multibots-telegraf/robokassa-unclaimed-watch";
pub const NAME : str = "robokassa-unclaimed-watch";
pub const HOST : str = "inngest";
pub const REPO : str = "999-multibots-telegraf";
pub const SERVICE : str = "src/inngest_app/functions/money/robokassaUnclaimedWatch.ts";
pub const SUMMARY_EN : str = "Asks Robokassa every morning about the pending invoices of the last thirty days and reports the ones paid but never credited.";
pub const SCHEDULE : str = "20 7 * * *";
pub const TZ : str = "UTC";
pub const RUNS : [0]str = [];
pub const RUNS_NOTE : str = "no skill invocation found in source";
pub const ENABLED : bool = true;
pub const ON_FAILURE : str = "log";
pub const CONTROL : str = "inngest-dashboard";
pub const NOTE : str = "This job is not in public/crons/manifest.json, which is produced by scripts/sync-crons.mjs from on-disk checkouts, so the card reads spec-only until that sync runs again. A failure does not open an issue; the Inngest registration carries a failure handler that messages the admin channel, which the function card states as ON_FAILURE admin-telegram.";
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// SPDX-License-Identifier: Apache-2.0
; specs/crons/999-multibots-telegraf-ton-pending-watch.t27 -- cron inngest/999-multibots-telegraf/ton-pending-watch
; Source of truth for the job card on t27.ai (#/crons?cron=inngest/999-multibots-telegraf/ton-pending-watch).
; The schedule was read from 999-multibots-telegraf:src/inngest_app/functions/money/tonPendingWatch.ts#L51 (main @05fd960).
; A cron CONTROLS skills: RUNS names the skill IDs it launches. It is empty
; unless the source evidently invokes one -- nothing here is inferred from a name.
; phi^2 + 1/phi^2 = 3 | TRINITY

module cron_999_multibots_telegraf_ton_pending_watch;

pub const KIND : str = "cron";
pub const ID : str = "inngest/999-multibots-telegraf/ton-pending-watch";
pub const NAME : str = "ton-pending-watch";
pub const HOST : str = "inngest";
pub const REPO : str = "999-multibots-telegraf";
pub const SERVICE : str = "src/inngest_app/functions/money/tonPendingWatch.ts";
pub const SUMMARY_EN : str = "Asks the chain every hour whether coins arrived against a pending TON invoice that was never credited.";
pub const SCHEDULE : str = "0 * * * *";
pub const TZ : str = "UTC";
pub const RUNS : [0]str = [];
pub const RUNS_NOTE : str = "no skill invocation found in source";
pub const ENABLED : bool = true;
pub const ON_FAILURE : str = "log";
pub const CONTROL : str = "inngest-dashboard";
pub const NOTE : str = "This job is not in public/crons/manifest.json, which is produced by scripts/sync-crons.mjs from on-disk checkouts, so the card reads spec-only until that sync runs again. A failure does not open an issue; the Inngest registration carries a failure handler that messages the admin channel, which the function card states as ON_FAILURE admin-telegram.";
Loading
Loading