@pippit-dev/cli 0.0.26 → 0.0.28
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/checksums.txt +6 -6
- package/cmd/update/update.go +110 -0
- package/cmd/update/update_test.go +109 -0
- package/package.json +3 -2
- package/scripts/install-wizard.js +25 -6
- package/scripts/install.js +2 -0
- package/scripts/run.js +1 -1
- package/scripts/telemetry.js +83 -0
package/checksums.txt
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
1
|
+
91f6452453768a4af724e7f478c1d5834b117dfd57545eb28f79838bcefee72c pippit-tool-cli-0.0.28-darwin-amd64.tar.gz
|
|
2
|
+
72784be227214d5821793241ec19c0d41227cbcf1bf10b8d8a3675b8a1093219 pippit-tool-cli-0.0.28-darwin-arm64.tar.gz
|
|
3
|
+
1b7197befef5930b91816a1021a7ab66b9f3d95c0cbd5b0ba5fea20c1a7a1173 pippit-tool-cli-0.0.28-linux-amd64.tar.gz
|
|
4
|
+
2452ba5f9dc74b516af47e4e4620cfcc247ffe0b2d46a847681910442535f62b pippit-tool-cli-0.0.28-linux-arm64.tar.gz
|
|
5
|
+
bdb744c4e3cc57774c97148665ba99a6952fd4a1293902728e16a655544b20dc pippit-tool-cli-0.0.28-windows-amd64.zip
|
|
6
|
+
52e660a8b334067fa056021dcf68f1bb13a0385f6792a45b93277463cd583200 pippit-tool-cli-0.0.28-windows-arm64.zip
|
package/cmd/update/update.go
CHANGED
|
@@ -1,24 +1,44 @@
|
|
|
1
1
|
package updatecmd
|
|
2
2
|
|
|
3
3
|
import (
|
|
4
|
+
"bytes"
|
|
5
|
+
"encoding/json"
|
|
4
6
|
"fmt"
|
|
5
7
|
"io"
|
|
8
|
+
"net/http"
|
|
6
9
|
"os"
|
|
7
10
|
"os/exec"
|
|
8
11
|
"path/filepath"
|
|
9
12
|
"runtime"
|
|
10
13
|
"strings"
|
|
14
|
+
"sync"
|
|
15
|
+
"time"
|
|
11
16
|
|
|
17
|
+
"github.com/Pippit-dev/pippit-cli/internal/version"
|
|
12
18
|
"github.com/spf13/cobra"
|
|
13
19
|
)
|
|
14
20
|
|
|
15
21
|
const defaultPackage = "@pippit-dev/cli"
|
|
16
22
|
|
|
23
|
+
const (
|
|
24
|
+
defaultTelemetryBaseURL = "https://xyq.jianying.com"
|
|
25
|
+
telemetryPath = "/api/biz/v1/skill/report_telemetry"
|
|
26
|
+
telemetryAuthHeader = "Bearer pippit-cli-skill-telemetry"
|
|
27
|
+
telemetryWaitTimeout = time.Second
|
|
28
|
+
)
|
|
29
|
+
|
|
17
30
|
var legacyGlobalSkills = []string{
|
|
18
31
|
"pippit-short-drama-skill",
|
|
19
32
|
"xyq-nest-skill",
|
|
20
33
|
}
|
|
21
34
|
|
|
35
|
+
var telemetrySkillNames = []string{
|
|
36
|
+
"xyq-skill",
|
|
37
|
+
"xyq-short-drama-skill",
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
var telemetryHTTPClient = &http.Client{Timeout: telemetryWaitTimeout}
|
|
41
|
+
|
|
22
42
|
// NewCommand builds the update command.
|
|
23
43
|
func NewCommand(stdout, stderr io.Writer) *cobra.Command {
|
|
24
44
|
cmd := &cobra.Command{
|
|
@@ -57,6 +77,7 @@ func runUpdate(stdout, stderr io.Writer) error {
|
|
|
57
77
|
return fmt.Errorf("update pippit-tool-cli skills: %w", err)
|
|
58
78
|
}
|
|
59
79
|
|
|
80
|
+
reportBundledSkillTelemetry("update", "cli_update", stderr)
|
|
60
81
|
fmt.Fprintln(stdout, "pippit-tool-cli and skills updated")
|
|
61
82
|
return nil
|
|
62
83
|
}
|
|
@@ -105,6 +126,95 @@ func cleanupLegacyGlobalSkills(globalSkillsDir string) error {
|
|
|
105
126
|
return nil
|
|
106
127
|
}
|
|
107
128
|
|
|
129
|
+
type telemetryPayload struct {
|
|
130
|
+
Event string `json:"event"`
|
|
131
|
+
SkillName string `json:"skill_name"`
|
|
132
|
+
Source string `json:"source"`
|
|
133
|
+
CliVersion string `json:"cli_version"`
|
|
134
|
+
Platform string `json:"platform"`
|
|
135
|
+
Arch string `json:"arch"`
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
func reportBundledSkillTelemetry(event string, source string, stderr io.Writer) {
|
|
139
|
+
if os.Getenv("PIPPIT_CLI_DISABLE_TELEMETRY") == "1" {
|
|
140
|
+
return
|
|
141
|
+
}
|
|
142
|
+
var wg sync.WaitGroup
|
|
143
|
+
for _, skillName := range telemetrySkillNames {
|
|
144
|
+
payload := telemetryPayload{
|
|
145
|
+
Event: event,
|
|
146
|
+
SkillName: skillName,
|
|
147
|
+
Source: source,
|
|
148
|
+
CliVersion: telemetryCliVersion(),
|
|
149
|
+
Platform: runtime.GOOS,
|
|
150
|
+
Arch: runtime.GOARCH,
|
|
151
|
+
}
|
|
152
|
+
wg.Add(1)
|
|
153
|
+
go func(payload telemetryPayload) {
|
|
154
|
+
defer wg.Done()
|
|
155
|
+
if err := reportSkillTelemetry(payload); err != nil && os.Getenv("PIPPIT_CLI_DEBUG_TELEMETRY") == "1" {
|
|
156
|
+
fmt.Fprintf(stderr, "[pippit-tool-cli] telemetry failed: %v\n", err)
|
|
157
|
+
}
|
|
158
|
+
}(payload)
|
|
159
|
+
}
|
|
160
|
+
done := make(chan struct{})
|
|
161
|
+
go func() {
|
|
162
|
+
wg.Wait()
|
|
163
|
+
close(done)
|
|
164
|
+
}()
|
|
165
|
+
select {
|
|
166
|
+
case <-done:
|
|
167
|
+
case <-time.After(telemetryWaitTimeout):
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
func reportSkillTelemetry(payload telemetryPayload) error {
|
|
172
|
+
body, err := json.Marshal(payload)
|
|
173
|
+
if err != nil {
|
|
174
|
+
return err
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
req, err := http.NewRequest(http.MethodPost, telemetryBaseURL()+telemetryPath, bytes.NewReader(body))
|
|
178
|
+
if err != nil {
|
|
179
|
+
return err
|
|
180
|
+
}
|
|
181
|
+
req.Header.Set("Content-Type", "application/json")
|
|
182
|
+
req.Header.Set("Authorization", telemetryAuthHeader)
|
|
183
|
+
req.Header.Set("x-use-ppe", "1")
|
|
184
|
+
req.Header.Set("x-tt-env", "ppe_harness_novel_v2")
|
|
185
|
+
|
|
186
|
+
resp, err := telemetryHTTPClient.Do(req)
|
|
187
|
+
if err != nil {
|
|
188
|
+
return err
|
|
189
|
+
}
|
|
190
|
+
defer resp.Body.Close()
|
|
191
|
+
_, _ = io.Copy(io.Discard, resp.Body)
|
|
192
|
+
if resp.StatusCode >= 400 {
|
|
193
|
+
return fmt.Errorf("telemetry returned HTTP %d", resp.StatusCode)
|
|
194
|
+
}
|
|
195
|
+
return nil
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
func telemetryBaseURL() string {
|
|
199
|
+
for _, key := range []string{"PIPPIT_CLI_TELEMETRY_BASE_URL", "XYQ_OPENAPI_BASE", "XYQ_BASE_URL"} {
|
|
200
|
+
if value := strings.TrimRight(strings.TrimSpace(os.Getenv(key)), "/"); value != "" {
|
|
201
|
+
return value
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
return defaultTelemetryBaseURL
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
func telemetryCliVersion() string {
|
|
208
|
+
return stripPrereleaseVersion(version.Current())
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
func stripPrereleaseVersion(value string) string {
|
|
212
|
+
if idx := strings.Index(value, "-"); idx >= 0 {
|
|
213
|
+
return value[:idx]
|
|
214
|
+
}
|
|
215
|
+
return value
|
|
216
|
+
}
|
|
217
|
+
|
|
108
218
|
func runInherit(stderr io.Writer, name string, args ...string) error {
|
|
109
219
|
return runInheritEnv(stderr, nil, name, args...)
|
|
110
220
|
}
|
|
@@ -2,11 +2,15 @@ package updatecmd
|
|
|
2
2
|
|
|
3
3
|
import (
|
|
4
4
|
"bytes"
|
|
5
|
+
"encoding/json"
|
|
6
|
+
"net/http"
|
|
7
|
+
"net/http/httptest"
|
|
5
8
|
"os"
|
|
6
9
|
"path/filepath"
|
|
7
10
|
"runtime"
|
|
8
11
|
"strings"
|
|
9
12
|
"testing"
|
|
13
|
+
"time"
|
|
10
14
|
)
|
|
11
15
|
|
|
12
16
|
func TestInstallSkillsInstallsAllBundledSkills(t *testing.T) {
|
|
@@ -70,3 +74,108 @@ func TestCleanupLegacyGlobalSkills(t *testing.T) {
|
|
|
70
74
|
}
|
|
71
75
|
}
|
|
72
76
|
}
|
|
77
|
+
|
|
78
|
+
func TestReportSkillTelemetry(t *testing.T) {
|
|
79
|
+
var gotAuth string
|
|
80
|
+
var gotHeaders http.Header
|
|
81
|
+
var gotPayload telemetryPayload
|
|
82
|
+
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
83
|
+
if r.URL.Path != telemetryPath {
|
|
84
|
+
t.Fatalf("path = %q, want %q", r.URL.Path, telemetryPath)
|
|
85
|
+
}
|
|
86
|
+
gotAuth = r.Header.Get("Authorization")
|
|
87
|
+
gotHeaders = r.Header.Clone()
|
|
88
|
+
if err := json.NewDecoder(r.Body).Decode(&gotPayload); err != nil {
|
|
89
|
+
t.Fatalf("decode request body: %v", err)
|
|
90
|
+
}
|
|
91
|
+
_, _ = w.Write([]byte(`{"ret":"0","errmsg":""}`))
|
|
92
|
+
}))
|
|
93
|
+
defer server.Close()
|
|
94
|
+
|
|
95
|
+
t.Setenv("PIPPIT_CLI_TELEMETRY_BASE_URL", server.URL+"/")
|
|
96
|
+
err := reportSkillTelemetry(telemetryPayload{
|
|
97
|
+
Event: "update",
|
|
98
|
+
SkillName: "xyq-skill",
|
|
99
|
+
Source: "cli_update",
|
|
100
|
+
CliVersion: "0.0.26",
|
|
101
|
+
Platform: "darwin",
|
|
102
|
+
Arch: "arm64",
|
|
103
|
+
})
|
|
104
|
+
if err != nil {
|
|
105
|
+
t.Fatalf("reportSkillTelemetry() error = %v", err)
|
|
106
|
+
}
|
|
107
|
+
if gotAuth != telemetryAuthHeader {
|
|
108
|
+
t.Fatalf("Authorization = %q, want %q", gotAuth, telemetryAuthHeader)
|
|
109
|
+
}
|
|
110
|
+
if got := gotHeaders.Get("x-use-ppe"); got != "1" {
|
|
111
|
+
t.Fatalf("x-use-ppe = %q, want 1", got)
|
|
112
|
+
}
|
|
113
|
+
if got := gotHeaders.Get("x-tt-env"); got != "ppe_harness_novel_v2" {
|
|
114
|
+
t.Fatalf("x-tt-env = %q, want ppe_harness_novel_v2", got)
|
|
115
|
+
}
|
|
116
|
+
if gotPayload.Event != "update" || gotPayload.SkillName != "xyq-skill" || gotPayload.Source != "cli_update" {
|
|
117
|
+
t.Fatalf("payload = %#v", gotPayload)
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
func TestReportBundledSkillTelemetryWaitsBriefly(t *testing.T) {
|
|
122
|
+
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
123
|
+
time.Sleep(2 * time.Second)
|
|
124
|
+
_, _ = w.Write([]byte(`{"ret":"0","errmsg":""}`))
|
|
125
|
+
}))
|
|
126
|
+
defer server.Close()
|
|
127
|
+
|
|
128
|
+
t.Setenv("PIPPIT_CLI_TELEMETRY_BASE_URL", server.URL)
|
|
129
|
+
start := time.Now()
|
|
130
|
+
reportBundledSkillTelemetry("update", "cli_update", &bytes.Buffer{})
|
|
131
|
+
if elapsed := time.Since(start); elapsed > 1500*time.Millisecond {
|
|
132
|
+
t.Fatalf("reportBundledSkillTelemetry() blocked for %v, want <= 1.5s", elapsed)
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
func TestReportBundledSkillTelemetryReportsBothSkills(t *testing.T) {
|
|
137
|
+
skillNames := make(chan string, len(telemetrySkillNames))
|
|
138
|
+
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
139
|
+
var payload telemetryPayload
|
|
140
|
+
if err := json.NewDecoder(r.Body).Decode(&payload); err != nil {
|
|
141
|
+
t.Fatalf("decode request body: %v", err)
|
|
142
|
+
}
|
|
143
|
+
skillNames <- payload.SkillName
|
|
144
|
+
_, _ = w.Write([]byte(`{"ret":"0","errmsg":""}`))
|
|
145
|
+
}))
|
|
146
|
+
defer server.Close()
|
|
147
|
+
|
|
148
|
+
t.Setenv("PIPPIT_CLI_TELEMETRY_BASE_URL", server.URL)
|
|
149
|
+
reportBundledSkillTelemetry("update", "cli_update", &bytes.Buffer{})
|
|
150
|
+
|
|
151
|
+
got := map[string]bool{}
|
|
152
|
+
for i := 0; i < len(telemetrySkillNames); i++ {
|
|
153
|
+
got[<-skillNames] = true
|
|
154
|
+
}
|
|
155
|
+
for _, skillName := range telemetrySkillNames {
|
|
156
|
+
if !got[skillName] {
|
|
157
|
+
t.Fatalf("missing telemetry for %s, got %#v", skillName, got)
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
func TestTelemetryBaseURL(t *testing.T) {
|
|
163
|
+
t.Setenv("PIPPIT_CLI_TELEMETRY_BASE_URL", " ")
|
|
164
|
+
t.Setenv("XYQ_OPENAPI_BASE", "https://example.com///")
|
|
165
|
+
if got := telemetryBaseURL(); got != "https://example.com" {
|
|
166
|
+
t.Fatalf("telemetryBaseURL() = %q, want https://example.com", got)
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
func TestStripPrereleaseVersion(t *testing.T) {
|
|
171
|
+
cases := map[string]string{
|
|
172
|
+
"0.0.27": "0.0.27",
|
|
173
|
+
"0.0.27-rc.1": "0.0.27",
|
|
174
|
+
"1.2.3-beta.4": "1.2.3",
|
|
175
|
+
}
|
|
176
|
+
for input, want := range cases {
|
|
177
|
+
if got := stripPrereleaseVersion(input); got != want {
|
|
178
|
+
t.Fatalf("stripPrereleaseVersion(%q) = %q, want %q", input, got, want)
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
}
|
package/package.json
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pippit-dev/cli",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.28",
|
|
4
4
|
"description": "Pippit CLI",
|
|
5
5
|
"bin": {
|
|
6
6
|
"pippit-tool-cli": "scripts/run.js"
|
|
7
7
|
},
|
|
8
8
|
"scripts": {
|
|
9
9
|
"postinstall": "node scripts/install.js",
|
|
10
|
-
"test": "node scripts/version-check.test.js && node scripts/skills.test.js && go test ./... && go vet ./..."
|
|
10
|
+
"test": "node scripts/version-check.test.js && node scripts/skills.test.js && node scripts/install-wizard.test.js && go test ./... && go vet ./..."
|
|
11
11
|
},
|
|
12
12
|
"os": [
|
|
13
13
|
"darwin",
|
|
@@ -35,6 +35,7 @@
|
|
|
35
35
|
"scripts/platform.js",
|
|
36
36
|
"scripts/run.js",
|
|
37
37
|
"scripts/skills.js",
|
|
38
|
+
"scripts/telemetry.js",
|
|
38
39
|
"scripts/version-check.js",
|
|
39
40
|
"checksums.txt",
|
|
40
41
|
"README.md",
|
|
@@ -4,8 +4,17 @@ const fs = require("fs");
|
|
|
4
4
|
const path = require("path");
|
|
5
5
|
const { isWindows, run, runSilent } = require("./platform");
|
|
6
6
|
const { DEFAULT_PKG, installGlobalPackageSkills } = require("./skills");
|
|
7
|
+
const { reportBundledSkillTelemetry } = require("./telemetry");
|
|
7
8
|
|
|
8
|
-
const
|
|
9
|
+
const VERSION = require("../package.json").version.replace(/-.*$/, "");
|
|
10
|
+
|
|
11
|
+
function defaultInstallPackage() {
|
|
12
|
+
return `${DEFAULT_PKG}@${VERSION}`;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function installPackage() {
|
|
16
|
+
return process.env.PIPPIT_CLI_INSTALL_PACKAGE || defaultInstallPackage();
|
|
17
|
+
}
|
|
9
18
|
|
|
10
19
|
function getGloballyInstalledVersion() {
|
|
11
20
|
try {
|
|
@@ -37,13 +46,14 @@ function whichPippitToolCli() {
|
|
|
37
46
|
}
|
|
38
47
|
|
|
39
48
|
function main() {
|
|
49
|
+
const pkg = installPackage();
|
|
40
50
|
const installed = getGloballyInstalledVersion();
|
|
41
51
|
if (installed) {
|
|
42
|
-
console.log(`Updating global pippit-tool-cli (${installed}) via ${
|
|
52
|
+
console.log(`Updating global pippit-tool-cli (${installed}) via ${pkg}...`);
|
|
43
53
|
} else {
|
|
44
|
-
console.log(`Installing ${
|
|
54
|
+
console.log(`Installing ${pkg} globally...`);
|
|
45
55
|
}
|
|
46
|
-
run("npm", ["install", "-g",
|
|
56
|
+
run("npm", ["install", "-g", pkg], {
|
|
47
57
|
timeout: 120000,
|
|
48
58
|
env: { ...process.env, PIPPIT_CLI_SKIP_SKILLS: "1" },
|
|
49
59
|
});
|
|
@@ -56,7 +66,7 @@ function main() {
|
|
|
56
66
|
throw err;
|
|
57
67
|
}
|
|
58
68
|
console.log("Existing global package does not contain skills; reinstalling...");
|
|
59
|
-
run("npm", ["install", "-g",
|
|
69
|
+
run("npm", ["install", "-g", pkg], { timeout: 120000 });
|
|
60
70
|
installGlobalPackageSkills(DEFAULT_PKG);
|
|
61
71
|
}
|
|
62
72
|
|
|
@@ -68,7 +78,16 @@ function main() {
|
|
|
68
78
|
}
|
|
69
79
|
|
|
70
80
|
console.log(`pippit-tool-cli is ready: ${bin}`);
|
|
81
|
+
reportBundledSkillTelemetry("install", "npx_install");
|
|
71
82
|
console.log("Try: pippit-tool-cli short-drama +submit-run --message \"写一个短剧开头\"");
|
|
72
83
|
}
|
|
73
84
|
|
|
74
|
-
main
|
|
85
|
+
if (require.main === module) {
|
|
86
|
+
main();
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
module.exports = {
|
|
90
|
+
defaultInstallPackage,
|
|
91
|
+
installPackage,
|
|
92
|
+
main,
|
|
93
|
+
};
|
package/scripts/install.js
CHANGED
|
@@ -6,6 +6,7 @@ const os = require("os");
|
|
|
6
6
|
const path = require("path");
|
|
7
7
|
const { isWindows, run } = require("./platform");
|
|
8
8
|
const { cleanupLegacyGlobalSkills, installSkillsFromRoot } = require("./skills");
|
|
9
|
+
const { reportBundledSkillTelemetry } = require("./telemetry");
|
|
9
10
|
|
|
10
11
|
const VERSION = require("../package.json").version.replace(/-.*$/, "");
|
|
11
12
|
const REPO = "Pippit-dev/cli";
|
|
@@ -134,6 +135,7 @@ function install() {
|
|
|
134
135
|
|
|
135
136
|
if (process.env.PIPPIT_CLI_SKIP_SKILLS !== "1") {
|
|
136
137
|
installSkillsFromRoot(ROOT);
|
|
138
|
+
reportBundledSkillTelemetry("install", "npm_install");
|
|
137
139
|
} else {
|
|
138
140
|
cleanupLegacyGlobalSkills();
|
|
139
141
|
}
|
package/scripts/run.js
CHANGED
|
@@ -38,7 +38,7 @@ if (process.platform === "win32" && fs.existsSync(oldBin)) {
|
|
|
38
38
|
// Match the lark-cli install entry: `npx @pippit-dev/cli@latest install`
|
|
39
39
|
// should run the JS setup flow before the native binary exists.
|
|
40
40
|
if (args[0] === "install") {
|
|
41
|
-
require("./install-wizard.js");
|
|
41
|
+
require("./install-wizard.js").main();
|
|
42
42
|
} else {
|
|
43
43
|
maybeWarnNewVersion(args);
|
|
44
44
|
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
const os = require("os");
|
|
2
|
+
const http = require("http");
|
|
3
|
+
const https = require("https");
|
|
4
|
+
|
|
5
|
+
const VERSION = require("../package.json").version.replace(/-.*$/, "");
|
|
6
|
+
const DEFAULT_BASE_URL = "https://xyq.jianying.com";
|
|
7
|
+
const REPORT_PATH = "/api/biz/v1/skill/report_telemetry";
|
|
8
|
+
const AUTH_HEADER = "Bearer pippit-cli-skill-telemetry";
|
|
9
|
+
const SKILL_NAMES = [
|
|
10
|
+
"xyq-skill",
|
|
11
|
+
"xyq-short-drama-skill",
|
|
12
|
+
];
|
|
13
|
+
|
|
14
|
+
function telemetryBaseURL() {
|
|
15
|
+
for (const key of ["PIPPIT_CLI_TELEMETRY_BASE_URL", "XYQ_OPENAPI_BASE", "XYQ_BASE_URL"]) {
|
|
16
|
+
const value = (process.env[key] || "").trim().replace(/\/+$/, "");
|
|
17
|
+
if (value) return value;
|
|
18
|
+
}
|
|
19
|
+
return DEFAULT_BASE_URL;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function reportBundledSkillTelemetry(event, source) {
|
|
23
|
+
if (process.env.PIPPIT_CLI_DISABLE_TELEMETRY === "1") {
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
for (const skillName of SKILL_NAMES) {
|
|
27
|
+
reportSkillTelemetry({
|
|
28
|
+
event,
|
|
29
|
+
skill_name: skillName,
|
|
30
|
+
source,
|
|
31
|
+
cli_version: VERSION,
|
|
32
|
+
platform: os.platform(),
|
|
33
|
+
arch: os.arch(),
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function reportSkillTelemetry(payload) {
|
|
39
|
+
const body = JSON.stringify(payload);
|
|
40
|
+
const url = new URL(`${telemetryBaseURL()}${REPORT_PATH}`);
|
|
41
|
+
const client = url.protocol === "http:" ? http : https;
|
|
42
|
+
|
|
43
|
+
try {
|
|
44
|
+
const req = client.request(url, {
|
|
45
|
+
method: "POST",
|
|
46
|
+
timeout: 2000,
|
|
47
|
+
headers: {
|
|
48
|
+
"Content-Type": "application/json",
|
|
49
|
+
"Content-Length": Buffer.byteLength(body),
|
|
50
|
+
"Authorization": AUTH_HEADER,
|
|
51
|
+
"x-use-ppe": "1",
|
|
52
|
+
"x-tt-env": "ppe_harness_novel_v2",
|
|
53
|
+
},
|
|
54
|
+
}, (res) => {
|
|
55
|
+
res.resume();
|
|
56
|
+
if (process.env.PIPPIT_CLI_DEBUG_TELEMETRY === "1" && res.statusCode >= 400) {
|
|
57
|
+
console.warn(`[pippit-tool-cli] telemetry failed: HTTP ${res.statusCode}`);
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
req.on("timeout", () => {
|
|
62
|
+
req.destroy(new Error("telemetry request timeout"));
|
|
63
|
+
});
|
|
64
|
+
req.on("error", (err) => {
|
|
65
|
+
if (process.env.PIPPIT_CLI_DEBUG_TELEMETRY === "1") {
|
|
66
|
+
const msg = err && err.message ? err.message : String(err);
|
|
67
|
+
console.warn(`[pippit-tool-cli] telemetry failed: ${msg}`);
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
req.end(body);
|
|
71
|
+
} catch (err) {
|
|
72
|
+
if (process.env.PIPPIT_CLI_DEBUG_TELEMETRY === "1") {
|
|
73
|
+
const msg = err && err.message ? err.message : String(err);
|
|
74
|
+
console.warn(`[pippit-tool-cli] telemetry failed: ${msg}`);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
module.exports = {
|
|
80
|
+
reportBundledSkillTelemetry,
|
|
81
|
+
reportSkillTelemetry,
|
|
82
|
+
telemetryBaseURL,
|
|
83
|
+
};
|