@desplega.ai/agent-swarm 2.4.2 → 2.4.4
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/{acp-adapter-dv7hmx4r.js → acp-adapter-thq04adh.js} +4 -5
- package/dist/{actions-51nc1gny.js → actions-j6ywh6x5.js} +18 -18
- package/dist/{amp-adapter-abp5tdx8.js → amp-adapter-k8b5xmj8.js} +3 -3
- package/dist/{app-9h14qvr6.js → app-rb7vc02s.js} +3 -3
- package/dist/{assistant-wv1gz3mt.js → assistant-ftta1zjf.js} +20 -20
- package/dist/{boot-reembed-6yn53ms9.js → boot-reembed-srp6v6af.js} +1 -1
- package/dist/{boot-reembed-7fcka4z5.js → boot-reembed-xns7h5h9.js} +1 -1
- package/dist/{boot-scrub-sweep-pm1580ax.js → boot-scrub-sweep-3qqrh2mz.js} +3 -3
- package/dist/{boot-seeds-g5hfc1x8.js → boot-seeds-9ks8hce7.js} +4 -4
- package/dist/{claude-adapter-gf3kxhf0.js → claude-adapter-k5ksyres.js} +4 -4
- package/dist/{claude-managed-setup-h00hsgtz.js → claude-managed-setup-n5a5eqks.js} +1 -1
- package/dist/{claude-sdk-session-s2k1qd8y.js → claude-sdk-session-2j3j4kwn.js} +9822 -9749
- package/dist/{cli-pkht5hap.js → cli-1d70crsy.js} +2 -2
- package/dist/{cli-r99kc9yq.js → cli-1ephgwnq.js} +3 -3
- package/dist/{cli-7225gwj7.js → cli-1m17dc9d.js} +1 -1
- package/dist/{cli-bcj753sq.js → cli-2v045xyf.js} +3 -3
- package/dist/{cli-h38rjv87.js → cli-2y91wnbh.js} +12 -7
- package/dist/{cli-sv5gb0yb.js → cli-2zqpkvtt.js} +1 -1
- package/dist/{cli-xbzvet96.js → cli-36ckw0wx.js} +5 -4
- package/dist/{cli-8sxqsbbq.js → cli-37yb7307.js} +1 -1
- package/dist/{cli-hyfw2j1e.js → cli-3cgngyd8.js} +11 -11
- package/dist/{cli-a4gvwttf.js → cli-44159k28.js} +2 -2
- package/dist/{cli-7awf1fp8.js → cli-4dg55wsk.js} +3 -3
- package/dist/{cli-mhywgrrz.js → cli-4sydckyj.js} +1 -1
- package/dist/{cli-y2x52gs2.js → cli-51y09c6p.js} +20 -17
- package/dist/{cli-ahtpy9kf.js → cli-55qmbp6z.js} +10 -5
- package/dist/{cli-pw7v69vp.js → cli-625tb7aq.js} +1 -1
- package/dist/{cli-x5mq1fyq.js → cli-74c1wpm0.js} +3 -3
- package/dist/{cli-b1dfr1m4.js → cli-7a6p4e65.js} +1 -1
- package/dist/{cli-hqhzg1qq.js → cli-82d3nkc3.js} +1 -1
- package/dist/{cli-nmqdc2t3.js → cli-9fhkkpj5.js} +78 -12
- package/dist/{cli-h93c9vb3.js → cli-amyhm3gj.js} +1 -1
- package/dist/{cli-0qvtffe9.js → cli-b8k7epj1.js} +6 -6
- package/dist/{cli-1pa3rz69.js → cli-ba8ne1es.js} +6 -1
- package/dist/{cli-g0hgtz4p.js → cli-bnz0r3kc.js} +3 -3
- package/dist/{cli-0hyhdkdk.js → cli-cebvbc9t.js} +4 -1
- package/dist/{cli-efaqv1c7.js → cli-cynvc9fj.js} +35 -7
- package/dist/{cli-8zwe9mpk.js → cli-dqb4n629.js} +10 -10
- package/dist/{cli-7a91w22y.js → cli-e8xyjvfc.js} +1 -1
- package/dist/{cli-s6vr7r2d.js → cli-esxerzg7.js} +1 -1
- package/dist/{cli-w9g4sz81.js → cli-gf2850q7.js} +1 -1
- package/dist/{cli-10hhg0km.js → cli-gqvh8d8a.js} +7 -7
- package/dist/{cli-t30yj95q.js → cli-hj3debgw.js} +1 -1
- package/dist/{cli-fpmsqq59.js → cli-nc35pxb7.js} +3 -3
- package/dist/{cli-d3qqdy4c.js → cli-p20r8w42.js} +16 -14
- package/dist/{cli-shvfedvm.js → cli-pccfmtb5.js} +5 -5
- package/dist/{cli-02qm7src.js → cli-q6r7t299.js} +1037 -299
- package/dist/{cli-2wag8973.js → cli-qeaq3j6t.js} +1 -1
- package/dist/{cli-nn47d7e8.js → cli-qkhc5aqy.js} +15 -15
- package/dist/{cli-faypxz7q.js → cli-t7cyef5g.js} +4 -4
- package/dist/{cli-z4wd2ftv.js → cli-te6b5wvg.js} +149 -184
- package/dist/{cli-5rk36sjf.js → cli-v3yr2gbg.js} +119 -44
- package/dist/{cli-239yjk27.js → cli-vdm20wej.js} +5 -5
- package/dist/{cli-zfg9enh9.js → cli-vfha21c9.js} +6 -1
- package/dist/{cli-rdyw3mct.js → cli-vq97g1jq.js} +6 -5
- package/dist/{cli-n85dqg6d.js → cli-w6nadkh4.js} +4 -4
- package/dist/{cli-99jez72r.js → cli-w9etnnxk.js} +6 -1
- package/dist/{cli-saw9a6f6.js → cli-xc27fwzg.js} +2 -2
- package/dist/{cli-ftyypbg5.js → cli-xj0re5tm.js} +1 -1
- package/dist/{cli-fyzjmseb.js → cli-zrk6jxv8.js} +1 -1
- package/dist/{cli-y8n5k515.js → cli-zrwpctp4.js} +28 -28
- package/dist/cli.js +44 -19
- package/dist/{codex-adapter-ttygw382.js → codex-adapter-968xwfy7.js} +2 -2
- package/dist/{codex-hook-x7nejyrr.js → codex-hook-e2he7aca.js} +2 -2
- package/dist/{codex-session-runner-60b58vv3.js → codex-session-runner-ht4z99fa.js} +2 -2
- package/dist/{commands-edmdwa4x.js → commands-pcymaeg9.js} +3 -3
- package/dist/{controller-m263fg43.js → controller-fpjyk46r.js} +3 -3
- package/dist/{controllers-connect-5fym8sw1.js → controllers-connect-mwzx1fh6.js} +19 -19
- package/dist/{cursor-adapter-cz6nm6mj.js → cursor-adapter-cp4s2e2f.js} +2 -2
- package/dist/{db-2y0mgstc.js → db-sgd12bt9.js} +3 -3
- package/dist/{db-nn0hcmx5.js → db-xsjg9jqq.js} +2 -2
- package/dist/{dispatcher-0a9wwjcx.js → dispatcher-x0jfw2c9.js} +17 -17
- package/dist/{dsh-adapter-3n3net33.js → dsh-adapter-jrq7ma7h.js} +2 -2
- package/dist/{e2b-thdcxtjd.js → e2b-16d6ch39.js} +1 -1
- package/dist/{e2b-7am6tmq6.js → e2b-zn0b4w5w.js} +1 -1
- package/dist/{external-channel-zhvt95n3.js → external-channel-8njj4h3b.js} +2 -2
- package/dist/{grok-adapter-qnr1hp2y.js → grok-adapter-kkr97v2f.js} +5 -6
- package/dist/handlers-0pvee9nw.js +39 -0
- package/dist/{heartbeat-gz97r7ac.js → heartbeat-wd03zhn0.js} +20 -20
- package/dist/{hook-1mmdgjqs.js → hook-f0vghj42.js} +10 -5
- package/dist/{hook-x8rthca4.js → hook-xzj2ts2p.js} +2 -2
- package/dist/{http-r8f85xr9.js → http-4hwxv62p.js} +261 -123
- package/dist/{index-va3y63es.js → index-6srwvd5b.js} +1 -2
- package/dist/{index-y7rbcrc1.js → index-97q4xn03.js} +20 -11
- package/dist/{index-s98037v0.js → index-cbxkmfc5.js} +1 -2
- package/dist/{index-vzvfqzfj.js → index-gdh8jrdm.js} +17 -17
- package/dist/{index-aex0eba9.js → index-hg0x2cdv.js} +17 -17
- package/dist/index-thm0y6a8.js +41 -0
- package/dist/{index-smxyk04s.js → index-ww2vznkp.js} +1 -1
- package/dist/{keepalive-64c0f34c.js → keepalive-hrh7xnr9.js} +3 -3
- package/dist/{lead-b1da0f97.js → lead-ee8vazz2.js} +30 -31
- package/dist/{maintenance-mnxpar12.js → maintenance-e8wnwnqx.js} +1 -1
- package/dist/{oauth-refresh-sweep-36hs2v4h.js → oauth-refresh-sweep-zm0yj4sj.js} +2 -2
- package/dist/{onboard-xes8de61.js → onboard-dtwcq603.js} +3 -3
- package/dist/{opencode-adapter-3s7ax02e.js → opencode-adapter-x4tqzhkh.js} +3 -3
- package/dist/{otel-impl-fzc57kcq.js → otel-impl-w3fbhpn0.js} +1 -1
- package/dist/{pi-mono-adapter-ytp7gz8b.js → pi-mono-adapter-mcfkn9vf.js} +3 -3
- package/dist/{pricing-refresh-1nek2w7b.js → pricing-refresh-j38dehfs.js} +3 -3
- package/dist/{rbac-roles-ttyfaep2.js → rbac-roles-ae8yttq4.js} +3 -3
- package/dist/{rbac-roles-sqefb5hw.js → rbac-roles-ejxx9b35.js} +2 -2
- package/dist/{render-v2-vb527jwn.js → render-v2-n16n0phe.js} +3 -3
- package/dist/{resume-jcdzg1bn.js → resume-z0fgjc38.js} +5 -5
- package/dist/{session-access-zsp4wsp0.js → session-access-cv3mq6mc.js} +6 -4
- package/dist/{setup-1nb2zqd3.js → setup-mafhj3yt.js} +1 -1
- package/dist/{work-objects-61w08fwr.js → work-objects-8b86mgjp.js} +21 -21
- package/dist/{worker-c1e68hpa.js → worker-16s75hm5.js} +30 -31
- package/dist/worker-token-xf11yyds.js +136 -0
- package/openapi.json +295 -12
- package/package.json +5 -5
- package/src/apps/action-runner.ts +4 -0
- package/src/apps/catalog.generated.json +3 -0
- package/src/apps/page-validator.ts +8 -2
- package/src/be/db.ts +7 -4
- package/src/be/migrations/231_slack_tasks_last_updated_index.sql +5 -0
- package/src/be/migrations/232_agent_session_tokens.sql +41 -0
- package/src/be/seed-scripts/catalog/heartbeat-jev-gate.ts +10 -1
- package/src/be/swarm-config-guard.ts +16 -0
- package/src/be/users.ts +169 -12
- package/src/cli.tsx +24 -0
- package/src/commands/worker-token.ts +164 -0
- package/src/github/handlers.ts +6 -5
- package/src/hooks/hook.ts +2 -1
- package/src/http/apps.ts +43 -5
- package/src/http/codex-oauth-keep-warm.ts +27 -9
- package/src/http/config.ts +5 -3
- package/src/http/core.ts +2 -0
- package/src/http/session-access.ts +51 -2
- package/src/http/sessions.ts +249 -10
- package/src/http/tasks.ts +4 -32
- package/src/providers/acp-adapter.ts +33 -13
- package/src/providers/acp-swarm-events.ts +1 -1
- package/src/providers/amp-adapter.ts +1 -1
- package/src/providers/codex-adapter.ts +4 -4
- package/src/providers/codex-oauth/storage.ts +1 -1
- package/src/providers/opencode-adapter.ts +2 -2
- package/src/providers/pi-mono-extension.ts +2 -1
- package/src/rbac/legacy-policy.ts +3 -1
- package/src/rbac/permissions.ts +4 -0
- package/src/tests/acp-adapter.test.ts +10 -23
- package/src/tests/acp-fake-agent.ts +36 -0
- package/src/tests/acp-swarm-events.test.ts +1 -1
- package/src/tests/agent-session-tokens.test.ts +452 -0
- package/src/tests/apps-action-parent-task.test.ts +295 -0
- package/src/tests/claude-stop-hook.test.ts +47 -0
- package/src/tests/codex-adapter.test.ts +42 -0
- package/src/tests/codex-oauth-keep-warm.test.ts +85 -1
- package/src/tests/config-session-auth.test.ts +14 -0
- package/src/tests/docs-index-footprint.test.js +2 -2
- package/src/tests/env-flag.test.ts +15 -1
- package/src/tests/github-handlers-cancel-config.test.ts +29 -8
- package/src/tests/github-handlers-inline-comments.test.ts +9 -2
- package/src/tests/grok-adapter.test.ts +3 -3
- package/src/tests/heartbeat-jev-gate.test.ts +23 -0
- package/src/tests/migration-232-agent-session-tokens.test.ts +67 -0
- package/src/tests/rbac-engine.test.ts +1 -0
- package/src/tests/runtime-child-token-cleanup.test.ts +3 -3
- package/src/tests/script-connections.test.ts +4 -0
- package/src/tests/session-route-posture.test.ts +2 -0
- package/src/tests/skill-script-refs.test.ts +63 -0
- package/src/tests/slack-render-v2-query-plans.test.ts +147 -0
- package/src/tests/worker-token-cli.test.ts +76 -0
- package/src/tests/workflow-executors.test.ts +4 -2
- package/src/tests/workflow-system-one-extraction.test.ts +805 -0
- package/src/types.ts +2 -1
- package/src/utils/env-flag.ts +9 -0
- package/src/utils/request-auth-context.ts +2 -1
- package/src/workflows/definition.ts +7 -1
- package/src/workflows/engine.ts +18 -12
- package/src/workflows/executors/index.ts +1 -0
- package/src/workflows/executors/registry.ts +2 -0
- package/src/workflows/executors/system-one-decision.ts +56 -255
- package/src/workflows/executors/system-one-extract-wire.ts +57 -0
- package/src/workflows/executors/system-one-extraction.ts +830 -0
- package/src/workflows/executors/system-one-providers.ts +277 -110
- package/src/workflows/executors/system-one-transport.ts +264 -0
- package/templates/official/lead/HEARTBEAT.md +1 -1
- package/templates/skills/apps/SKILL.md +4 -1
- package/templates/skills/apps/content.md +4 -1
- package/templates/skills/code-quality/content.md +9 -14
- package/templates/skills/heartbeat-runbook/content.md +3 -3
- package/dist/cli-v1sjhn52.js +0 -7
- package/dist/handlers-dkcarkd0.js +0 -39
- package/dist/index-5jecgp3n.js +0 -41
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
import { getOpenRouterAttributionHeaders } from "../../utils/openrouter-base-url";
|
|
2
|
+
import {
|
|
3
|
+
type SystemOneCapability,
|
|
4
|
+
type SystemOneHostId,
|
|
5
|
+
systemOneKeyRejectedMessage,
|
|
6
|
+
} from "./system-one-providers";
|
|
7
|
+
import { cloudflareErrorCode, isRecord } from "./system-one-wire";
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* One POST to a System One host, shared by every capability (`system-one-decision`,
|
|
11
|
+
* `system-one-extraction`): one time budget, transient retries with backoff,
|
|
12
|
+
* `Retry-After`, redirect refusal, a response size cap, and the same error
|
|
13
|
+
* sentences. The credential goes only into the `authorization` header.
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
export const SYSTEM_ONE_DEFAULT_TIMEOUT_MS = 30_000;
|
|
17
|
+
export const SYSTEM_ONE_MIN_TIMEOUT_MS = 1_000;
|
|
18
|
+
export const SYSTEM_ONE_MAX_TIMEOUT_MS = 300_000;
|
|
19
|
+
export const SYSTEM_ONE_DEFAULT_MAX_RETRIES = 2;
|
|
20
|
+
export const SYSTEM_ONE_MAX_RETRIES_LIMIT = 3;
|
|
21
|
+
|
|
22
|
+
/** Room left before the engine watchdog fires so the executor can report its own failure. */
|
|
23
|
+
const DEADLINE_MARGIN_MS = 250;
|
|
24
|
+
const BACKOFF_BASE_MS = 500;
|
|
25
|
+
const BACKOFF_CAP_MS = 8_000;
|
|
26
|
+
const MAX_RESPONSE_CHARS = 1_048_576;
|
|
27
|
+
const MAX_ERROR_BODY_CHARS = 65_536;
|
|
28
|
+
|
|
29
|
+
export interface SystemOneTransportOptions {
|
|
30
|
+
/** Transport. Tests inject a fake; production uses the global `fetch`. */
|
|
31
|
+
fetch?: typeof fetch;
|
|
32
|
+
sleep?: (ms: number, signal: AbortSignal) => Promise<void>;
|
|
33
|
+
now?: () => number;
|
|
34
|
+
random?: () => number;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export interface SystemOneRequest {
|
|
38
|
+
providerId: SystemOneHostId;
|
|
39
|
+
capability: SystemOneCapability;
|
|
40
|
+
endpoint: string;
|
|
41
|
+
apiKey: string;
|
|
42
|
+
/** The secret name the key was read under, named when the host rejects it. */
|
|
43
|
+
keyName: string;
|
|
44
|
+
body: string;
|
|
45
|
+
timeoutMs: number;
|
|
46
|
+
maxRetries: number;
|
|
47
|
+
env: NodeJS.ProcessEnv;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export type SystemOneSendResult =
|
|
51
|
+
| { ok: true; text: string; requestId?: string }
|
|
52
|
+
| { ok: false; error: string };
|
|
53
|
+
|
|
54
|
+
type Attempt =
|
|
55
|
+
| { kind: "ok"; text: string; requestId?: string }
|
|
56
|
+
| { kind: "timeout" }
|
|
57
|
+
| { kind: "fail"; message: string; retryable: boolean; retryAfterMs?: number };
|
|
58
|
+
|
|
59
|
+
const REQUEST_ID_RE = /^[A-Za-z0-9._:-]{1,128}$/;
|
|
60
|
+
const ERROR_CODE_RE = /^[A-Za-z0-9._:-]{1,64}$/;
|
|
61
|
+
|
|
62
|
+
function readRequestId(headers: Headers): string | undefined {
|
|
63
|
+
// Cloudflare marks every response with `cf-ray` and sends no request id.
|
|
64
|
+
const value = headers.get("x-request-id") ?? headers.get("request-id") ?? headers.get("cf-ray");
|
|
65
|
+
return value && REQUEST_ID_RE.test(value) ? value : undefined;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/** Retry-After as delta-seconds or an HTTP date, in ms. Undefined when absent or unparseable. */
|
|
69
|
+
function parseRetryAfter(value: string | null, now: number): number | undefined {
|
|
70
|
+
if (!value) return undefined;
|
|
71
|
+
const trimmed = value.trim();
|
|
72
|
+
if (/^\d+(\.\d+)?$/.test(trimmed)) return Math.round(Number(trimmed) * 1000);
|
|
73
|
+
const at = Date.parse(trimmed);
|
|
74
|
+
return Number.isNaN(at) ? undefined : Math.max(0, at - now);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/** Only a short identifier from the provider's error envelope. Never its message or echoed request. */
|
|
78
|
+
function readErrorCode(text: string): string | undefined {
|
|
79
|
+
if (text.length === 0 || text.length > MAX_ERROR_BODY_CHARS) return undefined;
|
|
80
|
+
let parsed: unknown;
|
|
81
|
+
try {
|
|
82
|
+
parsed = JSON.parse(text);
|
|
83
|
+
} catch {
|
|
84
|
+
return undefined;
|
|
85
|
+
}
|
|
86
|
+
if (!isRecord(parsed)) return undefined;
|
|
87
|
+
const nested = isRecord(parsed.error) ? parsed.error : undefined;
|
|
88
|
+
const detail = isRecord(parsed.detail) ? parsed.detail : undefined;
|
|
89
|
+
for (const candidate of [
|
|
90
|
+
nested?.code,
|
|
91
|
+
nested?.type,
|
|
92
|
+
detail?.error_type,
|
|
93
|
+
parsed.code,
|
|
94
|
+
parsed.type,
|
|
95
|
+
]) {
|
|
96
|
+
if (typeof candidate === "string" && ERROR_CODE_RE.test(candidate)) return candidate;
|
|
97
|
+
}
|
|
98
|
+
// Cloudflare's envelope: `{ success: false, errors: [{ code: 10000, message }] }`.
|
|
99
|
+
return cloudflareErrorCode(parsed);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
function defaultSleep(ms: number, signal: AbortSignal): Promise<void> {
|
|
103
|
+
return new Promise((resolve) => {
|
|
104
|
+
if (signal.aborted) return resolve();
|
|
105
|
+
const timer = setTimeout(done, ms);
|
|
106
|
+
function done() {
|
|
107
|
+
clearTimeout(timer);
|
|
108
|
+
signal.removeEventListener("abort", done);
|
|
109
|
+
resolve();
|
|
110
|
+
}
|
|
111
|
+
signal.addEventListener("abort", done, { once: true });
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* POST once, retrying only transient failures inside one time budget.
|
|
117
|
+
* Retries: connection errors, HTTP 408 / 429 / 5xx (incl. 529). Never: 401, 422,
|
|
118
|
+
* other 4xx, redirects, or a bad success body (the caller validates that).
|
|
119
|
+
*/
|
|
120
|
+
export async function sendSystemOneRequest(
|
|
121
|
+
request: SystemOneRequest,
|
|
122
|
+
options: SystemOneTransportOptions = {},
|
|
123
|
+
): Promise<SystemOneSendResult> {
|
|
124
|
+
const { timeoutMs, maxRetries } = request;
|
|
125
|
+
const doFetch = options.fetch ?? fetch;
|
|
126
|
+
const sleep = options.sleep ?? defaultSleep;
|
|
127
|
+
const now = options.now ?? Date.now;
|
|
128
|
+
const random = options.random ?? Math.random;
|
|
129
|
+
|
|
130
|
+
const deadlineAt = now() + timeoutMs - DEADLINE_MARGIN_MS;
|
|
131
|
+
const controller = new AbortController();
|
|
132
|
+
const timer = setTimeout(() => controller.abort(), Math.max(0, deadlineAt - now()));
|
|
133
|
+
const timedOut = () =>
|
|
134
|
+
({
|
|
135
|
+
ok: false,
|
|
136
|
+
error: `SystemOne request exceeded its ${timeoutMs}ms time budget`,
|
|
137
|
+
}) as const;
|
|
138
|
+
|
|
139
|
+
try {
|
|
140
|
+
for (let attempt = 0; ; attempt++) {
|
|
141
|
+
const result = await attemptOnce(doFetch, request, controller.signal, now);
|
|
142
|
+
if (result.kind === "ok") {
|
|
143
|
+
return { ok: true, text: result.text, requestId: result.requestId };
|
|
144
|
+
}
|
|
145
|
+
if (result.kind === "timeout" || controller.signal.aborted) return timedOut();
|
|
146
|
+
|
|
147
|
+
const attempts = attempt + 1;
|
|
148
|
+
const suffix = attempts > 1 ? ` after ${attempts} attempts` : "";
|
|
149
|
+
if (!result.retryable || attempt >= maxRetries) {
|
|
150
|
+
return { ok: false, error: `${result.message}${suffix}` };
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
const backoff = Math.min(BACKOFF_CAP_MS, BACKOFF_BASE_MS * 2 ** attempt);
|
|
154
|
+
const delay = result.retryAfterMs ?? Math.round(backoff * (0.5 + random() * 0.5));
|
|
155
|
+
if (delay >= deadlineAt - now()) {
|
|
156
|
+
return {
|
|
157
|
+
ok: false,
|
|
158
|
+
error: `${result.message}${suffix}; the ${delay}ms retry delay does not fit the ${timeoutMs}ms time budget`,
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
await sleep(delay, controller.signal);
|
|
162
|
+
if (controller.signal.aborted) return timedOut();
|
|
163
|
+
}
|
|
164
|
+
} finally {
|
|
165
|
+
clearTimeout(timer);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
async function attemptOnce(
|
|
170
|
+
doFetch: typeof fetch,
|
|
171
|
+
request: SystemOneRequest,
|
|
172
|
+
signal: AbortSignal,
|
|
173
|
+
now: () => number,
|
|
174
|
+
): Promise<Attempt> {
|
|
175
|
+
const { endpoint, apiKey, body } = request;
|
|
176
|
+
let res: Response;
|
|
177
|
+
try {
|
|
178
|
+
res = await doFetch(endpoint, {
|
|
179
|
+
method: "POST",
|
|
180
|
+
headers: {
|
|
181
|
+
...getOpenRouterAttributionHeaders(endpoint, request.env),
|
|
182
|
+
"content-type": "application/json",
|
|
183
|
+
accept: "application/json",
|
|
184
|
+
authorization: `Bearer ${apiKey}`,
|
|
185
|
+
},
|
|
186
|
+
body,
|
|
187
|
+
redirect: "manual",
|
|
188
|
+
signal,
|
|
189
|
+
});
|
|
190
|
+
} catch (err) {
|
|
191
|
+
if (signal.aborted) return { kind: "timeout" };
|
|
192
|
+
const code = (err as { code?: unknown })?.code;
|
|
193
|
+
const detail = typeof code === "string" && /^[A-Z0-9_]{3,40}$/.test(code) ? ` (${code})` : "";
|
|
194
|
+
return {
|
|
195
|
+
kind: "fail",
|
|
196
|
+
message: `SystemOne request failed: network error${detail}`,
|
|
197
|
+
retryable: true,
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
const requestId = readRequestId(res.headers);
|
|
202
|
+
const withId = (message: string) => (requestId ? `${message} [request ${requestId}]` : message);
|
|
203
|
+
|
|
204
|
+
if (res.status >= 200 && res.status < 300) {
|
|
205
|
+
let text: string;
|
|
206
|
+
try {
|
|
207
|
+
text = await res.text();
|
|
208
|
+
} catch {
|
|
209
|
+
if (signal.aborted) return { kind: "timeout" };
|
|
210
|
+
return {
|
|
211
|
+
kind: "fail",
|
|
212
|
+
message: withId("SystemOne response body could not be read"),
|
|
213
|
+
retryable: true,
|
|
214
|
+
};
|
|
215
|
+
}
|
|
216
|
+
if (text.length > MAX_RESPONSE_CHARS) {
|
|
217
|
+
return {
|
|
218
|
+
kind: "fail",
|
|
219
|
+
message: withId("SystemOne response exceeded the size limit"),
|
|
220
|
+
retryable: false,
|
|
221
|
+
};
|
|
222
|
+
}
|
|
223
|
+
return { kind: "ok", text, requestId };
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
if (res.status >= 300 && res.status < 400) {
|
|
227
|
+
return {
|
|
228
|
+
kind: "fail",
|
|
229
|
+
message: withId(
|
|
230
|
+
`SystemOne request was redirected (HTTP ${res.status}); redirects are refused`,
|
|
231
|
+
),
|
|
232
|
+
retryable: false,
|
|
233
|
+
};
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
let errorText = "";
|
|
237
|
+
try {
|
|
238
|
+
errorText = await res.text();
|
|
239
|
+
} catch {
|
|
240
|
+
if (signal.aborted) return { kind: "timeout" };
|
|
241
|
+
}
|
|
242
|
+
const code = readErrorCode(errorText);
|
|
243
|
+
// The host answered but does not accept the key: name it, never retry.
|
|
244
|
+
if (res.status === 401 || res.status === 403) {
|
|
245
|
+
return {
|
|
246
|
+
kind: "fail",
|
|
247
|
+
message: withId(
|
|
248
|
+
systemOneKeyRejectedMessage(request.providerId, res.status, code, {
|
|
249
|
+
keyName: request.keyName,
|
|
250
|
+
capability: request.capability,
|
|
251
|
+
}),
|
|
252
|
+
),
|
|
253
|
+
retryable: false,
|
|
254
|
+
};
|
|
255
|
+
}
|
|
256
|
+
const detail = code ? ` (${code})` : "";
|
|
257
|
+
const retryable = res.status === 408 || res.status === 429 || res.status >= 500;
|
|
258
|
+
return {
|
|
259
|
+
kind: "fail",
|
|
260
|
+
message: withId(`SystemOne API returned HTTP ${res.status}${detail}`),
|
|
261
|
+
retryable,
|
|
262
|
+
retryAfterMs: retryable ? parseRetryAfter(res.headers.get("retry-after"), now()) : undefined,
|
|
263
|
+
};
|
|
264
|
+
}
|
|
@@ -11,5 +11,5 @@
|
|
|
11
11
|
## Tracked Items
|
|
12
12
|
|
|
13
13
|
- Live items only: active blockers and watch items. Cap 10, 20 max during a surge; prune before you add.
|
|
14
|
-
- Each item states its lift trigger and a calendar date (e.g. `lift when X; check
|
|
14
|
+
- Each item states its lift trigger and a calendar date as a bare `MM-DD` (e.g. `lift when X; check 08-22`) or `DELETE MM-DD`. A full `YYYY-MM-DD` stamp does not arm the gate.
|
|
15
15
|
- An item closes: move its durable facts to memory, then delete the line. Never strike it through.
|
|
@@ -645,6 +645,8 @@ Only inside action-chain `params` (`on.<event>`, `Table.rowActions[].actions`, o
|
|
|
645
645
|
| `{ "$form": "title" }` | One current Form value. |
|
|
646
646
|
| `{ "$form": "" }` | All current Form values. |
|
|
647
647
|
| `{ "$state": "/queries/allIdeas/data" }` | Current value at a valid app state path, including action state such as `/actions/refreshIssues/status`. |
|
|
648
|
+
| `{ "$chain": "leafTaskId" }` | One chain-scope value, published by a component that runs a task chain; it carries `leafTaskId` and `newTaskId`. Where no chain scope is published, the sentinel is left in place and the action fails instead of silently dropping the parent. |
|
|
649
|
+
| `{ "$chain": "" }` | The whole chain scope. |
|
|
648
650
|
|
|
649
651
|
Each sentinel object must contain exactly the single key shown.
|
|
650
652
|
|
|
@@ -652,7 +654,7 @@ An action-chain step is `{ "action": "<type>", "params": {...} }`. Available act
|
|
|
652
654
|
|
|
653
655
|
- `app.mutate`: `{ model, op, rowId?, values?, formId? }`, where `op` is `"create"`, `"update"`, or `"delete"`. `update`/`delete` require `rowId` (usually `{ "$row": "id" }`, or `{ "$state": "/route/params/<param>" }` in a Drawer footer); literal `values` keys must be model columns. Successful mutation refetches all queries on that model.
|
|
654
656
|
- `app.refresh`: `{ query? }`; omit `query` to refetch all, or name a declared query.
|
|
655
|
-
- `app.action`: `{ name, input? }`; `name` must be declared in definition `actions`. For a task-kind row action, pass whole-row context with `input: { issue: { "$row": "" } }`.
|
|
657
|
+
- `app.action`: `{ name, input?, parentTaskId? }`; `name` must be declared in definition `actions`. For a task-kind row action, pass whole-row context with `input: { issue: { "$row": "" } }`. `parentTaskId` chains the created task under an existing one for task-kind actions (typically `{ "$chain": "leafTaskId" }`; a literal or `$state` task id also works); a script or sync action rejects it with 400.
|
|
656
658
|
- `app.navigate`: `{ page, params? }`; `page` must be declared, supplied keys must be params of the target page, and every required target param must be supplied. `params` replace the current route params wholesale and may contain action sentinels. Navigation pushes history, so browser Back returns to the previous page/params; only `mode` is preserved automatically.
|
|
657
659
|
- `ui.toast`: `{ message, description?, tone?, undo? }`, where `tone` is `"success"`, `"error"`, `"info"` (default), or `"warning"`. `undo: { label?, actions }` adds an Undo button (default label `Undo`) that runs `actions` as a chain; its steps are validated like any chain. Put it after the step it confirms, e.g. a row delete followed by `{ "action": "ui.toast", "params": { "message": "Order deleted", "undo": { "actions": [{ "action": "app.mutate", "params": { "model": "order", "op": "create", "values": { "title": { "$row": "title" } } } }] } } }`. Undo params resolve `$state` when Undo is pressed; `$row` / `$form` resolve when the toast is shown.
|
|
658
660
|
- `swarm.sdk`: `{ sdk, args? }`; invokes a catalog-supported Swarm browser SDK method with the viewer's bearer.
|
|
@@ -790,6 +792,7 @@ The tool returns `{ appId, url: "/apps/<id>" }`. Open that URL to verify the liv
|
|
|
790
792
|
- Logged-in browser: a fresh dashboard has no connection and redirects to /setup. Seed the localStorage key `agent-swarm-connections` with `{connections:[{id,name,apiUrl,apiKey}],activeId}`. Build the value from an env var and pipe it to `agent-browser eval --stdin`, so the key never reaches a command line. Reload, then pick a user in the "Who are you?" dialog.
|
|
791
793
|
- Apps scroll inside an inner canvas, so a full-page screenshot captures only the viewport. Scroll the canvas or raise the viewport height. For mobile, set a 375px-wide viewport before the screenshot.
|
|
792
794
|
- App definitions: `GET /api/apps` and `GET /api/apps/<id>` with the API key as Bearer.
|
|
795
|
+
- Follow-up edit to a live app: list in the brief the control numbers the edit must not move, and assert them from the backing script before publishing. Take a signed-in screenshot of each changed selector at 1440px wide, save the shots to agent-fs, critique, and repeat at least 3 times. If the backing script caches results, bump its version or force a fresh run so the shots show new data.
|
|
793
796
|
|
|
794
797
|
|
|
795
798
|
### Rows from agents and scripts
|
|
@@ -640,6 +640,8 @@ Only inside action-chain `params` (`on.<event>`, `Table.rowActions[].actions`, o
|
|
|
640
640
|
| `{ "$form": "title" }` | One current Form value. |
|
|
641
641
|
| `{ "$form": "" }` | All current Form values. |
|
|
642
642
|
| `{ "$state": "/queries/allIdeas/data" }` | Current value at a valid app state path, including action state such as `/actions/refreshIssues/status`. |
|
|
643
|
+
| `{ "$chain": "leafTaskId" }` | One chain-scope value, published by a component that runs a task chain; it carries `leafTaskId` and `newTaskId`. Where no chain scope is published, the sentinel is left in place and the action fails instead of silently dropping the parent. |
|
|
644
|
+
| `{ "$chain": "" }` | The whole chain scope. |
|
|
643
645
|
|
|
644
646
|
Each sentinel object must contain exactly the single key shown.
|
|
645
647
|
|
|
@@ -647,7 +649,7 @@ An action-chain step is `{ "action": "<type>", "params": {...} }`. Available act
|
|
|
647
649
|
|
|
648
650
|
- `app.mutate`: `{ model, op, rowId?, values?, formId? }`, where `op` is `"create"`, `"update"`, or `"delete"`. `update`/`delete` require `rowId` (usually `{ "$row": "id" }`, or `{ "$state": "/route/params/<param>" }` in a Drawer footer); literal `values` keys must be model columns. Successful mutation refetches all queries on that model.
|
|
649
651
|
- `app.refresh`: `{ query? }`; omit `query` to refetch all, or name a declared query.
|
|
650
|
-
- `app.action`: `{ name, input? }`; `name` must be declared in definition `actions`. For a task-kind row action, pass whole-row context with `input: { issue: { "$row": "" } }`.
|
|
652
|
+
- `app.action`: `{ name, input?, parentTaskId? }`; `name` must be declared in definition `actions`. For a task-kind row action, pass whole-row context with `input: { issue: { "$row": "" } }`. `parentTaskId` chains the created task under an existing one for task-kind actions (typically `{ "$chain": "leafTaskId" }`; a literal or `$state` task id also works); a script or sync action rejects it with 400.
|
|
651
653
|
- `app.navigate`: `{ page, params? }`; `page` must be declared, supplied keys must be params of the target page, and every required target param must be supplied. `params` replace the current route params wholesale and may contain action sentinels. Navigation pushes history, so browser Back returns to the previous page/params; only `mode` is preserved automatically.
|
|
652
654
|
- `ui.toast`: `{ message, description?, tone?, undo? }`, where `tone` is `"success"`, `"error"`, `"info"` (default), or `"warning"`. `undo: { label?, actions }` adds an Undo button (default label `Undo`) that runs `actions` as a chain; its steps are validated like any chain. Put it after the step it confirms, e.g. a row delete followed by `{ "action": "ui.toast", "params": { "message": "Order deleted", "undo": { "actions": [{ "action": "app.mutate", "params": { "model": "order", "op": "create", "values": { "title": { "$row": "title" } } } }] } } }`. Undo params resolve `$state` when Undo is pressed; `$row` / `$form` resolve when the toast is shown.
|
|
653
655
|
- `swarm.sdk`: `{ sdk, args? }`; invokes a catalog-supported Swarm browser SDK method with the viewer's bearer.
|
|
@@ -785,6 +787,7 @@ The tool returns `{ appId, url: "/apps/<id>" }`. Open that URL to verify the liv
|
|
|
785
787
|
- Logged-in browser: a fresh dashboard has no connection and redirects to /setup. Seed the localStorage key `agent-swarm-connections` with `{connections:[{id,name,apiUrl,apiKey}],activeId}`. Build the value from an env var and pipe it to `agent-browser eval --stdin`, so the key never reaches a command line. Reload, then pick a user in the "Who are you?" dialog.
|
|
786
788
|
- Apps scroll inside an inner canvas, so a full-page screenshot captures only the viewport. Scroll the canvas or raise the viewport height. For mobile, set a 375px-wide viewport before the screenshot.
|
|
787
789
|
- App definitions: `GET /api/apps` and `GET /api/apps/<id>` with the API key as Bearer.
|
|
790
|
+
- Follow-up edit to a live app: list in the brief the control numbers the edit must not move, and assert them from the backing script before publishing. Take a signed-in screenshot of each changed selector at 1440px wide, save the shots to agent-fs, critique, and repeat at least 3 times. If the backing script caches results, bump its version or force a fresh run so the shots show new data.
|
|
788
791
|
|
|
789
792
|
|
|
790
793
|
### Rows from agents and scripts
|
|
@@ -82,27 +82,22 @@ The review body is the verdict line: at most about 60 tokens. Each inline commen
|
|
|
82
82
|
- Swarm PR, nit fixed: ``**Approve** at `3d4f34a` · 0 blocking · set `Risk: high` (billing) in the body``
|
|
83
83
|
- Re-review: ``**Approve** at `661327f` · B1 fixed · N1 won't fix (author)``, new findings inline.
|
|
84
84
|
|
|
85
|
-
Never on GitHub: test counts, CI lists (unless a red check changes the verdict), what you read, how the code works, or why GitHub refused a formal verdict. Those go to your task output
|
|
85
|
+
Never on GitHub: test counts, CI lists (unless a red check changes the verdict), what you read, how the code works, or why GitHub refused a formal verdict. Those go to your task output.
|
|
86
86
|
|
|
87
|
-
### Post
|
|
87
|
+
### Post the review
|
|
88
88
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
1. Draft the review as JSON: `{ pr: "<owner>/<repo>#<n>", head, swarmAuthored, risk, round, priorFindings: [{ id, state, text }], findings: [{ id?, tag, path?, line?, text, fix? }], body? }`. Write `fix` so it reads as done in the verdict line, for example "set `Risk: high` (billing) in the body". When you ran `code-reviewing`, its Standards/Spec report stays in your task output; only its findings go into the draft.
|
|
92
|
-
2. Run `script-run name="review-post-gate" scope="global" args=<draft>`. It checks token limits, the nit cap, tallies and CI lists, turns swarm-PR nits into `fixes`, and asks Jev to keep, drop or relabel each finding against the live `rules.md`. Every decision is logged with its reason. With `jev: "unavailable"` the deterministic result still stands.
|
|
93
|
-
3. Apply every entry in `fixes`, then post exactly `postable`, never your draft:
|
|
89
|
+
1. Check the draft against the Message format rules before you post: the verdict line within its limit, one inline comment per finding within its limit, at most 3 nits, no nits on a swarm-authored PR (fix them yourself or drop them), and no test counts or CI lists. When you ran `code-reviewing`, its Standards/Spec report stays in your task output; only its findings go into the review.
|
|
90
|
+
2. Post the verdict line and every inline comment as one review:
|
|
94
91
|
|
|
95
92
|
```bash
|
|
96
|
-
jq -n --
|
|
97
|
-
'{commit_id: $sha, event: $
|
|
93
|
+
jq -n --arg sha "$HEAD" --arg event "$EVENT" --arg body "$VERDICT" --argjson comments "$COMMENTS" \
|
|
94
|
+
'{commit_id: $sha, event: $event, body: $body, comments: [$comments[] | {path, line, side: "RIGHT", body}]}' \
|
|
98
95
|
| gh api repos/<owner>/<repo>/pulls/<n>/reviews --input -
|
|
99
96
|
```
|
|
100
97
|
|
|
101
|
-
On a PR the reviewing account authored,
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
If the gate cannot run, post nothing to GitHub. Keep the draft in your task output and report the gate failure (the error and the time) to the lead.
|
|
98
|
+
`EVENT` is `APPROVE` or `REQUEST_CHANGES`. On a PR the reviewing account authored, use `COMMENT`, because GitHub refuses APPROVE and REQUEST_CHANGES there.
|
|
99
|
+
3. Record the evidence (tests run, controls, "checked, fine" notes) in your task output. Never on the PR.
|
|
100
|
+
4. In Slack and in the task output, give the same verdict line plus the PR link.
|
|
106
101
|
|
|
107
102
|
### Capture pushback as a rule
|
|
108
103
|
|
|
@@ -22,7 +22,7 @@ Two kinds of sections:
|
|
|
22
22
|
## The cap
|
|
23
23
|
|
|
24
24
|
- Tracked items across all tracked sections: 10. Absolute maximum 20, only during a real surge.
|
|
25
|
-
- Every tracked item states its lift trigger and a date. An item with no removal condition does not go in.
|
|
25
|
+
- Every tracked item states its lift trigger and a date. An item with no removal condition does not go in. Write the date as a bare `MM-DD` (`check 10-20`) or `DELETE MM-DD` for a past-date prune: those are the only forms the gate can see.
|
|
26
26
|
- Write an age trigger as a calendar date (opened date + N days), never as a day count computed at check time. A floored age fires a day late.
|
|
27
27
|
- Never arm a defer chain to re-check a tracked item. The next heartbeat already checks it. Defer only for work no scheduled pass owns.
|
|
28
28
|
- Incident detail goes to memory: `memory-store` at `swarm` scope, one line of pointer stays in the runbook.
|
|
@@ -63,7 +63,7 @@ A gate script can run before each checklist tick and decide whether the tick nee
|
|
|
63
63
|
- `HEARTBEAT_CHECKLIST_GATE_MODE=enforce`: a quiet verdict skips the task. A wake verdict adds the gate's summary as a Gate Findings section. Enforce is opt-in; turn it on only after shadow tags agree with your own quiet outcomes.
|
|
64
64
|
- The gate fails open. A timeout (60 s), a script error or a malformed result is an `error` verdict, and the task is created in both modes.
|
|
65
65
|
- Preview a verdict with `script-run` on `heartbeat-jev-gate`, `args: { dryRun: true }`.
|
|
66
|
-
- The gate sees a tracked item as due when its line contains today's
|
|
66
|
+
- The gate sees a tracked item as due when its line contains today's `MM-DD` as a bare token (`check 10-20`) or a `DELETE MM-DD` marker on or before today. A full `YYYY-MM-DD` date does not count: a line that only carries a re-verification stamp (`2026-10-20 ~10:45Z`) is invisible to the gate, so write the due date bare. A line with no date is invisible too, and a date already past is only caught through `DELETE MM-DD`, so the prune in step 2 still matters.
|
|
67
67
|
|
|
68
68
|
## Example standing orders
|
|
69
69
|
|
|
@@ -74,5 +74,5 @@ A gate script can run before each checklist tick and decide whether the tick nee
|
|
|
74
74
|
- Slack requests older than 1 hour without a task: create the task.
|
|
75
75
|
|
|
76
76
|
## Watch Items
|
|
77
|
-
- Linear webhook retries since 2026-08-18. Lift when zero retries for 48 h (check
|
|
77
|
+
- Linear webhook retries since 2026-08-18. Lift when zero retries for 48 h (check 08-22).
|
|
78
78
|
```
|
package/dist/cli-v1sjhn52.js
DELETED
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
isUserAllowed2,
|
|
3
|
-
registerMessageHandler2
|
|
4
|
-
} from "./cli-10hhg0km.js";
|
|
5
|
-
import"./cli-0qvtffe9.js";
|
|
6
|
-
import"./cli-bcj753sq.js";
|
|
7
|
-
import"./cli-5rk36sjf.js";
|
|
8
|
-
import"./cli-smvcw9z5.js";
|
|
9
|
-
import"./cli-sv5gb0yb.js";
|
|
10
|
-
import"./cli-qz93y3x5.js";
|
|
11
|
-
import"./cli-3h26v7yj.js";
|
|
12
|
-
import"./cli-7a91w22y.js";
|
|
13
|
-
import"./cli-saw9a6f6.js";
|
|
14
|
-
import"./cli-h38rjv87.js";
|
|
15
|
-
import"./cli-3ggwdtb0.js";
|
|
16
|
-
import"./cli-s6vr7r2d.js";
|
|
17
|
-
import"./cli-faypxz7q.js";
|
|
18
|
-
import"./cli-h93c9vb3.js";
|
|
19
|
-
import"./cli-qje9k2nh.js";
|
|
20
|
-
import"./cli-y2x52gs2.js";
|
|
21
|
-
import"./cli-02qm7src.js";
|
|
22
|
-
import"./cli-8nyhf7za.js";
|
|
23
|
-
import"./cli-ejs3m1sx.js";
|
|
24
|
-
import"./cli-efaqv1c7.js";
|
|
25
|
-
import"./cli-13p25grh.js";
|
|
26
|
-
import"./cli-0adyhvq2.js";
|
|
27
|
-
import"./cli-nn47d7e8.js";
|
|
28
|
-
import"./cli-pkht5hap.js";
|
|
29
|
-
import"./cli-n85dqg6d.js";
|
|
30
|
-
import"./cli-nmqdc2t3.js";
|
|
31
|
-
import"./cli-445c1vp7.js";
|
|
32
|
-
import"./cli-kvzgak7c.js";
|
|
33
|
-
import"./cli-7awf1fp8.js";
|
|
34
|
-
import"./cli-d3qqdy4c.js";
|
|
35
|
-
import"./cli-wt645v7q.js";
|
|
36
|
-
export {
|
|
37
|
-
isUserAllowed2 as isUserAllowed,
|
|
38
|
-
registerMessageHandler2 as registerMessageHandler
|
|
39
|
-
};
|
package/dist/index-5jecgp3n.js
DELETED
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
import"./cli-ns59dc6r.js";
|
|
2
|
-
import {
|
|
3
|
-
startHeartbeat2,
|
|
4
|
-
stopHeartbeat2
|
|
5
|
-
} from "./cli-hyfw2j1e.js";
|
|
6
|
-
import"./cli-8zwe9mpk.js";
|
|
7
|
-
import"./cli-hqhzg1qq.js";
|
|
8
|
-
import"./cli-5rk36sjf.js";
|
|
9
|
-
import"./cli-smvcw9z5.js";
|
|
10
|
-
import"./cli-sv5gb0yb.js";
|
|
11
|
-
import"./cli-qz93y3x5.js";
|
|
12
|
-
import"./cli-3h26v7yj.js";
|
|
13
|
-
import"./cli-7a91w22y.js";
|
|
14
|
-
import"./cli-saw9a6f6.js";
|
|
15
|
-
import"./cli-h38rjv87.js";
|
|
16
|
-
import"./cli-3ggwdtb0.js";
|
|
17
|
-
import"./cli-s6vr7r2d.js";
|
|
18
|
-
import"./cli-faypxz7q.js";
|
|
19
|
-
import"./cli-h93c9vb3.js";
|
|
20
|
-
import"./cli-qje9k2nh.js";
|
|
21
|
-
import"./cli-y2x52gs2.js";
|
|
22
|
-
import"./cli-02qm7src.js";
|
|
23
|
-
import"./cli-8nyhf7za.js";
|
|
24
|
-
import"./cli-ejs3m1sx.js";
|
|
25
|
-
import"./cli-efaqv1c7.js";
|
|
26
|
-
import"./cli-13p25grh.js";
|
|
27
|
-
import"./cli-0adyhvq2.js";
|
|
28
|
-
import"./cli-nn47d7e8.js";
|
|
29
|
-
import"./cli-pkht5hap.js";
|
|
30
|
-
import"./cli-n85dqg6d.js";
|
|
31
|
-
import"./cli-nmqdc2t3.js";
|
|
32
|
-
import"./cli-445c1vp7.js";
|
|
33
|
-
import"./cli-kvzgak7c.js";
|
|
34
|
-
import"./cli-b2mz5mjc.js";
|
|
35
|
-
import"./cli-7awf1fp8.js";
|
|
36
|
-
import"./cli-d3qqdy4c.js";
|
|
37
|
-
import"./cli-wt645v7q.js";
|
|
38
|
-
export {
|
|
39
|
-
startHeartbeat2 as startHeartbeat,
|
|
40
|
-
stopHeartbeat2 as stopHeartbeat
|
|
41
|
-
};
|