@exla/rudder 0.0.0-stage → 3.4.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/LICENSE +100 -0
- package/README.md +733 -2
- package/assets/rudder.icns +0 -0
- package/assets/sounds/NOTICE.md +8 -0
- package/assets/sounds/ping.mp3 +0 -0
- package/dist/agent-attention.d.ts +5 -0
- package/dist/agent-attention.js +54 -0
- package/dist/agent-attention.js.map +1 -0
- package/dist/analytics.d.ts +36 -0
- package/dist/analytics.js +178 -0
- package/dist/analytics.js.map +1 -0
- package/dist/attach-session.d.ts +91 -0
- package/dist/attach-session.js +290 -0
- package/dist/attach-session.js.map +1 -0
- package/dist/auth.d.ts +36 -0
- package/dist/auth.js +392 -0
- package/dist/auth.js.map +1 -0
- package/dist/backends.d.ts +3 -0
- package/dist/backends.js +638 -0
- package/dist/backends.js.map +1 -0
- package/dist/board/board.css +1 -0
- package/dist/board/board.js +2 -0
- package/dist/board/daemon.d.ts +39 -0
- package/dist/board/daemon.js +1510 -0
- package/dist/board/daemon.js.map +1 -0
- package/dist/brain.d.ts +24 -0
- package/dist/brain.js +244 -0
- package/dist/brain.js.map +1 -0
- package/dist/bus.d.ts +9 -0
- package/dist/bus.js +23 -0
- package/dist/bus.js.map +1 -0
- package/dist/checkout-sync.d.ts +35 -0
- package/dist/checkout-sync.js +247 -0
- package/dist/checkout-sync.js.map +1 -0
- package/dist/cloud.d.ts +48 -0
- package/dist/cloud.js +4596 -0
- package/dist/cloud.js.map +1 -0
- package/dist/codex-binary.d.ts +12 -0
- package/dist/codex-binary.js +184 -0
- package/dist/codex-binary.js.map +1 -0
- package/dist/context-audit.d.ts +21 -0
- package/dist/context-audit.js +109 -0
- package/dist/context-audit.js.map +1 -0
- package/dist/daemon.d.ts +27 -0
- package/dist/daemon.js +203 -0
- package/dist/daemon.js.map +1 -0
- package/dist/effort.d.ts +9 -0
- package/dist/effort.js +72 -0
- package/dist/effort.js.map +1 -0
- package/dist/feedback.d.ts +46 -0
- package/dist/feedback.js +173 -0
- package/dist/feedback.js.map +1 -0
- package/dist/gc.d.ts +3 -0
- package/dist/gc.js +262 -0
- package/dist/gc.js.map +1 -0
- package/dist/git.d.ts +31 -0
- package/dist/git.js +455 -0
- package/dist/git.js.map +1 -0
- package/dist/goal.d.ts +33 -0
- package/dist/goal.js +95 -0
- package/dist/goal.js.map +1 -0
- package/dist/graph.d.ts +93 -0
- package/dist/graph.js +372 -0
- package/dist/graph.js.map +1 -0
- package/dist/handoff.d.ts +110 -0
- package/dist/handoff.js +565 -0
- package/dist/handoff.js.map +1 -0
- package/dist/improve/advisor.d.ts +10 -0
- package/dist/improve/advisor.js +115 -0
- package/dist/improve/advisor.js.map +1 -0
- package/dist/improve/collect.d.ts +49 -0
- package/dist/improve/collect.js +274 -0
- package/dist/improve/collect.js.map +1 -0
- package/dist/improve/gate.d.ts +17 -0
- package/dist/improve/gate.js +60 -0
- package/dist/improve/gate.js.map +1 -0
- package/dist/improve/index.d.ts +9 -0
- package/dist/improve/index.js +376 -0
- package/dist/improve/index.js.map +1 -0
- package/dist/improve/judge.d.ts +32 -0
- package/dist/improve/judge.js +114 -0
- package/dist/improve/judge.js.map +1 -0
- package/dist/improve/mine.d.ts +31 -0
- package/dist/improve/mine.js +192 -0
- package/dist/improve/mine.js.map +1 -0
- package/dist/improve/propose.d.ts +51 -0
- package/dist/improve/propose.js +150 -0
- package/dist/improve/propose.js.map +1 -0
- package/dist/improve/rank.d.ts +16 -0
- package/dist/improve/rank.js +49 -0
- package/dist/improve/rank.js.map +1 -0
- package/dist/improve/schedule.d.ts +1 -0
- package/dist/improve/schedule.js +95 -0
- package/dist/improve/schedule.js.map +1 -0
- package/dist/improve/ship.d.ts +25 -0
- package/dist/improve/ship.js +82 -0
- package/dist/improve/ship.js.map +1 -0
- package/dist/improve/state.d.ts +157 -0
- package/dist/improve/state.js +264 -0
- package/dist/improve/state.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +88 -0
- package/dist/index.js.map +1 -0
- package/dist/jj-binary.d.ts +36 -0
- package/dist/jj-binary.js +143 -0
- package/dist/jj-binary.js.map +1 -0
- package/dist/jj.d.ts +163 -0
- package/dist/jj.js +926 -0
- package/dist/jj.js.map +1 -0
- package/dist/logger.d.ts +22 -0
- package/dist/logger.js +110 -0
- package/dist/logger.js.map +1 -0
- package/dist/main.d.ts +3 -0
- package/dist/main.js +1366 -0
- package/dist/main.js.map +1 -0
- package/dist/migration.d.ts +82 -0
- package/dist/migration.js +198 -0
- package/dist/migration.js.map +1 -0
- package/dist/models.d.ts +9 -0
- package/dist/models.js +623 -0
- package/dist/models.js.map +1 -0
- package/dist/move-home.d.ts +82 -0
- package/dist/move-home.js +472 -0
- package/dist/move-home.js.map +1 -0
- package/dist/native/darwin-arm64/rudder-native +0 -0
- package/dist/native/darwin-x64/rudder-native +0 -0
- package/dist/native/linux-x64/rudder-native +0 -0
- package/dist/native-agents.d.ts +8 -0
- package/dist/native-agents.js +178 -0
- package/dist/native-agents.js.map +1 -0
- package/dist/native-binary.d.ts +4 -0
- package/dist/native-binary.js +140 -0
- package/dist/native-binary.js.map +1 -0
- package/dist/paste-bridge.d.ts +36 -0
- package/dist/paste-bridge.js +279 -0
- package/dist/paste-bridge.js.map +1 -0
- package/dist/plan-mode.d.ts +2 -0
- package/dist/plan-mode.js +22 -0
- package/dist/plan-mode.js.map +1 -0
- package/dist/planner.d.ts +27 -0
- package/dist/planner.js +587 -0
- package/dist/planner.js.map +1 -0
- package/dist/predict.d.ts +67 -0
- package/dist/predict.js +369 -0
- package/dist/predict.js.map +1 -0
- package/dist/report.d.ts +74 -0
- package/dist/report.js +412 -0
- package/dist/report.js.map +1 -0
- package/dist/rudder-md.d.ts +33 -0
- package/dist/rudder-md.js +142 -0
- package/dist/rudder-md.js.map +1 -0
- package/dist/run-manager.d.ts +62 -0
- package/dist/run-manager.js +1400 -0
- package/dist/run-manager.js.map +1 -0
- package/dist/scheduler.d.ts +128 -0
- package/dist/scheduler.js +955 -0
- package/dist/scheduler.js.map +1 -0
- package/dist/state.d.ts +127 -0
- package/dist/state.js +704 -0
- package/dist/state.js.map +1 -0
- package/dist/surfaces.d.ts +91 -0
- package/dist/surfaces.js +460 -0
- package/dist/surfaces.js.map +1 -0
- package/dist/task-summary.d.ts +30 -0
- package/dist/task-summary.js +472 -0
- package/dist/task-summary.js.map +1 -0
- package/dist/types.d.ts +492 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/usage.d.ts +198 -0
- package/dist/usage.js +830 -0
- package/dist/usage.js.map +1 -0
- package/dist/util.d.ts +73 -0
- package/dist/util.js +399 -0
- package/dist/util.js.map +1 -0
- package/dist/version-check.d.ts +16 -0
- package/dist/version-check.js +269 -0
- package/dist/version-check.js.map +1 -0
- package/package.json +68 -4
- package/scripts/copy-native.mjs +89 -0
- package/scripts/postinstall.mjs +34 -0
|
Binary file
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
`ping.mp3` is copied from:
|
|
2
|
+
|
|
3
|
+
https://github.com/superset-sh/superset/tree/main/apps/desktop/src/resources/sounds
|
|
4
|
+
|
|
5
|
+
Superset is distributed under the Elastic License 2.0. The relevant license text
|
|
6
|
+
is available at:
|
|
7
|
+
|
|
8
|
+
https://github.com/superset-sh/superset/blob/main/LICENSE.md
|
|
Binary file
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
const PERMISSION_WORD = /\b(permission|approval|approve|allow|authorize|authorization|confirmation|proceed|deny)\b/i;
|
|
2
|
+
const PERMISSION_PATTERNS = [
|
|
3
|
+
/\b(do you want|would you like|are you sure)\b[\s\S]{0,180}\b(allow|approve|run|execute|continue|proceed)\b/i,
|
|
4
|
+
/\b(allow|approve|authorize)\b[\s\S]{0,120}\b(command|tool|edit|write|file|access|execution|network|shell|operation)\b/i,
|
|
5
|
+
/\b(permission|approval|authorization|confirmation)\b[\s\S]{0,160}\b(required|need(?:ed)?|request(?:ed|ing)?|waiting|prompt)\b[\s\S]{0,160}\b(approve|allow|deny|yes|no|enter|return|press)\b/i,
|
|
6
|
+
/\b(approve|allow|deny|yes|no|enter|return|press)\b[\s\S]{0,160}\b(permission|approval|authorization|confirmation)\b/i,
|
|
7
|
+
/\bpress\b[\s\S]{0,80}\b(y|yes|enter|return)\b[\s\S]{0,120}\b(allow|approve|continue|proceed)\b/i,
|
|
8
|
+
/\b(yes|no)\b[\s\S]{0,100}\b(approve|deny|allow|permission)\b/i,
|
|
9
|
+
];
|
|
10
|
+
export function permissionAttentionFromOutput(output) {
|
|
11
|
+
const recentLines = recentTerminalLines(output, 60);
|
|
12
|
+
const recentText = recentLines.join("\n");
|
|
13
|
+
if (!PERMISSION_WORD.test(recentText)) {
|
|
14
|
+
return { needsPermission: false };
|
|
15
|
+
}
|
|
16
|
+
if (!PERMISSION_PATTERNS.some((pattern) => pattern.test(recentText))) {
|
|
17
|
+
return { needsPermission: false };
|
|
18
|
+
}
|
|
19
|
+
return {
|
|
20
|
+
needsPermission: true,
|
|
21
|
+
summary: summarizePermissionPrompt(recentLines),
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
function summarizePermissionPrompt(lines) {
|
|
25
|
+
const line = [...lines]
|
|
26
|
+
.reverse()
|
|
27
|
+
.find((candidate) => PERMISSION_WORD.test(candidate));
|
|
28
|
+
if (!line) {
|
|
29
|
+
return undefined;
|
|
30
|
+
}
|
|
31
|
+
return truncate(line.replace(/\s+/g, " ").trim(), 120);
|
|
32
|
+
}
|
|
33
|
+
function recentTerminalLines(output, maxLines) {
|
|
34
|
+
return stripTerminalControls(output)
|
|
35
|
+
.replace(/\r/g, "\n")
|
|
36
|
+
.split("\n")
|
|
37
|
+
.map((line) => line.trim())
|
|
38
|
+
.filter(Boolean)
|
|
39
|
+
.slice(-maxLines);
|
|
40
|
+
}
|
|
41
|
+
function stripTerminalControls(value) {
|
|
42
|
+
return value
|
|
43
|
+
.replace(/\x1b\][^\u0007]*(?:\u0007|\x1b\\)/g, "")
|
|
44
|
+
.replace(/\x1b\[[0-?]*[ -/]*[@-~]/g, "")
|
|
45
|
+
.replace(/\x1b[()][A-Za-z0-9]/g, "")
|
|
46
|
+
.replace(/[\u0000-\u0008\u000b\u000c\u000e-\u001f\u007f]/g, "");
|
|
47
|
+
}
|
|
48
|
+
function truncate(value, width) {
|
|
49
|
+
if (value.length <= width) {
|
|
50
|
+
return value;
|
|
51
|
+
}
|
|
52
|
+
return `${value.slice(0, Math.max(0, width - 3))}...`;
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=agent-attention.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-attention.js","sourceRoot":"","sources":["../src/agent-attention.ts"],"names":[],"mappings":"AAKA,MAAM,eAAe,GAAG,4FAA4F,CAAC;AACrH,MAAM,mBAAmB,GAAG;IAC1B,6GAA6G;IAC7G,wHAAwH;IACxH,+LAA+L;IAC/L,sHAAsH;IACtH,iGAAiG;IACjG,+DAA+D;CAChE,CAAC;AAEF,MAAM,UAAU,6BAA6B,CAAC,MAAc;IAC1D,MAAM,WAAW,GAAG,mBAAmB,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IACpD,MAAM,UAAU,GAAG,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC1C,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC;QACtC,OAAO,EAAE,eAAe,EAAE,KAAK,EAAE,CAAC;IACpC,CAAC;IACD,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC;QACrE,OAAO,EAAE,eAAe,EAAE,KAAK,EAAE,CAAC;IACpC,CAAC;IACD,OAAO;QACL,eAAe,EAAE,IAAI;QACrB,OAAO,EAAE,yBAAyB,CAAC,WAAW,CAAC;KAChD,CAAC;AACJ,CAAC;AAED,SAAS,yBAAyB,CAAC,KAAe;IAChD,MAAM,IAAI,GAAG,CAAC,GAAG,KAAK,CAAC;SACpB,OAAO,EAAE;SACT,IAAI,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,eAAe,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC;IACxD,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,OAAO,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,GAAG,CAAC,CAAC;AACzD,CAAC;AAED,SAAS,mBAAmB,CAAC,MAAc,EAAE,QAAgB;IAC3D,OAAO,qBAAqB,CAAC,MAAM,CAAC;SACjC,OAAO,CAAC,KAAK,EAAE,IAAI,CAAC;SACpB,KAAK,CAAC,IAAI,CAAC;SACX,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;SAC1B,MAAM,CAAC,OAAO,CAAC;SACf,KAAK,CAAC,CAAC,QAAQ,CAAC,CAAC;AACtB,CAAC;AAED,SAAS,qBAAqB,CAAC,KAAa;IAC1C,OAAO,KAAK;SACT,OAAO,CAAC,oCAAoC,EAAE,EAAE,CAAC;SACjD,OAAO,CAAC,0BAA0B,EAAE,EAAE,CAAC;SACvC,OAAO,CAAC,sBAAsB,EAAE,EAAE,CAAC;SACnC,OAAO,CAAC,iDAAiD,EAAE,EAAE,CAAC,CAAC;AACpE,CAAC;AAED,SAAS,QAAQ,CAAC,KAAa,EAAE,KAAa;IAC5C,IAAI,KAAK,CAAC,MAAM,IAAI,KAAK,EAAE,CAAC;QAC1B,OAAO,KAAK,CAAC;IACf,CAAC;IACD,OAAO,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC;AACxD,CAAC"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
export declare const TELEMETRY_NOTICE = "rudder sends anonymous usage events (which backend, which commands, merge outcomes) \u2014 never your prompts, code, paths, or repo names. Turn it off with `rudder telemetry off`.";
|
|
2
|
+
export type EventProperties = Record<string, string | number | boolean | undefined>;
|
|
3
|
+
/**
|
|
4
|
+
* Off when the user said so, and off in the places where events would be noise
|
|
5
|
+
* rather than signal: CI, the fake-backend test harness, and any run with no
|
|
6
|
+
* project key configured.
|
|
7
|
+
*/
|
|
8
|
+
export declare function telemetryEnabled(): Promise<boolean>;
|
|
9
|
+
export declare function setTelemetryEnabled(enabled: boolean): Promise<void>;
|
|
10
|
+
/**
|
|
11
|
+
* A stable anonymous id per install, minted once and kept in the global config.
|
|
12
|
+
* It identifies a machine's rudder, not a person: no email, no username, no
|
|
13
|
+
* hostname. Without it every event would look like a new user and retention
|
|
14
|
+
* would be meaningless.
|
|
15
|
+
*/
|
|
16
|
+
export declare function installId(): Promise<string>;
|
|
17
|
+
/**
|
|
18
|
+
* Show the telemetry notice exactly once per install and record that we did.
|
|
19
|
+
* Returns the text to print, or undefined when it has already been shown (or
|
|
20
|
+
* telemetry is off, in which case there is nothing to disclose).
|
|
21
|
+
*/
|
|
22
|
+
export declare function pendingTelemetryNotice(): Promise<string | undefined>;
|
|
23
|
+
/**
|
|
24
|
+
* A repository identity that cannot be turned back into a path or a name:
|
|
25
|
+
* "how many distinct projects" without saying which. Truncated because a full
|
|
26
|
+
* digest is no more useful here and reads as more identifying than it is.
|
|
27
|
+
*/
|
|
28
|
+
export declare function projectHash(repoRoot: string): string;
|
|
29
|
+
/** Drop undefined values and anything that smells like a path or a secret. */
|
|
30
|
+
export declare function sanitizeProperties(properties: EventProperties): EventProperties;
|
|
31
|
+
/**
|
|
32
|
+
* Send one event. Resolves whether or not it worked: a failed capture is never
|
|
33
|
+
* worth surfacing, and never worth retrying (the next session will tell the
|
|
34
|
+
* same story). Returns true only when PostHog accepted it, for tests.
|
|
35
|
+
*/
|
|
36
|
+
export declare function capture(event: string, properties?: EventProperties): Promise<boolean>;
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
// ---------------------------------------------------------------------------
|
|
2
|
+
// USAGE TELEMETRY.
|
|
3
|
+
//
|
|
4
|
+
// Rudder emits a small set of anonymous product events so the parts people get
|
|
5
|
+
// stuck on are visible: how many installs ever start an agent, how many ever
|
|
6
|
+
// merge, which backend they pick, which errors fire most. npm downloads cannot
|
|
7
|
+
// answer any of that.
|
|
8
|
+
//
|
|
9
|
+
// The rules this file exists to enforce:
|
|
10
|
+
// * NEVER send prompts, diffs, file contents, paths, repo names, or session
|
|
11
|
+
// ids. Only the whitelisted properties each call site passes, plus a hashed
|
|
12
|
+
// project id when a cardinality signal is genuinely needed.
|
|
13
|
+
// * NEVER block the caller. A dashboard that stutters because analytics is
|
|
14
|
+
// slow is a worse product than one with no analytics.
|
|
15
|
+
// * ALWAYS be trivially switchable off, and say so on first run. Dev tools
|
|
16
|
+
// that phone home silently get uninstalled, deservedly.
|
|
17
|
+
//
|
|
18
|
+
// Transport is PostHog's public capture endpoint: one POST with the PROJECT
|
|
19
|
+
// token (a write-only key, safe to ship) and `$process_person_profile: false`,
|
|
20
|
+
// which keeps events anonymous — no person profile per install.
|
|
21
|
+
// ---------------------------------------------------------------------------
|
|
22
|
+
import { createHash, randomUUID } from "node:crypto";
|
|
23
|
+
import fsp from "node:fs/promises";
|
|
24
|
+
import { fileURLToPath } from "node:url";
|
|
25
|
+
import path from "node:path";
|
|
26
|
+
import { loadConfig, saveConfig } from "./state.js";
|
|
27
|
+
const POSTHOG_HOST = "https://us.i.posthog.com";
|
|
28
|
+
/** Project write key. Public by design; overridable so forks can point elsewhere. */
|
|
29
|
+
const POSTHOG_PROJECT_KEY = "phc_2KfOzM4nSxjAgPDfgEikP7Kp7JVcU5aJ0kAyEQykkmn";
|
|
30
|
+
/** A hung network must never hold up a CLI command or the dashboard's shutdown. */
|
|
31
|
+
const CAPTURE_TIMEOUT_MS = 2_000;
|
|
32
|
+
export const TELEMETRY_NOTICE = "rudder sends anonymous usage events (which backend, which commands, merge outcomes) — never your prompts, code, paths, or repo names. Turn it off with `rudder telemetry off`.";
|
|
33
|
+
function posthogKey() {
|
|
34
|
+
return (process.env.RUDDER_POSTHOG_KEY ?? POSTHOG_PROJECT_KEY).trim();
|
|
35
|
+
}
|
|
36
|
+
function posthogHost() {
|
|
37
|
+
return (process.env.RUDDER_POSTHOG_HOST ?? POSTHOG_HOST).trim().replace(/\/+$/, "");
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Off when the user said so, and off in the places where events would be noise
|
|
41
|
+
* rather than signal: CI, the fake-backend test harness, and any run with no
|
|
42
|
+
* project key configured.
|
|
43
|
+
*/
|
|
44
|
+
export async function telemetryEnabled() {
|
|
45
|
+
if (!posthogKey()) {
|
|
46
|
+
return false;
|
|
47
|
+
}
|
|
48
|
+
const flag = (process.env.RUDDER_TELEMETRY ?? "").trim().toLowerCase();
|
|
49
|
+
if (["0", "off", "false", "no"].includes(flag)) {
|
|
50
|
+
return false;
|
|
51
|
+
}
|
|
52
|
+
if (process.env.CI || process.env.RUDDER_FAKE_BACKEND === "1") {
|
|
53
|
+
return false;
|
|
54
|
+
}
|
|
55
|
+
const config = await loadConfig();
|
|
56
|
+
return config.telemetry !== false;
|
|
57
|
+
}
|
|
58
|
+
export async function setTelemetryEnabled(enabled) {
|
|
59
|
+
const config = await loadConfig();
|
|
60
|
+
await saveConfig({ ...config, telemetry: enabled });
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* A stable anonymous id per install, minted once and kept in the global config.
|
|
64
|
+
* It identifies a machine's rudder, not a person: no email, no username, no
|
|
65
|
+
* hostname. Without it every event would look like a new user and retention
|
|
66
|
+
* would be meaningless.
|
|
67
|
+
*/
|
|
68
|
+
export async function installId() {
|
|
69
|
+
const config = await loadConfig();
|
|
70
|
+
if (config.installId && /^[0-9a-f-]{8,}$/i.test(config.installId)) {
|
|
71
|
+
return config.installId;
|
|
72
|
+
}
|
|
73
|
+
const minted = randomUUID();
|
|
74
|
+
await saveConfig({ ...config, installId: minted });
|
|
75
|
+
return minted;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Show the telemetry notice exactly once per install and record that we did.
|
|
79
|
+
* Returns the text to print, or undefined when it has already been shown (or
|
|
80
|
+
* telemetry is off, in which case there is nothing to disclose).
|
|
81
|
+
*/
|
|
82
|
+
export async function pendingTelemetryNotice() {
|
|
83
|
+
if (!(await telemetryEnabled())) {
|
|
84
|
+
return undefined;
|
|
85
|
+
}
|
|
86
|
+
const config = await loadConfig();
|
|
87
|
+
if (config.telemetryNoticeShownAt) {
|
|
88
|
+
return undefined;
|
|
89
|
+
}
|
|
90
|
+
await saveConfig({ ...config, telemetryNoticeShownAt: new Date().toISOString() });
|
|
91
|
+
return TELEMETRY_NOTICE;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* A repository identity that cannot be turned back into a path or a name:
|
|
95
|
+
* "how many distinct projects" without saying which. Truncated because a full
|
|
96
|
+
* digest is no more useful here and reads as more identifying than it is.
|
|
97
|
+
*/
|
|
98
|
+
export function projectHash(repoRoot) {
|
|
99
|
+
return createHash("sha256").update(repoRoot).digest("hex").slice(0, 12);
|
|
100
|
+
}
|
|
101
|
+
/** The shipped version, read from the package rather than a baked constant. */
|
|
102
|
+
async function packageVersion() {
|
|
103
|
+
const packageFile = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..", "package.json");
|
|
104
|
+
const raw = await fsp.readFile(packageFile, "utf8").catch(() => "");
|
|
105
|
+
try {
|
|
106
|
+
return JSON.parse(raw).version ?? "unknown";
|
|
107
|
+
}
|
|
108
|
+
catch {
|
|
109
|
+
return "unknown";
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
async function baseProperties() {
|
|
113
|
+
return {
|
|
114
|
+
$process_person_profile: false,
|
|
115
|
+
rudder_version: await packageVersion(),
|
|
116
|
+
platform: `${process.platform}-${process.arch}`,
|
|
117
|
+
node_version: process.versions.node,
|
|
118
|
+
ci: Boolean(process.env.CI),
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
/** Drop undefined values and anything that smells like a path or a secret. */
|
|
122
|
+
export function sanitizeProperties(properties) {
|
|
123
|
+
const clean = {};
|
|
124
|
+
for (const [key, value] of Object.entries(properties)) {
|
|
125
|
+
if (value === undefined) {
|
|
126
|
+
continue;
|
|
127
|
+
}
|
|
128
|
+
if (typeof value === "string") {
|
|
129
|
+
// A property carrying an absolute path or a token is a bug at the call
|
|
130
|
+
// site; drop it rather than shipping it and apologising later.
|
|
131
|
+
if (value.startsWith("/") || value.startsWith("~/") || /^[A-Za-z]:\\/.test(value)) {
|
|
132
|
+
continue;
|
|
133
|
+
}
|
|
134
|
+
if (/(sk-|ghp_|phc_|xox[baprs]-)/.test(value)) {
|
|
135
|
+
continue;
|
|
136
|
+
}
|
|
137
|
+
clean[key] = value.length > 500 ? `${value.slice(0, 500)}…` : value;
|
|
138
|
+
continue;
|
|
139
|
+
}
|
|
140
|
+
clean[key] = value;
|
|
141
|
+
}
|
|
142
|
+
return clean;
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Send one event. Resolves whether or not it worked: a failed capture is never
|
|
146
|
+
* worth surfacing, and never worth retrying (the next session will tell the
|
|
147
|
+
* same story). Returns true only when PostHog accepted it, for tests.
|
|
148
|
+
*/
|
|
149
|
+
export async function capture(event, properties = {}) {
|
|
150
|
+
if (!(await telemetryEnabled())) {
|
|
151
|
+
return false;
|
|
152
|
+
}
|
|
153
|
+
const payload = {
|
|
154
|
+
api_key: posthogKey(),
|
|
155
|
+
event,
|
|
156
|
+
distinct_id: await installId(),
|
|
157
|
+
properties: { ...(await baseProperties()), ...sanitizeProperties(properties) },
|
|
158
|
+
timestamp: new Date().toISOString(),
|
|
159
|
+
};
|
|
160
|
+
const controller = new AbortController();
|
|
161
|
+
const timer = setTimeout(() => controller.abort(), CAPTURE_TIMEOUT_MS);
|
|
162
|
+
try {
|
|
163
|
+
const response = await fetch(`${posthogHost()}/i/v0/e/`, {
|
|
164
|
+
method: "POST",
|
|
165
|
+
headers: { "Content-Type": "application/json" },
|
|
166
|
+
body: JSON.stringify(payload),
|
|
167
|
+
signal: controller.signal,
|
|
168
|
+
});
|
|
169
|
+
return response.ok;
|
|
170
|
+
}
|
|
171
|
+
catch {
|
|
172
|
+
return false;
|
|
173
|
+
}
|
|
174
|
+
finally {
|
|
175
|
+
clearTimeout(timer);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
//# sourceMappingURL=analytics.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"analytics.js","sourceRoot":"","sources":["../src/analytics.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,mBAAmB;AACnB,EAAE;AACF,+EAA+E;AAC/E,6EAA6E;AAC7E,+EAA+E;AAC/E,sBAAsB;AACtB,EAAE;AACF,yCAAyC;AACzC,8EAA8E;AAC9E,gFAAgF;AAChF,gEAAgE;AAChE,6EAA6E;AAC7E,0DAA0D;AAC1D,6EAA6E;AAC7E,4DAA4D;AAC5D,EAAE;AACF,4EAA4E;AAC5E,+EAA+E;AAC/E,gEAAgE;AAChE,8EAA8E;AAE9E,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAErD,OAAO,GAAG,MAAM,kBAAkB,CAAC;AACnC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAEpD,MAAM,YAAY,GAAG,0BAA0B,CAAC;AAChD,qFAAqF;AACrF,MAAM,mBAAmB,GAAG,iDAAiD,CAAC;AAC9E,mFAAmF;AACnF,MAAM,kBAAkB,GAAG,KAAK,CAAC;AAEjC,MAAM,CAAC,MAAM,gBAAgB,GAC3B,gLAAgL,CAAC;AAInL,SAAS,UAAU;IACjB,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,kBAAkB,IAAI,mBAAmB,CAAC,CAAC,IAAI,EAAE,CAAC;AACxE,CAAC;AAED,SAAS,WAAW;IAClB,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,mBAAmB,IAAI,YAAY,CAAC,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;AACtF,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB;IACpC,IAAI,CAAC,UAAU,EAAE,EAAE,CAAC;QAClB,OAAO,KAAK,CAAC;IACf,CAAC;IACD,MAAM,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,gBAAgB,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IACvE,IAAI,CAAC,GAAG,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QAC/C,OAAO,KAAK,CAAC;IACf,CAAC;IACD,IAAI,OAAO,CAAC,GAAG,CAAC,EAAE,IAAI,OAAO,CAAC,GAAG,CAAC,mBAAmB,KAAK,GAAG,EAAE,CAAC;QAC9D,OAAO,KAAK,CAAC;IACf,CAAC;IACD,MAAM,MAAM,GAAG,MAAM,UAAU,EAAE,CAAC;IAClC,OAAO,MAAM,CAAC,SAAS,KAAK,KAAK,CAAC;AACpC,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,OAAgB;IACxD,MAAM,MAAM,GAAG,MAAM,UAAU,EAAE,CAAC;IAClC,MAAM,UAAU,CAAC,EAAE,GAAG,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC,CAAC;AACtD,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,SAAS;IAC7B,MAAM,MAAM,GAAG,MAAM,UAAU,EAAE,CAAC;IAClC,IAAI,MAAM,CAAC,SAAS,IAAI,kBAAkB,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC;QAClE,OAAO,MAAM,CAAC,SAAS,CAAC;IAC1B,CAAC;IACD,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;IAC5B,MAAM,UAAU,CAAC,EAAE,GAAG,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,CAAC,CAAC;IACnD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,sBAAsB;IAC1C,IAAI,CAAC,CAAC,MAAM,gBAAgB,EAAE,CAAC,EAAE,CAAC;QAChC,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,MAAM,MAAM,GAAG,MAAM,UAAU,EAAE,CAAC;IAClC,IAAI,MAAM,CAAC,sBAAsB,EAAE,CAAC;QAClC,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,MAAM,UAAU,CAAC,EAAE,GAAG,MAAM,EAAE,sBAAsB,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;IAClF,OAAO,gBAAgB,CAAC;AAC1B,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,WAAW,CAAC,QAAgB;IAC1C,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;AAC1E,CAAC;AAED,+EAA+E;AAC/E,KAAK,UAAU,cAAc;IAC3B,MAAM,WAAW,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,cAAc,CAAC,CAAC;IACrG,MAAM,GAAG,GAAG,MAAM,GAAG,CAAC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC;IACpE,IAAI,CAAC;QACH,OAAQ,IAAI,CAAC,KAAK,CAAC,GAAG,CAA0B,CAAC,OAAO,IAAI,SAAS,CAAC;IACxE,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC;AAED,KAAK,UAAU,cAAc;IAC3B,OAAO;QACL,uBAAuB,EAAE,KAAK;QAC9B,cAAc,EAAE,MAAM,cAAc,EAAE;QACtC,QAAQ,EAAE,GAAG,OAAO,CAAC,QAAQ,IAAI,OAAO,CAAC,IAAI,EAAE;QAC/C,YAAY,EAAE,OAAO,CAAC,QAAQ,CAAC,IAAI;QACnC,EAAE,EAAE,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;KAC5B,CAAC;AACJ,CAAC;AAED,8EAA8E;AAC9E,MAAM,UAAU,kBAAkB,CAAC,UAA2B;IAC5D,MAAM,KAAK,GAAoB,EAAE,CAAC;IAClC,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC;QACtD,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACxB,SAAS;QACX,CAAC;QACD,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;YAC9B,uEAAuE;YACvE,+DAA+D;YAC/D,IAAI,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,cAAc,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;gBAClF,SAAS;YACX,CAAC;YACD,IAAI,6BAA6B,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;gBAC9C,SAAS;YACX,CAAC;YACD,KAAK,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,MAAM,GAAG,GAAG,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC;YACpE,SAAS;QACX,CAAC;QACD,KAAK,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;IACrB,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,OAAO,CAAC,KAAa,EAAE,aAA8B,EAAE;IAC3E,IAAI,CAAC,CAAC,MAAM,gBAAgB,EAAE,CAAC,EAAE,CAAC;QAChC,OAAO,KAAK,CAAC;IACf,CAAC;IACD,MAAM,OAAO,GAAG;QACd,OAAO,EAAE,UAAU,EAAE;QACrB,KAAK;QACL,WAAW,EAAE,MAAM,SAAS,EAAE;QAC9B,UAAU,EAAE,EAAE,GAAG,CAAC,MAAM,cAAc,EAAE,CAAC,EAAE,GAAG,kBAAkB,CAAC,UAAU,CAAC,EAAE;QAC9E,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;KACpC,CAAC;IACF,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAC;IACzC,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,KAAK,EAAE,EAAE,kBAAkB,CAAC,CAAC;IACvE,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,WAAW,EAAE,UAAU,EAAE;YACvD,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;YAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC;YAC7B,MAAM,EAAE,UAAU,CAAC,MAAM;SAC1B,CAAC,CAAC;QACH,OAAO,QAAQ,CAAC,EAAE,CAAC;IACrB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;YAAS,CAAC;QACT,YAAY,CAAC,KAAK,CAAC,CAAC;IACtB,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { EchoPredictor } from "./predict.js";
|
|
2
|
+
export type SessionInput = {
|
|
3
|
+
on(event: "data", listener: (chunk: Buffer | string) => void): unknown;
|
|
4
|
+
off(event: "data", listener: (chunk: Buffer | string) => void): unknown;
|
|
5
|
+
resume(): unknown;
|
|
6
|
+
pause(): unknown;
|
|
7
|
+
setRawMode?(mode: boolean): unknown;
|
|
8
|
+
};
|
|
9
|
+
export type SessionOutput = {
|
|
10
|
+
columns?: number;
|
|
11
|
+
rows?: number;
|
|
12
|
+
write(text: string): unknown;
|
|
13
|
+
on(event: "resize", listener: () => void): unknown;
|
|
14
|
+
off(event: "resize", listener: () => void): unknown;
|
|
15
|
+
};
|
|
16
|
+
export type SessionOptions = {
|
|
17
|
+
interactive: boolean;
|
|
18
|
+
/** false keeps the screen model but never draws predicted keystrokes. */
|
|
19
|
+
predict?: boolean;
|
|
20
|
+
/** Where a non-interactive session reports a drop (stderr). */
|
|
21
|
+
log?: (text: string) => void;
|
|
22
|
+
now?: () => number;
|
|
23
|
+
};
|
|
24
|
+
export declare const KITTY_KEYBOARD_PUSH = "\u001B[>5u";
|
|
25
|
+
export declare const KITTY_KEYBOARD_POP = "\u001B[<u";
|
|
26
|
+
export declare function containsCtrlC(data: Buffer): boolean;
|
|
27
|
+
export declare class AttachSession {
|
|
28
|
+
/** Sent as `?client=`: the relay lets this terminal take its own place back. */
|
|
29
|
+
readonly clientId: `${string}-${string}-${string}-${string}-${string}`;
|
|
30
|
+
readonly interactive: boolean;
|
|
31
|
+
/** The cloud's screen as last drawn (and predictive echo on top of it). */
|
|
32
|
+
readonly predictor: EchoPredictor | null;
|
|
33
|
+
/** Connections that reached `open`. */
|
|
34
|
+
connections: number;
|
|
35
|
+
/** The cloud has drawn on this terminal: a reconnect resumes that picture. */
|
|
36
|
+
drewFrame: boolean;
|
|
37
|
+
hasLeft: boolean;
|
|
38
|
+
private readonly input;
|
|
39
|
+
private readonly output;
|
|
40
|
+
private readonly label;
|
|
41
|
+
private readonly log;
|
|
42
|
+
private readonly now;
|
|
43
|
+
private held;
|
|
44
|
+
private released;
|
|
45
|
+
private inGap;
|
|
46
|
+
private status;
|
|
47
|
+
private badge;
|
|
48
|
+
private queued;
|
|
49
|
+
private queuedBytes;
|
|
50
|
+
private lastCtrlC;
|
|
51
|
+
private leaveListeners;
|
|
52
|
+
constructor(label: string, input: SessionInput, output: SessionOutput, options: SessionOptions);
|
|
53
|
+
/** Take the terminal: alternate screen, raw keys, mouse and keyboard flags. */
|
|
54
|
+
hold(): void;
|
|
55
|
+
/** Give the terminal back exactly once, whatever state it is in. */
|
|
56
|
+
release(): void;
|
|
57
|
+
/**
|
|
58
|
+
* The link dropped and a reconnect follows. The screen stays as it was, a
|
|
59
|
+
* badge says what is happening, and keys are kept for the next connection.
|
|
60
|
+
*/
|
|
61
|
+
enterGap(): void;
|
|
62
|
+
/** A retry is about to start; the badge counts them once it is slow. */
|
|
63
|
+
noteAttempt(attempt: number): void;
|
|
64
|
+
/** A connection opened: it reads the keys from here on. */
|
|
65
|
+
exitGap(): void;
|
|
66
|
+
/** Keys typed while the link was down, in order, for the new connection. */
|
|
67
|
+
takeQueued(): Buffer | null;
|
|
68
|
+
/** Wait out a retry delay; true if the user left meanwhile. */
|
|
69
|
+
wait(ms: number): Promise<boolean>;
|
|
70
|
+
onLeave(listener: () => void): () => void;
|
|
71
|
+
/**
|
|
72
|
+
* Ctrl+C while nothing on the other end can take it: the first press says
|
|
73
|
+
* how to leave, a second within a few seconds leaves. True when leaving.
|
|
74
|
+
*/
|
|
75
|
+
ctrlCToLeave(): boolean;
|
|
76
|
+
leave(): void;
|
|
77
|
+
/** A lasting state worth a badge (worker away, read-only, reconnecting). */
|
|
78
|
+
showStatus(text: string): void;
|
|
79
|
+
/** The state is over: take the badge off and repaint what it covered. */
|
|
80
|
+
clearStatus(): void;
|
|
81
|
+
get statusText(): string | null;
|
|
82
|
+
/** The terminal changed size while connected: redraw the badge to fit. */
|
|
83
|
+
noteResize(): void;
|
|
84
|
+
private onGapInput;
|
|
85
|
+
private onGapResize;
|
|
86
|
+
private stopGapInput;
|
|
87
|
+
private closeOpenSequence;
|
|
88
|
+
private drawBadge;
|
|
89
|
+
private eraseBadge;
|
|
90
|
+
private setTitle;
|
|
91
|
+
}
|