alpic 0.0.0-dev.ge9cb8ec → 0.0.0-dev.ge9d2c4f
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -0
- package/bin/dev.js +0 -0
- package/dist/__tests__/audit.e2e.test.js +1 -1
- package/dist/__tests__/audit.e2e.test.js.map +1 -1
- package/dist/__tests__/deployment-logs.e2e.test.js +0 -1
- package/dist/__tests__/deployment-logs.e2e.test.js.map +1 -1
- package/dist/__tests__/environment-delete.e2e.test.d.ts +1 -0
- package/dist/__tests__/environment-delete.e2e.test.js +95 -0
- package/dist/__tests__/environment-delete.e2e.test.js.map +1 -0
- package/dist/__tests__/git.e2e.test.js +1 -1
- package/dist/__tests__/git.e2e.test.js.map +1 -1
- package/dist/__tests__/insights-category.e2e.test.d.ts +1 -0
- package/dist/__tests__/insights-category.e2e.test.js +247 -0
- package/dist/__tests__/insights-category.e2e.test.js.map +1 -0
- package/dist/__tests__/insights.e2e.test.d.ts +1 -0
- package/dist/__tests__/insights.e2e.test.js +193 -0
- package/dist/__tests__/insights.e2e.test.js.map +1 -0
- package/dist/__tests__/logs.e2e.test.js +0 -1
- package/dist/__tests__/logs.e2e.test.js.map +1 -1
- package/dist/__tests__/mock-api.d.ts +21 -0
- package/dist/__tests__/mock-api.js +375 -32
- package/dist/__tests__/mock-api.js.map +1 -1
- package/dist/__tests__/publish.e2e.test.js +1 -3
- package/dist/__tests__/publish.e2e.test.js.map +1 -1
- package/dist/__tests__/submission.e2e.test.d.ts +1 -0
- package/dist/__tests__/submission.e2e.test.js +173 -0
- package/dist/__tests__/submission.e2e.test.js.map +1 -0
- package/dist/__tests__/team-inspect.e2e.test.js +26 -1
- package/dist/__tests__/team-inspect.e2e.test.js.map +1 -1
- package/dist/__tests__/telemetry-destinations.e2e.test.d.ts +1 -0
- package/dist/__tests__/telemetry-destinations.e2e.test.js +105 -0
- package/dist/__tests__/telemetry-destinations.e2e.test.js.map +1 -0
- package/dist/__tests__/tunnel.e2e.test.js +69 -22
- package/dist/__tests__/tunnel.e2e.test.js.map +1 -1
- package/dist/__tests__/utils.d.ts +5 -11
- package/dist/__tests__/utils.js +20 -23
- package/dist/__tests__/utils.js.map +1 -1
- package/dist/commands/audit.js +3 -1
- package/dist/commands/audit.js.map +1 -1
- package/dist/commands/deploy.js +12 -11
- package/dist/commands/deploy.js.map +1 -1
- package/dist/commands/deployment/list.js +3 -3
- package/dist/commands/deployment/list.js.map +1 -1
- package/dist/commands/environment/delete.d.ts +13 -0
- package/dist/commands/environment/delete.js +45 -0
- package/dist/commands/environment/delete.js.map +1 -0
- package/dist/commands/environment/inspect.js +3 -3
- package/dist/commands/environment/inspect.js.map +1 -1
- package/dist/commands/environment/list.js +3 -3
- package/dist/commands/environment/list.js.map +1 -1
- package/dist/commands/insights/category/create.d.ts +17 -0
- package/dist/commands/insights/category/create.js +63 -0
- package/dist/commands/insights/category/create.js.map +1 -0
- package/dist/commands/insights/category/delete.d.ts +13 -0
- package/dist/commands/insights/category/delete.js +40 -0
- package/dist/commands/insights/category/delete.js.map +1 -0
- package/dist/commands/insights/category/link.d.ts +14 -0
- package/dist/commands/insights/category/link.js +36 -0
- package/dist/commands/insights/category/link.js.map +1 -0
- package/dist/commands/insights/category/list.d.ts +13 -0
- package/dist/commands/insights/category/list.js +46 -0
- package/dist/commands/insights/category/list.js.map +1 -0
- package/dist/commands/insights/category/unlink.d.ts +14 -0
- package/dist/commands/insights/category/unlink.js +36 -0
- package/dist/commands/insights/category/unlink.js.map +1 -0
- package/dist/commands/insights/category/update.d.ts +16 -0
- package/dist/commands/insights/category/update.js +45 -0
- package/dist/commands/insights/category/update.js.map +1 -0
- package/dist/commands/insights/feedback/list.d.ts +19 -0
- package/dist/commands/insights/feedback/list.js +73 -0
- package/dist/commands/insights/feedback/list.js.map +1 -0
- package/dist/commands/insights/intent/list.d.ts +22 -0
- package/dist/commands/insights/intent/list.js +89 -0
- package/dist/commands/insights/intent/list.js.map +1 -0
- package/dist/commands/link.js +4 -3
- package/dist/commands/link.js.map +1 -1
- package/dist/commands/logs.js +1 -9
- package/dist/commands/logs.js.map +1 -1
- package/dist/commands/project/inspect.js +3 -3
- package/dist/commands/project/inspect.js.map +1 -1
- package/dist/commands/project/list.js +3 -3
- package/dist/commands/project/list.js.map +1 -1
- package/dist/commands/submission/create.d.ts +15 -0
- package/dist/commands/submission/create.js +59 -0
- package/dist/commands/submission/create.js.map +1 -0
- package/dist/commands/submission/inspect.d.ts +10 -0
- package/dist/commands/submission/inspect.js +56 -0
- package/dist/commands/submission/inspect.js.map +1 -0
- package/dist/commands/submission/list.d.ts +13 -0
- package/dist/commands/submission/list.js +63 -0
- package/dist/commands/submission/list.js.map +1 -0
- package/dist/commands/submission/update.d.ts +12 -0
- package/dist/commands/submission/update.js +37 -0
- package/dist/commands/submission/update.js.map +1 -0
- package/dist/commands/team/inspect.js +25 -10
- package/dist/commands/team/inspect.js.map +1 -1
- package/dist/commands/team/list.js +3 -3
- package/dist/commands/team/list.js.map +1 -1
- package/dist/commands/telemetry/destinations/create.d.ts +19 -0
- package/dist/commands/telemetry/destinations/create.js +57 -0
- package/dist/commands/telemetry/destinations/create.js.map +1 -0
- package/dist/commands/telemetry/destinations/delete.d.ts +13 -0
- package/dist/commands/telemetry/destinations/delete.js +27 -0
- package/dist/commands/telemetry/destinations/delete.js.map +1 -0
- package/dist/commands/telemetry/destinations/list.d.ts +13 -0
- package/dist/commands/telemetry/destinations/list.js +48 -0
- package/dist/commands/telemetry/destinations/list.js.map +1 -0
- package/dist/commands/telemetry/destinations/update.d.ts +20 -0
- package/dist/commands/telemetry/destinations/update.js +62 -0
- package/dist/commands/telemetry/destinations/update.js.map +1 -0
- package/dist/commands/tunnel.js +7 -11
- package/dist/commands/tunnel.js.map +1 -1
- package/dist/lib/agent-mode.d.ts +8 -1
- package/dist/lib/agent-mode.js +25 -26
- package/dist/lib/agent-mode.js.map +1 -1
- package/dist/lib/alpic-command.d.ts +2 -1
- package/dist/lib/alpic-command.js +3 -3
- package/dist/lib/alpic-command.js.map +1 -1
- package/dist/lib/alpic-sdk.js +1 -2
- package/dist/lib/alpic-sdk.js.map +1 -1
- package/dist/lib/audit.d.ts +1 -0
- package/dist/lib/audit.js +22 -13
- package/dist/lib/audit.js.map +1 -1
- package/dist/lib/base-workflow.d.ts +2 -1
- package/dist/lib/base-workflow.js +3 -3
- package/dist/lib/base-workflow.js.map +1 -1
- package/dist/lib/deployment.js +12 -12
- package/dist/lib/deployment.js.map +1 -1
- package/dist/lib/environment-variable.js +14 -13
- package/dist/lib/environment-variable.js.map +1 -1
- package/dist/lib/insights.d.ts +19 -0
- package/dist/lib/insights.js +54 -0
- package/dist/lib/insights.js.map +1 -0
- package/dist/lib/link.js +5 -4
- package/dist/lib/link.js.map +1 -1
- package/dist/lib/logs.js +1 -0
- package/dist/lib/logs.js.map +1 -1
- package/dist/lib/playground.js +25 -25
- package/dist/lib/playground.js.map +1 -1
- package/dist/lib/project-settings.js +1 -9
- package/dist/lib/project-settings.js.map +1 -1
- package/dist/lib/publish.js +3 -3
- package/dist/lib/publish.js.map +1 -1
- package/dist/lib/resolve.d.ts +7 -6
- package/dist/lib/resolve.js +23 -19
- package/dist/lib/resolve.js.map +1 -1
- package/dist/lib/submission.d.ts +13 -0
- package/dist/lib/submission.js +52 -0
- package/dist/lib/submission.js.map +1 -0
- package/dist/lib/telemetry-destinations.d.ts +9 -0
- package/dist/lib/telemetry-destinations.js +22 -0
- package/dist/lib/telemetry-destinations.js.map +1 -0
- package/dist/lib/telemetry-destinations.test.d.ts +1 -0
- package/dist/lib/telemetry-destinations.test.js +14 -0
- package/dist/lib/telemetry-destinations.test.js.map +1 -0
- package/dist/lib/telemetry.d.ts +1 -1
- package/dist/lib/telemetry.js +20 -19
- package/dist/lib/telemetry.js.map +1 -1
- package/dist/lib/telemetry.test.d.ts +1 -0
- package/dist/lib/telemetry.test.js +136 -0
- package/dist/lib/telemetry.test.js.map +1 -0
- package/dist/lib/utils.d.ts +8 -1
- package/dist/lib/utils.js +14 -1
- package/dist/lib/utils.js.map +1 -1
- package/dist/lib/utils.test.js +28 -5
- package/dist/lib/utils.test.js.map +1 -1
- package/dist/sentry.js +3 -6
- package/dist/sentry.js.map +1 -1
- package/package.json +25 -24
package/dist/lib/resolve.js
CHANGED
|
@@ -2,7 +2,7 @@ import * as p from "@clack/prompts";
|
|
|
2
2
|
import { Flags } from "@oclif/core";
|
|
3
3
|
import chalk from "chalk";
|
|
4
4
|
import { api } from "../api.js";
|
|
5
|
-
import {
|
|
5
|
+
import { createLogger, ERRORS_ONLY, isAgentMode } from "./agent-mode.js";
|
|
6
6
|
import { alpic } from "./alpic-sdk.js";
|
|
7
7
|
export const projectFlags = {
|
|
8
8
|
"project-id": Flags.string({ description: "The ID of the project", exclusive: ["project-name"] }),
|
|
@@ -12,15 +12,20 @@ export const environmentFlags = {
|
|
|
12
12
|
"environment-id": Flags.string({ description: "The ID of the environment", exclusive: ["environment-name"] }),
|
|
13
13
|
"environment-name": Flags.string({ description: "The name of the environment", exclusive: ["environment-id"] }),
|
|
14
14
|
};
|
|
15
|
+
const info = (options, message) => {
|
|
16
|
+
if (!options.silent) {
|
|
17
|
+
p.log.info(message);
|
|
18
|
+
}
|
|
19
|
+
};
|
|
15
20
|
export const resolveProjectId = async (flags, options = {}) => {
|
|
16
21
|
if (flags["project-id"]) {
|
|
17
22
|
return flags["project-id"];
|
|
18
23
|
}
|
|
19
24
|
if (flags["project-name"]) {
|
|
20
|
-
const
|
|
21
|
-
|
|
25
|
+
const logger = createLogger(options.silent ? ERRORS_ONLY : "all");
|
|
26
|
+
logger.start("Resolving project by name...");
|
|
22
27
|
const projects = await api.projects.list.v1();
|
|
23
|
-
|
|
28
|
+
logger.stop("");
|
|
24
29
|
const matches = projects.filter((project) => project.name === flags["project-name"]);
|
|
25
30
|
if (matches.length === 0) {
|
|
26
31
|
throw new Error(`No project found with name "${flags["project-name"]}".`);
|
|
@@ -32,23 +37,23 @@ export const resolveProjectId = async (flags, options = {}) => {
|
|
|
32
37
|
if (!project) {
|
|
33
38
|
throw new Error(`No project found with name "${flags["project-name"]}".`);
|
|
34
39
|
}
|
|
35
|
-
|
|
40
|
+
info(options, `Resolved project "${project.name}" ${chalk.dim(`(${project.id})`)}`);
|
|
36
41
|
return project.id;
|
|
37
42
|
}
|
|
38
43
|
if (!options.skipLocalConfig) {
|
|
39
44
|
const projectId = alpic.projects.loadConfig()?.projectId;
|
|
40
45
|
if (projectId !== undefined) {
|
|
41
|
-
|
|
46
|
+
info(options, `Using project id from .alpic config: ${chalk.bold(projectId)}`);
|
|
42
47
|
return projectId;
|
|
43
48
|
}
|
|
44
49
|
}
|
|
45
50
|
if (flags["non-interactive"] || isAgentMode()) {
|
|
46
51
|
throw new Error("No project specified. Use --project-id or --project-name.");
|
|
47
52
|
}
|
|
48
|
-
const
|
|
49
|
-
|
|
53
|
+
const logger = createLogger(options.silent ? ERRORS_ONLY : "all");
|
|
54
|
+
logger.start("Fetching projects...");
|
|
50
55
|
const projects = await api.projects.list.v1();
|
|
51
|
-
|
|
56
|
+
logger.stop("");
|
|
52
57
|
if (projects.length === 0) {
|
|
53
58
|
throw new Error("No projects found.");
|
|
54
59
|
}
|
|
@@ -67,10 +72,9 @@ export const resolveEnvironmentId = async (flags, options = {}) => {
|
|
|
67
72
|
return flags["environment-id"];
|
|
68
73
|
}
|
|
69
74
|
if (flags["environment-name"]) {
|
|
70
|
-
// Resolve project context — needed to look up environment by name
|
|
71
75
|
let projectId = flags["project-id"];
|
|
72
76
|
if (!projectId && flags["project-name"]) {
|
|
73
|
-
projectId = await resolveProjectId({ "project-name": flags["project-name"], "non-interactive": flags["non-interactive"] },
|
|
77
|
+
projectId = await resolveProjectId({ "project-name": flags["project-name"], "non-interactive": flags["non-interactive"] }, options);
|
|
74
78
|
}
|
|
75
79
|
if (!projectId && !options.skipLocalConfig) {
|
|
76
80
|
projectId = alpic.projects.loadConfig()?.projectId;
|
|
@@ -78,23 +82,23 @@ export const resolveEnvironmentId = async (flags, options = {}) => {
|
|
|
78
82
|
if (!projectId) {
|
|
79
83
|
throw new Error("Cannot resolve --environment-name without a project context. Use --environment-id directly, or provide --project-id or --project-name.");
|
|
80
84
|
}
|
|
81
|
-
const
|
|
82
|
-
|
|
85
|
+
const logger = createLogger(options.silent ? ERRORS_ONLY : "all");
|
|
86
|
+
logger.start("Resolving environment by name...");
|
|
83
87
|
const project = await api.projects.get.v1({ projectId });
|
|
84
|
-
|
|
88
|
+
logger.stop("");
|
|
85
89
|
const match = project.environments.find((env) => env.name === flags["environment-name"]);
|
|
86
90
|
if (!match) {
|
|
87
91
|
const identifier = flags["project-name"] ?? projectId;
|
|
88
92
|
throw new Error(`No environment found with name "${flags["environment-name"]}" in project "${identifier}".`);
|
|
89
93
|
}
|
|
90
|
-
|
|
94
|
+
info(options, `Resolved environment "${match.name}" ${chalk.dim(`(${match.id})`)}`);
|
|
91
95
|
return match.id;
|
|
92
96
|
}
|
|
93
97
|
if (!options.skipLocalConfig) {
|
|
94
98
|
const localConfig = alpic.projects.loadConfig();
|
|
95
99
|
const environmentId = localConfig?.environmentId;
|
|
96
100
|
if (environmentId !== undefined) {
|
|
97
|
-
|
|
101
|
+
info(options, `Using environment id from .alpic config: ${chalk.bold(environmentId)}`);
|
|
98
102
|
return environmentId;
|
|
99
103
|
}
|
|
100
104
|
}
|
|
@@ -102,10 +106,10 @@ export const resolveEnvironmentId = async (flags, options = {}) => {
|
|
|
102
106
|
throw new Error("No environment specified. Use --environment-id.");
|
|
103
107
|
}
|
|
104
108
|
const projectId = await resolveProjectId(flags, options);
|
|
105
|
-
const
|
|
106
|
-
|
|
109
|
+
const logger = createLogger(options.silent ? ERRORS_ONLY : "all");
|
|
110
|
+
logger.start("Fetching environments...");
|
|
107
111
|
const project = await api.projects.get.v1({ projectId });
|
|
108
|
-
|
|
112
|
+
logger.stop("");
|
|
109
113
|
if (project.environments.length === 0) {
|
|
110
114
|
throw new Error("No environments found in this project.");
|
|
111
115
|
}
|
package/dist/lib/resolve.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resolve.js","sourceRoot":"","sources":["../../src/lib/resolve.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,gBAAgB,CAAC;AACpC,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AACpC,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,GAAG,EAAE,MAAM,WAAW,CAAC;AAChC,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"resolve.js","sourceRoot":"","sources":["../../src/lib/resolve.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export declare const parsePlatform: (platform: string) => "chatgpt" | "claudeai";
|
|
2
|
+
export declare const submissionFlags: {
|
|
3
|
+
"submission-id": import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
4
|
+
};
|
|
5
|
+
export declare const formDataFlags: {
|
|
6
|
+
"form-data": import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
7
|
+
"form-data-file": import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
8
|
+
};
|
|
9
|
+
export declare const readFormData: (flags: {
|
|
10
|
+
"form-data"?: string;
|
|
11
|
+
"form-data-file"?: string;
|
|
12
|
+
}) => object;
|
|
13
|
+
export declare const formatFormDataValue: (value: unknown) => string;
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { readFileSync } from "node:fs";
|
|
2
|
+
import { AI_PLATFORMS } from "@alpic-ai/api";
|
|
3
|
+
import { Flags } from "@oclif/core";
|
|
4
|
+
const MAX_FIELD_VALUE_LENGTH = 80;
|
|
5
|
+
const STDIN_FILE_DESCRIPTOR = 0;
|
|
6
|
+
export const parsePlatform = (platform) => {
|
|
7
|
+
const match = AI_PLATFORMS.find((candidate) => candidate === platform);
|
|
8
|
+
if (match === undefined) {
|
|
9
|
+
throw new Error(`Invalid platform: ${platform}`);
|
|
10
|
+
}
|
|
11
|
+
return match;
|
|
12
|
+
};
|
|
13
|
+
export const submissionFlags = {
|
|
14
|
+
"submission-id": Flags.string({ description: "The ID of the submission package", required: true }),
|
|
15
|
+
};
|
|
16
|
+
export const formDataFlags = {
|
|
17
|
+
"form-data": Flags.string({
|
|
18
|
+
description: "The submission fields as a JSON object",
|
|
19
|
+
exclusive: ["form-data-file"],
|
|
20
|
+
}),
|
|
21
|
+
"form-data-file": Flags.string({
|
|
22
|
+
description: "Path to a JSON file holding the submission fields; use - to read stdin",
|
|
23
|
+
exclusive: ["form-data"],
|
|
24
|
+
}),
|
|
25
|
+
};
|
|
26
|
+
export const readFormData = (flags) => {
|
|
27
|
+
const source = flags["form-data-file"]
|
|
28
|
+
? readFileSync(flags["form-data-file"] === "-" ? STDIN_FILE_DESCRIPTOR : flags["form-data-file"], "utf8")
|
|
29
|
+
: flags["form-data"];
|
|
30
|
+
if (source === undefined) {
|
|
31
|
+
throw new Error("No form data provided. Use --form-data or --form-data-file.");
|
|
32
|
+
}
|
|
33
|
+
let parsed;
|
|
34
|
+
try {
|
|
35
|
+
parsed = JSON.parse(source);
|
|
36
|
+
}
|
|
37
|
+
catch (error) {
|
|
38
|
+
throw new Error(`Form data is not valid JSON: ${error instanceof Error ? error.message : String(error)}`);
|
|
39
|
+
}
|
|
40
|
+
if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
41
|
+
throw new Error("Form data must be a JSON object of submission fields.");
|
|
42
|
+
}
|
|
43
|
+
return parsed;
|
|
44
|
+
};
|
|
45
|
+
export const formatFormDataValue = (value) => {
|
|
46
|
+
if (value === null || value === undefined || value === "") {
|
|
47
|
+
return "-";
|
|
48
|
+
}
|
|
49
|
+
const formatted = typeof value === "string" ? value : JSON.stringify(value);
|
|
50
|
+
return formatted.length <= MAX_FIELD_VALUE_LENGTH ? formatted : `${formatted.slice(0, MAX_FIELD_VALUE_LENGTH - 1)}…`;
|
|
51
|
+
};
|
|
52
|
+
//# sourceMappingURL=submission.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"submission.js","sourceRoot":"","sources":["../../src/lib/submission.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { RouterOutput } from "@alpic-ai/api";
|
|
2
|
+
type TelemetryDestination = RouterOutput["telemetryDestinations"]["list"]["v1"][number];
|
|
3
|
+
export declare function parseTelemetryHeaders(headers?: string[], secretHeaders?: string[]): {
|
|
4
|
+
name: string;
|
|
5
|
+
value: string;
|
|
6
|
+
isSecret: boolean;
|
|
7
|
+
}[];
|
|
8
|
+
export declare function formatTelemetryHeaders(headers: TelemetryDestination["headers"]): string;
|
|
9
|
+
export {};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { UserInputError } from "@alpic-ai/sdk";
|
|
2
|
+
export function parseTelemetryHeaders(headers = [], secretHeaders = []) {
|
|
3
|
+
return [
|
|
4
|
+
...headers.map((header) => parseTelemetryHeader(header, false)),
|
|
5
|
+
...secretHeaders.map((header) => parseTelemetryHeader(header, true)),
|
|
6
|
+
];
|
|
7
|
+
}
|
|
8
|
+
export function formatTelemetryHeaders(headers) {
|
|
9
|
+
return headers.map((header) => `${header.name}=${header.isSecret ? "<secret>" : header.value}`).join(", ");
|
|
10
|
+
}
|
|
11
|
+
function parseTelemetryHeader(header, isSecret) {
|
|
12
|
+
const separatorIndex = header.indexOf("=");
|
|
13
|
+
if (separatorIndex <= 0 || separatorIndex === header.length - 1) {
|
|
14
|
+
throw new UserInputError(`Invalid header "${header}". Use NAME=VALUE.`);
|
|
15
|
+
}
|
|
16
|
+
return {
|
|
17
|
+
name: header.slice(0, separatorIndex),
|
|
18
|
+
value: header.slice(separatorIndex + 1),
|
|
19
|
+
isSecret,
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=telemetry-destinations.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"telemetry-destinations.js","sourceRoot":"","sources":["../../src/lib/telemetry-destinations.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAI/C,MAAM,UAAU,qBAAqB,CAAC,UAAoB,EAAE,EAAE,gBAA0B,EAAE;IACxF,OAAO;QACL,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,oBAAoB,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;QAC/D,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,oBAAoB,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;KACrE,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,sBAAsB,CAAC,OAAwC;IAC7E,OAAO,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,GAAG,MAAM,CAAC,IAAI,IAAI,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC7G,CAAC;AAED,SAAS,oBAAoB,CAAC,MAAc,EAAE,QAAiB;IAC7D,MAAM,cAAc,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IAC3C,IAAI,cAAc,IAAI,CAAC,IAAI,cAAc,KAAK,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAChE,MAAM,IAAI,cAAc,CAAC,mBAAmB,MAAM,oBAAoB,CAAC,CAAC;IAC1E,CAAC;IAED,OAAO;QACL,IAAI,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,cAAc,CAAC;QACrC,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,cAAc,GAAG,CAAC,CAAC;QACvC,QAAQ;KACT,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
import { parseTelemetryHeaders } from "./telemetry-destinations.js";
|
|
3
|
+
describe("parseTelemetryHeaders", () => {
|
|
4
|
+
it("preserves equals signs in header values", () => {
|
|
5
|
+
expect(parseTelemetryHeaders(["X-Token=part=two"], ["Authorization=Bearer secret"])).toEqual([
|
|
6
|
+
{ name: "X-Token", value: "part=two", isSecret: false },
|
|
7
|
+
{ name: "Authorization", value: "Bearer secret", isSecret: true },
|
|
8
|
+
]);
|
|
9
|
+
});
|
|
10
|
+
it.each(["missing-separator", "=missing-name", "missing-value="])("rejects malformed header %s", (header) => {
|
|
11
|
+
expect(() => parseTelemetryHeaders([header])).toThrow(`Invalid header "${header}". Use NAME=VALUE.`);
|
|
12
|
+
});
|
|
13
|
+
});
|
|
14
|
+
//# sourceMappingURL=telemetry-destinations.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"telemetry-destinations.test.js","sourceRoot":"","sources":["../../src/lib/telemetry-destinations.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,qBAAqB,EAAE,MAAM,6BAA6B,CAAC;AAEpE,QAAQ,CAAC,uBAAuB,EAAE,GAAG,EAAE;IACrC,EAAE,CAAC,yCAAyC,EAAE,GAAG,EAAE;QACjD,MAAM,CAAC,qBAAqB,CAAC,CAAC,kBAAkB,CAAC,EAAE,CAAC,6BAA6B,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;YAC3F,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,UAAU,EAAE,QAAQ,EAAE,KAAK,EAAE;YACvD,EAAE,IAAI,EAAE,eAAe,EAAE,KAAK,EAAE,eAAe,EAAE,QAAQ,EAAE,IAAI,EAAE;SAClE,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,IAAI,CAAC,CAAC,mBAAmB,EAAE,eAAe,EAAE,gBAAgB,CAAC,CAAC,CAAC,6BAA6B,EAAE,CAAC,MAAM,EAAE,EAAE;QAC1G,MAAM,CAAC,GAAG,EAAE,CAAC,qBAAqB,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,mBAAmB,MAAM,oBAAoB,CAAC,CAAC;IACvG,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
package/dist/lib/telemetry.d.ts
CHANGED
package/dist/lib/telemetry.js
CHANGED
|
@@ -1,18 +1,16 @@
|
|
|
1
1
|
import crypto from "node:crypto";
|
|
2
|
-
import { globalStore } from "@alpic-ai/sdk";
|
|
2
|
+
import { globalStore, UserInputError } from "@alpic-ai/sdk";
|
|
3
|
+
import { Errors } from "@oclif/core";
|
|
3
4
|
import { ORPCError } from "@orpc/client";
|
|
4
5
|
import ci from "ci-info";
|
|
6
|
+
import { agent } from "std-env";
|
|
5
7
|
import posthog from "../posthog.js";
|
|
6
8
|
import { initSentry, Sentry } from "../sentry.js";
|
|
7
9
|
import { getResponseErrorStatus } from "./utils.js";
|
|
8
10
|
const ENV_TELEMETRY_DISABLED = "ALPIC_TELEMETRY_DISABLED";
|
|
9
11
|
const ENV_TELEMETRY_DEBUG = "ALPIC_TELEMETRY_DEBUG";
|
|
10
12
|
const ENV_DO_NOT_TRACK = "DO_NOT_TRACK";
|
|
11
|
-
//
|
|
12
|
-
// "EEXIT: 1". AlpicCommand.exitWithErrorMessage attaches the original error
|
|
13
|
-
// as `cause` before throwing. That cause may be a non-Error value (e.g. a
|
|
14
|
-
// string or plain object thrown by a third-party lib), so we return `unknown`
|
|
15
|
-
// and let callers pick a representation.
|
|
13
|
+
// Unwraps oclif's ExitError (AlpicCommand.exitWithErrorMessage attaches the original error as `cause`) so we report the real failure instead of "EEXIT: 1"; the cause may be a non-Error value, hence `unknown`.
|
|
16
14
|
function unwrapError(error) {
|
|
17
15
|
if (!error) {
|
|
18
16
|
return undefined;
|
|
@@ -36,7 +34,14 @@ function getErrorMessage(error) {
|
|
|
36
34
|
return String(error).trim();
|
|
37
35
|
}
|
|
38
36
|
}
|
|
39
|
-
function
|
|
37
|
+
function isOclifParseError(error) {
|
|
38
|
+
// CLIParseError is unexported (`parse` marks it); InvalidArgsSpecError is a broken command definition and stays reportable.
|
|
39
|
+
return error instanceof Errors.CLIError && "parse" in error && error.constructor.name !== "InvalidArgsSpecError";
|
|
40
|
+
}
|
|
41
|
+
function shouldSkipSentryCapture(error) {
|
|
42
|
+
if (error instanceof UserInputError || isOclifParseError(error)) {
|
|
43
|
+
return true;
|
|
44
|
+
}
|
|
40
45
|
if (error instanceof ORPCError) {
|
|
41
46
|
return error.status === 401 || error.status === 403 || error.code === "UNAUTHORIZED" || error.code === "FORBIDDEN";
|
|
42
47
|
}
|
|
@@ -52,9 +57,7 @@ async function captureToPosthog(event) {
|
|
|
52
57
|
});
|
|
53
58
|
await posthog.shutdown(2000);
|
|
54
59
|
}
|
|
55
|
-
catch {
|
|
56
|
-
// no-op
|
|
57
|
-
}
|
|
60
|
+
catch { }
|
|
58
61
|
}
|
|
59
62
|
async function captureToSentry(error, event) {
|
|
60
63
|
try {
|
|
@@ -67,14 +70,13 @@ async function captureToSentry(error, event) {
|
|
|
67
70
|
platform: event.platform,
|
|
68
71
|
nodeVersion: event.nodeVersion,
|
|
69
72
|
isCI: String(event.isCI),
|
|
73
|
+
agent: event.agent,
|
|
70
74
|
},
|
|
71
75
|
extra: { sessionId: event.sessionId },
|
|
72
76
|
});
|
|
73
77
|
await Sentry.flush(2000);
|
|
74
78
|
}
|
|
75
|
-
catch {
|
|
76
|
-
// no-op
|
|
77
|
-
}
|
|
79
|
+
catch { }
|
|
78
80
|
}
|
|
79
81
|
export function isEnabled() {
|
|
80
82
|
if (process.env[ENV_TELEMETRY_DISABLED] === "1" || process.env[ENV_TELEMETRY_DISABLED]?.toLowerCase() === "true") {
|
|
@@ -119,9 +121,7 @@ export async function aliasMachineToUser(userId) {
|
|
|
119
121
|
});
|
|
120
122
|
await posthog.flush();
|
|
121
123
|
}
|
|
122
|
-
catch {
|
|
123
|
-
// Silently ignore telemetry errors - never block CLI operation
|
|
124
|
-
}
|
|
124
|
+
catch { }
|
|
125
125
|
}
|
|
126
126
|
const hook = async ({ id: command, config: { version }, error, }) => {
|
|
127
127
|
if (!isEnabled()) {
|
|
@@ -134,6 +134,7 @@ const hook = async ({ id: command, config: { version }, error, }) => {
|
|
|
134
134
|
machineId: getMachineId(),
|
|
135
135
|
sessionId: crypto.randomUUID(),
|
|
136
136
|
isCI: ci.isCI,
|
|
137
|
+
agent,
|
|
137
138
|
nodeVersion: process.version,
|
|
138
139
|
platform: process.platform,
|
|
139
140
|
outcome: error ? "failure" : "success",
|
|
@@ -143,8 +144,8 @@ const hook = async ({ id: command, config: { version }, error, }) => {
|
|
|
143
144
|
console.debug("[Telemetry Debug] Would send event:", JSON.stringify(event, null, 2));
|
|
144
145
|
if (rootError !== undefined && rootError !== null) {
|
|
145
146
|
const detail = rootError instanceof Error ? (rootError.stack ?? rootError.message) : rootError;
|
|
146
|
-
if (
|
|
147
|
-
console.debug("[Telemetry Debug] Would skip Sentry capture for
|
|
147
|
+
if (shouldSkipSentryCapture(rootError)) {
|
|
148
|
+
console.debug("[Telemetry Debug] Would skip Sentry capture for expected error:", detail);
|
|
148
149
|
}
|
|
149
150
|
else {
|
|
150
151
|
console.debug("[Telemetry Debug] Would send exception to Sentry:", detail);
|
|
@@ -153,7 +154,7 @@ const hook = async ({ id: command, config: { version }, error, }) => {
|
|
|
153
154
|
return;
|
|
154
155
|
}
|
|
155
156
|
const promises = [captureToPosthog(event)];
|
|
156
|
-
if (rootError !== undefined && rootError !== null && !
|
|
157
|
+
if (rootError !== undefined && rootError !== null && !shouldSkipSentryCapture(rootError)) {
|
|
157
158
|
promises.push(captureToSentry(rootError, event));
|
|
158
159
|
}
|
|
159
160
|
await Promise.allSettled(promises);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"telemetry.js","sourceRoot":"","sources":["../../src/lib/telemetry.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,aAAa,CAAC;AACjC,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"telemetry.js","sourceRoot":"","sources":["../../src/lib/telemetry.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import { UserInputError } from "@alpic-ai/sdk";
|
|
2
|
+
import { Args, Errors, Flags, Parser } from "@oclif/core";
|
|
3
|
+
import { beforeEach, describe, expect, it, vi } from "vitest";
|
|
4
|
+
import { parseTelemetryHeaders } from "./telemetry-destinations.js";
|
|
5
|
+
const capture = vi.fn();
|
|
6
|
+
const captureException = vi.fn();
|
|
7
|
+
vi.mock("../sentry.js", () => ({
|
|
8
|
+
initSentry: vi.fn(),
|
|
9
|
+
Sentry: {
|
|
10
|
+
captureException: (...args) => captureException(...args),
|
|
11
|
+
flush: () => Promise.resolve(true),
|
|
12
|
+
},
|
|
13
|
+
}));
|
|
14
|
+
vi.mock("../posthog.js", () => ({
|
|
15
|
+
default: {
|
|
16
|
+
capture: (...args) => capture(...args),
|
|
17
|
+
shutdown: () => Promise.resolve(undefined),
|
|
18
|
+
},
|
|
19
|
+
}));
|
|
20
|
+
vi.mock("ci-info", () => ({
|
|
21
|
+
default: { isCI: true, name: "test-ci" },
|
|
22
|
+
}));
|
|
23
|
+
const { default: hook } = await import("./telemetry.js");
|
|
24
|
+
async function parserFailure(argv, options = {}) {
|
|
25
|
+
try {
|
|
26
|
+
await Parser.parse(argv, options);
|
|
27
|
+
}
|
|
28
|
+
catch (error) {
|
|
29
|
+
if (error instanceof Error) {
|
|
30
|
+
return error;
|
|
31
|
+
}
|
|
32
|
+
throw error;
|
|
33
|
+
}
|
|
34
|
+
throw new Error(`expected parsing ${JSON.stringify(argv)} to fail`);
|
|
35
|
+
}
|
|
36
|
+
function exitWith(cause) {
|
|
37
|
+
const exitError = new Errors.ExitError(1);
|
|
38
|
+
exitError.cause = cause;
|
|
39
|
+
return exitError;
|
|
40
|
+
}
|
|
41
|
+
async function runHook(error) {
|
|
42
|
+
const run = hook;
|
|
43
|
+
await run({
|
|
44
|
+
id: "login",
|
|
45
|
+
config: { version: "1.158.0" },
|
|
46
|
+
error,
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
describe("telemetry Sentry capture", () => {
|
|
50
|
+
beforeEach(() => {
|
|
51
|
+
vi.clearAllMocks();
|
|
52
|
+
});
|
|
53
|
+
it("skips a nonexistent flag, including when oclif rethrows it as ExitError", async () => {
|
|
54
|
+
const error = await parserFailure(["--api-key", "secret"]);
|
|
55
|
+
expect(error.constructor.name).toBe("NonExistentFlagsError");
|
|
56
|
+
expect(error.message).toContain("Nonexistent flag: --api-key");
|
|
57
|
+
await runHook(error);
|
|
58
|
+
await runHook(exitWith(error));
|
|
59
|
+
expect(captureException).not.toHaveBeenCalled();
|
|
60
|
+
expect(capture).toHaveBeenCalledWith(expect.objectContaining({
|
|
61
|
+
event: "login",
|
|
62
|
+
properties: expect.objectContaining({
|
|
63
|
+
outcome: "failure",
|
|
64
|
+
error: expect.stringContaining("Nonexistent flag: --api-key"),
|
|
65
|
+
}),
|
|
66
|
+
}));
|
|
67
|
+
});
|
|
68
|
+
it("skips an unexpected argument", async () => {
|
|
69
|
+
const error = await parserFailure(["extra"]);
|
|
70
|
+
expect(error.constructor.name).toBe("UnexpectedArgsError");
|
|
71
|
+
await runHook(exitWith(error));
|
|
72
|
+
expect(captureException).not.toHaveBeenCalled();
|
|
73
|
+
});
|
|
74
|
+
it("skips a missing required argument", async () => {
|
|
75
|
+
const error = await parserFailure([], {
|
|
76
|
+
args: { name: Args.string({ required: true, description: "project name" }) },
|
|
77
|
+
});
|
|
78
|
+
expect(error.constructor.name).toBe("RequiredArgsError");
|
|
79
|
+
expect(error.message).toContain("Missing 1 required arg");
|
|
80
|
+
await runHook(exitWith(error));
|
|
81
|
+
expect(captureException).not.toHaveBeenCalled();
|
|
82
|
+
});
|
|
83
|
+
it("skips other user parser failures such as an invalid flag value", async () => {
|
|
84
|
+
const error = await parserFailure(["--color", "purple"], {
|
|
85
|
+
flags: { color: Flags.string({ options: ["red", "blue"] }) },
|
|
86
|
+
});
|
|
87
|
+
expect(error.constructor.name).toBe("FlagInvalidOptionError");
|
|
88
|
+
await runHook(exitWith(error));
|
|
89
|
+
expect(captureException).not.toHaveBeenCalled();
|
|
90
|
+
});
|
|
91
|
+
it.each([false, true])("skips a malformed telemetry header (secret: %s)", async (isSecret) => {
|
|
92
|
+
let error;
|
|
93
|
+
try {
|
|
94
|
+
parseTelemetryHeaders(isSecret ? [] : ["not-a-header"], isSecret ? ["not-a-header"] : []);
|
|
95
|
+
}
|
|
96
|
+
catch (caught) {
|
|
97
|
+
error = caught;
|
|
98
|
+
}
|
|
99
|
+
expect(error).toBeInstanceOf(UserInputError);
|
|
100
|
+
if (!(error instanceof Error)) {
|
|
101
|
+
throw new Error("Expected malformed telemetry header to fail");
|
|
102
|
+
}
|
|
103
|
+
expect(error.message).toBe('Invalid header "not-a-header". Use NAME=VALUE.');
|
|
104
|
+
await runHook(exitWith(error));
|
|
105
|
+
expect(captureException).not.toHaveBeenCalled();
|
|
106
|
+
expect(capture).toHaveBeenCalledWith(expect.objectContaining({
|
|
107
|
+
properties: expect.objectContaining({ outcome: "failure", error: error.message }),
|
|
108
|
+
}));
|
|
109
|
+
});
|
|
110
|
+
it("still captures a broken argument spec", async () => {
|
|
111
|
+
const error = await parserFailure([], {
|
|
112
|
+
args: {
|
|
113
|
+
optional: Args.string({ required: false }),
|
|
114
|
+
required: Args.string({ required: true }),
|
|
115
|
+
},
|
|
116
|
+
});
|
|
117
|
+
expect(error.constructor.name).toBe("InvalidArgsSpecError");
|
|
118
|
+
await runHook(exitWith(error));
|
|
119
|
+
expect(captureException).toHaveBeenCalledWith(error, expect.anything());
|
|
120
|
+
});
|
|
121
|
+
it("still captures a non-parse CLIError", async () => {
|
|
122
|
+
const error = await parserFailure(["--name", "a", "--name", "b"], {
|
|
123
|
+
flags: { name: Flags.string() },
|
|
124
|
+
});
|
|
125
|
+
expect(error).toBeInstanceOf(Errors.CLIError);
|
|
126
|
+
expect(error.constructor.name).toBe("CLIError");
|
|
127
|
+
await runHook(exitWith(error));
|
|
128
|
+
expect(captureException).toHaveBeenCalledWith(error, expect.anything());
|
|
129
|
+
});
|
|
130
|
+
it("still captures an unexpected failure", async () => {
|
|
131
|
+
const error = new Error("lambda exploded");
|
|
132
|
+
await runHook(exitWith(error));
|
|
133
|
+
expect(captureException).toHaveBeenCalledWith(error, expect.anything());
|
|
134
|
+
});
|
|
135
|
+
});
|
|
136
|
+
//# sourceMappingURL=telemetry.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"telemetry.test.js","sourceRoot":"","sources":["../../src/lib/telemetry.test.ts"],"names":[],"mappings":"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"}
|
package/dist/lib/utils.d.ts
CHANGED
|
@@ -35,5 +35,12 @@ export declare const formatAgo: (date: Date, options?: {
|
|
|
35
35
|
now?: Date;
|
|
36
36
|
}) => string;
|
|
37
37
|
export declare const plural: (count: number, word: string) => string;
|
|
38
|
+
export declare const formatUsage: ({ requestCount, includedRequests, periodEnd, now, }: {
|
|
39
|
+
requestCount: number;
|
|
40
|
+
includedRequests: number | null;
|
|
41
|
+
periodEnd: Date;
|
|
42
|
+
now?: Date;
|
|
43
|
+
}) => string;
|
|
38
44
|
export declare function getResponseErrorStatus(error: unknown): number | undefined;
|
|
39
|
-
export declare const
|
|
45
|
+
export declare const isValidTimeInput: (input: string) => boolean;
|
|
46
|
+
export declare function validateTimeFlag(value: string | undefined, flagName: string): void;
|
package/dist/lib/utils.js
CHANGED
|
@@ -52,6 +52,11 @@ export const formatAgo = (date, options = {}) => {
|
|
|
52
52
|
return rtf.format(value, unit);
|
|
53
53
|
};
|
|
54
54
|
export const plural = (count, word) => `${count} ${word}${count === 1 ? "" : "s"}`;
|
|
55
|
+
const numberFormatter = new Intl.NumberFormat("en-US");
|
|
56
|
+
export const formatUsage = ({ requestCount, includedRequests, periodEnd, now, }) => {
|
|
57
|
+
const allowance = includedRequests === null ? "" : ` / ${numberFormatter.format(includedRequests)}`;
|
|
58
|
+
return `${numberFormatter.format(requestCount)}${allowance} requests (resets ${formatAgo(periodEnd, { now })})`;
|
|
59
|
+
};
|
|
55
60
|
const errorStatusSchema = z.object({ status: z.number() });
|
|
56
61
|
const errorCauseStatusSchema = z.object({ cause: errorStatusSchema });
|
|
57
62
|
export function getResponseErrorStatus(error) {
|
|
@@ -66,5 +71,13 @@ export function getResponseErrorStatus(error) {
|
|
|
66
71
|
return undefined;
|
|
67
72
|
}
|
|
68
73
|
const RELATIVE_TIME_RE = /^\d+(\.\d+)?\s*(ms|s|m|h|d|w|y)$/i;
|
|
69
|
-
export const
|
|
74
|
+
export const isValidTimeInput = (input) => RELATIVE_TIME_RE.test(input) || z.iso.datetime().safeParse(input).success;
|
|
75
|
+
export function validateTimeFlag(value, flagName) {
|
|
76
|
+
if (value === undefined) {
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
if (!isValidTimeInput(value)) {
|
|
80
|
+
throw new Error(`Invalid --${flagName} value: "${value}". Use a relative duration (1h, 30m, 2d) or ISO 8601 date (2024-01-01T00:00:00Z).`);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
70
83
|
//# sourceMappingURL=utils.js.map
|