run402 4.34.0 → 4.35.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/cli.mjs +18 -1
- package/lib/command-manifest.mjs +15 -10
- package/lib/contacts.mjs +428 -0
- package/lib/deliveries.mjs +101 -0
- package/lib/escalations.mjs +15 -50
- package/lib/notifications.mjs +58 -577
- package/lib/subscriptions.mjs +146 -0
- package/package.json +1 -1
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `run402 subscriptions` — which events reach which destination.
|
|
3
|
+
*
|
|
4
|
+
* Was `run402 notifications rules`. One subscription is one match (project,
|
|
5
|
+
* source, event types, classes) resolving to one destination.
|
|
6
|
+
*
|
|
7
|
+
* HONESTY NOTE (legible-cli-surface D5): this surface accepts subscriptions it
|
|
8
|
+
* cannot currently honour. The delivery pipeline consumes `source IN
|
|
9
|
+
* ('app','agent-messaging')`, so a subscription naming a platform-emitted type
|
|
10
|
+
* — a lifecycle cliff, an error rollup — is stored, listed back as enabled,
|
|
11
|
+
* and never fires. Measured in production: one live rule, five such types, 101
|
|
12
|
+
* qualifying events, zero delivered. The gateway reports this at create time;
|
|
13
|
+
* the pipeline widening that removes the need for the report is a filed
|
|
14
|
+
* successor, and the report must stop firing because the pipeline carries
|
|
15
|
+
* those events — never because the check was removed.
|
|
16
|
+
*
|
|
17
|
+
* HTTP paths unchanged (`/agent/v1/notifications/rules*`); the allowance auth
|
|
18
|
+
* headers are PATH-scoped and must keep naming the real route.
|
|
19
|
+
*/
|
|
20
|
+
import { allowanceAuthHeaders } from "./config.mjs";
|
|
21
|
+
import { getSdk } from "./sdk.mjs";
|
|
22
|
+
import { reportSdkError, fail } from "./sdk-errors.mjs";
|
|
23
|
+
import {
|
|
24
|
+
assertAllowedValue,
|
|
25
|
+
assertKnownFlags,
|
|
26
|
+
flagValue,
|
|
27
|
+
normalizeArgv,
|
|
28
|
+
positionalArgs,
|
|
29
|
+
requirePositionalCount,
|
|
30
|
+
failUnknownSubcommand,
|
|
31
|
+
hasHelp,
|
|
32
|
+
} from "./argparse.mjs";
|
|
33
|
+
|
|
34
|
+
const HELP = `run402 subscriptions — which events go where
|
|
35
|
+
|
|
36
|
+
Usage:
|
|
37
|
+
run402 subscriptions add --contact <binding_id> [--project <id>] [--source app|platform] [--type a,b] [--class a,b]
|
|
38
|
+
run402 subscriptions list
|
|
39
|
+
run402 subscriptions rm <subscription_id>
|
|
40
|
+
|
|
41
|
+
Notes:
|
|
42
|
+
- Absent dimensions are wildcards; an explicit empty list matches NOTHING.
|
|
43
|
+
- A subscription naming a platform-emitted event type cannot match today —
|
|
44
|
+
the delivery pipeline carries app and agent-messaging sources only. The
|
|
45
|
+
gateway says so when you create one.
|
|
46
|
+
- Where a human is reachable is \`run402 contacts\`; what actually landed is
|
|
47
|
+
\`run402 deliveries\`.
|
|
48
|
+
`;
|
|
49
|
+
|
|
50
|
+
// ---------------------------------------------------------------------------
|
|
51
|
+
// Telegram routing rules — notification-channel-routing-telegram.
|
|
52
|
+
// ---------------------------------------------------------------------------
|
|
53
|
+
|
|
54
|
+
function splitCsv(value) {
|
|
55
|
+
return value
|
|
56
|
+
.split(",")
|
|
57
|
+
.map((s) => s.trim())
|
|
58
|
+
.filter((s) => s.length > 0);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
async function rulesAdd(args) {
|
|
62
|
+
const a = normalizeArgv(args);
|
|
63
|
+
const valueFlags = ["--binding", "--project", "--source", "--type", "--class"];
|
|
64
|
+
assertKnownFlags(a, [...valueFlags, "--help", "-h"], valueFlags);
|
|
65
|
+
const positionals = positionalArgs(a, valueFlags);
|
|
66
|
+
if (positionals.length > 0) {
|
|
67
|
+
fail({ code: "BAD_USAGE", message: `Unexpected argument for notifications rules add: ${positionals[0]}` });
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const bindingId = flagValue(a, "--binding");
|
|
71
|
+
if (!bindingId) {
|
|
72
|
+
fail({
|
|
73
|
+
code: "BAD_USAGE",
|
|
74
|
+
message:
|
|
75
|
+
"Usage: run402 notifications rules add --binding <binding_id> [--project <id>] [--source app|platform] [--type a,b] [--class a,b]",
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
const projectId = flagValue(a, "--project");
|
|
79
|
+
const source = flagValue(a, "--source");
|
|
80
|
+
if (source !== null) assertAllowedValue(source, ["app", "platform"], "--source");
|
|
81
|
+
const typeRaw = flagValue(a, "--type");
|
|
82
|
+
const classRaw = flagValue(a, "--class");
|
|
83
|
+
|
|
84
|
+
const input = { telegramBindingId: bindingId };
|
|
85
|
+
if (projectId) input.projectId = projectId;
|
|
86
|
+
if (source) input.source = source;
|
|
87
|
+
if (typeRaw !== null) input.eventTypes = splitCsv(typeRaw);
|
|
88
|
+
if (classRaw !== null) input.classes = splitCsv(classRaw);
|
|
89
|
+
|
|
90
|
+
allowanceAuthHeaders("/agent/v1/notifications/rules");
|
|
91
|
+
try {
|
|
92
|
+
console.log(JSON.stringify(await getSdk().admin.rules.create(input), null, 2));
|
|
93
|
+
} catch (err) {
|
|
94
|
+
reportSdkError(err);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
async function rulesList() {
|
|
99
|
+
allowanceAuthHeaders("/agent/v1/notifications/rules");
|
|
100
|
+
try {
|
|
101
|
+
console.log(JSON.stringify(await getSdk().admin.rules.list(), null, 2));
|
|
102
|
+
} catch (err) {
|
|
103
|
+
reportSdkError(err);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
async function rulesRm(args) {
|
|
108
|
+
const a = normalizeArgv(args);
|
|
109
|
+
assertKnownFlags(a, ["--help", "-h"]);
|
|
110
|
+
const [ruleId] = requirePositionalCount(a, [], {
|
|
111
|
+
min: 1,
|
|
112
|
+
max: 1,
|
|
113
|
+
command: "run402 notifications rules rm <rule_id>",
|
|
114
|
+
missing: "Missing <rule_id>.",
|
|
115
|
+
});
|
|
116
|
+
allowanceAuthHeaders("/agent/v1/notifications/rules");
|
|
117
|
+
try {
|
|
118
|
+
console.log(JSON.stringify(await getSdk().admin.rules.delete(ruleId), null, 2));
|
|
119
|
+
} catch (err) {
|
|
120
|
+
reportSdkError(err);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
export async function run(sub, args) {
|
|
126
|
+
const rest = Array.isArray(args) ? args : [];
|
|
127
|
+
// `--help` arrives as the SUBCOMMAND (`run402 subscriptions --help`), not
|
|
128
|
+
// only inside args — check both, the way every other family does.
|
|
129
|
+
if (!sub || hasHelp([sub, ...rest])) {
|
|
130
|
+
console.log(HELP);
|
|
131
|
+
process.exit(0);
|
|
132
|
+
}
|
|
133
|
+
switch (sub) {
|
|
134
|
+
case "add":
|
|
135
|
+
await rulesAdd(rest);
|
|
136
|
+
return;
|
|
137
|
+
case "list":
|
|
138
|
+
await rulesList();
|
|
139
|
+
return;
|
|
140
|
+
case "rm":
|
|
141
|
+
await rulesRm(rest);
|
|
142
|
+
return;
|
|
143
|
+
default:
|
|
144
|
+
failUnknownSubcommand("subscriptions", sub);
|
|
145
|
+
}
|
|
146
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "run402",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.35.0",
|
|
4
4
|
"description": "CLI for Run402 — full-stack backend infrastructure for AI agents: Postgres, auth, storage, serverless functions and atomic deploys. Paid with x402/MPP. Includes $0.03 image generation.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|