@pippit-dev/cli 0.0.25 → 0.0.27
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 +96 -0
- package/cmd/update/update_test.go +67 -0
- package/package.json +2 -1
- package/scripts/install-wizard.js +2 -0
- package/scripts/install.js +2 -0
- package/scripts/telemetry.js +83 -0
- package/skills/xyq-nest-skill/scripts/get_thread.py +2 -2
- package/skills/xyq-nest-skill/scripts/submit_run.py +1 -1
- package/skills/xyq-nest-skill/scripts/upload_file.py +1 -1
- /package/skills/xyq-nest-skill/scripts/{_common.py → xyq_common.py} +0 -0
package/checksums.txt
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
1
|
+
3e95e8bbd667579fa1feddd4c58e583d70003f0f179d7249135b883a612165e5 pippit-tool-cli-0.0.27-darwin-amd64.tar.gz
|
|
2
|
+
15671a5880feff8a67bd0c8042ab7e2a77d1ea7c81ed6625427bdd472d925c6a pippit-tool-cli-0.0.27-darwin-arm64.tar.gz
|
|
3
|
+
aef2fc4896d2c8966f681a82e5bd624b9ec9f0382e23dd05776f014cbb65473d pippit-tool-cli-0.0.27-linux-amd64.tar.gz
|
|
4
|
+
5b01a760298c22a6fd42661f212f9f1d1e822e84d1feb87307c36590f795515a pippit-tool-cli-0.0.27-linux-arm64.tar.gz
|
|
5
|
+
18315d247bb409f594d11e64cb2292ffbf48504d73290011f5c5a2ba319f93df pippit-tool-cli-0.0.27-windows-amd64.zip
|
|
6
|
+
31284208bc244d9d48066c8e7086bf40e167209fff106ea6462c9638cbd6efef pippit-tool-cli-0.0.27-windows-arm64.zip
|
package/cmd/update/update.go
CHANGED
|
@@ -1,24 +1,42 @@
|
|
|
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
|
+
"time"
|
|
11
15
|
|
|
16
|
+
"github.com/Pippit-dev/pippit-cli/internal/version"
|
|
12
17
|
"github.com/spf13/cobra"
|
|
13
18
|
)
|
|
14
19
|
|
|
15
20
|
const defaultPackage = "@pippit-dev/cli"
|
|
16
21
|
|
|
22
|
+
const (
|
|
23
|
+
defaultTelemetryBaseURL = "https://xyq.jianying.com"
|
|
24
|
+
telemetryPath = "/api/biz/v1/skill/report_telemetry"
|
|
25
|
+
telemetryAuthHeader = "Bearer pippit-cli-skill-telemetry"
|
|
26
|
+
)
|
|
27
|
+
|
|
17
28
|
var legacyGlobalSkills = []string{
|
|
18
29
|
"pippit-short-drama-skill",
|
|
19
30
|
"xyq-nest-skill",
|
|
20
31
|
}
|
|
21
32
|
|
|
33
|
+
var telemetrySkillNames = []string{
|
|
34
|
+
"xyq-skill",
|
|
35
|
+
"xyq-short-drama-skill",
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
var telemetryHTTPClient = &http.Client{Timeout: 2 * time.Second}
|
|
39
|
+
|
|
22
40
|
// NewCommand builds the update command.
|
|
23
41
|
func NewCommand(stdout, stderr io.Writer) *cobra.Command {
|
|
24
42
|
cmd := &cobra.Command{
|
|
@@ -57,6 +75,7 @@ func runUpdate(stdout, stderr io.Writer) error {
|
|
|
57
75
|
return fmt.Errorf("update pippit-tool-cli skills: %w", err)
|
|
58
76
|
}
|
|
59
77
|
|
|
78
|
+
reportBundledSkillTelemetry("update", "cli_update", stderr)
|
|
60
79
|
fmt.Fprintln(stdout, "pippit-tool-cli and skills updated")
|
|
61
80
|
return nil
|
|
62
81
|
}
|
|
@@ -105,6 +124,83 @@ func cleanupLegacyGlobalSkills(globalSkillsDir string) error {
|
|
|
105
124
|
return nil
|
|
106
125
|
}
|
|
107
126
|
|
|
127
|
+
type telemetryPayload struct {
|
|
128
|
+
Event string `json:"event"`
|
|
129
|
+
SkillName string `json:"skill_name"`
|
|
130
|
+
Source string `json:"source"`
|
|
131
|
+
CliVersion string `json:"cli_version"`
|
|
132
|
+
Platform string `json:"platform"`
|
|
133
|
+
Arch string `json:"arch"`
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
func reportBundledSkillTelemetry(event string, source string, stderr io.Writer) {
|
|
137
|
+
if os.Getenv("PIPPIT_CLI_DISABLE_TELEMETRY") == "1" {
|
|
138
|
+
return
|
|
139
|
+
}
|
|
140
|
+
for _, skillName := range telemetrySkillNames {
|
|
141
|
+
payload := telemetryPayload{
|
|
142
|
+
Event: event,
|
|
143
|
+
SkillName: skillName,
|
|
144
|
+
Source: source,
|
|
145
|
+
CliVersion: telemetryCliVersion(),
|
|
146
|
+
Platform: runtime.GOOS,
|
|
147
|
+
Arch: runtime.GOARCH,
|
|
148
|
+
}
|
|
149
|
+
go func(payload telemetryPayload) {
|
|
150
|
+
if err := reportSkillTelemetry(payload); err != nil && os.Getenv("PIPPIT_CLI_DEBUG_TELEMETRY") == "1" {
|
|
151
|
+
fmt.Fprintf(stderr, "[pippit-tool-cli] telemetry failed: %v\n", err)
|
|
152
|
+
}
|
|
153
|
+
}(payload)
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
func reportSkillTelemetry(payload telemetryPayload) error {
|
|
158
|
+
body, err := json.Marshal(payload)
|
|
159
|
+
if err != nil {
|
|
160
|
+
return err
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
req, err := http.NewRequest(http.MethodPost, telemetryBaseURL()+telemetryPath, bytes.NewReader(body))
|
|
164
|
+
if err != nil {
|
|
165
|
+
return err
|
|
166
|
+
}
|
|
167
|
+
req.Header.Set("Content-Type", "application/json")
|
|
168
|
+
req.Header.Set("Authorization", telemetryAuthHeader)
|
|
169
|
+
req.Header.Set("x-use-ppe", "1")
|
|
170
|
+
req.Header.Set("x-tt-env", "ppe_harness_novel_v2")
|
|
171
|
+
|
|
172
|
+
resp, err := telemetryHTTPClient.Do(req)
|
|
173
|
+
if err != nil {
|
|
174
|
+
return err
|
|
175
|
+
}
|
|
176
|
+
defer resp.Body.Close()
|
|
177
|
+
_, _ = io.Copy(io.Discard, resp.Body)
|
|
178
|
+
if resp.StatusCode >= 400 {
|
|
179
|
+
return fmt.Errorf("telemetry returned HTTP %d", resp.StatusCode)
|
|
180
|
+
}
|
|
181
|
+
return nil
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
func telemetryBaseURL() string {
|
|
185
|
+
for _, key := range []string{"PIPPIT_CLI_TELEMETRY_BASE_URL", "XYQ_OPENAPI_BASE", "XYQ_BASE_URL"} {
|
|
186
|
+
if value := strings.TrimRight(strings.TrimSpace(os.Getenv(key)), "/"); value != "" {
|
|
187
|
+
return value
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
return defaultTelemetryBaseURL
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
func telemetryCliVersion() string {
|
|
194
|
+
return stripPrereleaseVersion(version.Current())
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
func stripPrereleaseVersion(value string) string {
|
|
198
|
+
if idx := strings.Index(value, "-"); idx >= 0 {
|
|
199
|
+
return value[:idx]
|
|
200
|
+
}
|
|
201
|
+
return value
|
|
202
|
+
}
|
|
203
|
+
|
|
108
204
|
func runInherit(stderr io.Writer, name string, args ...string) error {
|
|
109
205
|
return runInheritEnv(stderr, nil, name, args...)
|
|
110
206
|
}
|
|
@@ -2,6 +2,9 @@ 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"
|
|
@@ -70,3 +73,67 @@ func TestCleanupLegacyGlobalSkills(t *testing.T) {
|
|
|
70
73
|
}
|
|
71
74
|
}
|
|
72
75
|
}
|
|
76
|
+
|
|
77
|
+
func TestReportSkillTelemetry(t *testing.T) {
|
|
78
|
+
var gotAuth string
|
|
79
|
+
var gotHeaders http.Header
|
|
80
|
+
var gotPayload telemetryPayload
|
|
81
|
+
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
82
|
+
if r.URL.Path != telemetryPath {
|
|
83
|
+
t.Fatalf("path = %q, want %q", r.URL.Path, telemetryPath)
|
|
84
|
+
}
|
|
85
|
+
gotAuth = r.Header.Get("Authorization")
|
|
86
|
+
gotHeaders = r.Header.Clone()
|
|
87
|
+
if err := json.NewDecoder(r.Body).Decode(&gotPayload); err != nil {
|
|
88
|
+
t.Fatalf("decode request body: %v", err)
|
|
89
|
+
}
|
|
90
|
+
_, _ = w.Write([]byte(`{"ret":"0","errmsg":""}`))
|
|
91
|
+
}))
|
|
92
|
+
defer server.Close()
|
|
93
|
+
|
|
94
|
+
t.Setenv("PIPPIT_CLI_TELEMETRY_BASE_URL", server.URL+"/")
|
|
95
|
+
err := reportSkillTelemetry(telemetryPayload{
|
|
96
|
+
Event: "update",
|
|
97
|
+
SkillName: "xyq-skill",
|
|
98
|
+
Source: "cli_update",
|
|
99
|
+
CliVersion: "0.0.26",
|
|
100
|
+
Platform: "darwin",
|
|
101
|
+
Arch: "arm64",
|
|
102
|
+
})
|
|
103
|
+
if err != nil {
|
|
104
|
+
t.Fatalf("reportSkillTelemetry() error = %v", err)
|
|
105
|
+
}
|
|
106
|
+
if gotAuth != telemetryAuthHeader {
|
|
107
|
+
t.Fatalf("Authorization = %q, want %q", gotAuth, telemetryAuthHeader)
|
|
108
|
+
}
|
|
109
|
+
if got := gotHeaders.Get("x-use-ppe"); got != "1" {
|
|
110
|
+
t.Fatalf("x-use-ppe = %q, want 1", got)
|
|
111
|
+
}
|
|
112
|
+
if got := gotHeaders.Get("x-tt-env"); got != "ppe_harness_novel_v2" {
|
|
113
|
+
t.Fatalf("x-tt-env = %q, want ppe_harness_novel_v2", got)
|
|
114
|
+
}
|
|
115
|
+
if gotPayload.Event != "update" || gotPayload.SkillName != "xyq-skill" || gotPayload.Source != "cli_update" {
|
|
116
|
+
t.Fatalf("payload = %#v", gotPayload)
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
func TestTelemetryBaseURL(t *testing.T) {
|
|
121
|
+
t.Setenv("PIPPIT_CLI_TELEMETRY_BASE_URL", " ")
|
|
122
|
+
t.Setenv("XYQ_OPENAPI_BASE", "https://example.com///")
|
|
123
|
+
if got := telemetryBaseURL(); got != "https://example.com" {
|
|
124
|
+
t.Fatalf("telemetryBaseURL() = %q, want https://example.com", got)
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
func TestStripPrereleaseVersion(t *testing.T) {
|
|
129
|
+
cases := map[string]string{
|
|
130
|
+
"0.0.27": "0.0.27",
|
|
131
|
+
"0.0.27-rc.1": "0.0.27",
|
|
132
|
+
"1.2.3-beta.4": "1.2.3",
|
|
133
|
+
}
|
|
134
|
+
for input, want := range cases {
|
|
135
|
+
if got := stripPrereleaseVersion(input); got != want {
|
|
136
|
+
t.Fatalf("stripPrereleaseVersion(%q) = %q, want %q", input, got, want)
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pippit-dev/cli",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.27",
|
|
4
4
|
"description": "Pippit CLI",
|
|
5
5
|
"bin": {
|
|
6
6
|
"pippit-tool-cli": "scripts/run.js"
|
|
@@ -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,6 +4,7 @@ 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
9
|
const PKG = process.env.PIPPIT_CLI_INSTALL_PACKAGE || DEFAULT_PKG;
|
|
9
10
|
|
|
@@ -68,6 +69,7 @@ function main() {
|
|
|
68
69
|
}
|
|
69
70
|
|
|
70
71
|
console.log(`pippit-tool-cli is ready: ${bin}`);
|
|
72
|
+
reportBundledSkillTelemetry("install", "npx_install");
|
|
71
73
|
console.log("Try: pippit-tool-cli short-drama +submit-run --message \"写一个短剧开头\"");
|
|
72
74
|
}
|
|
73
75
|
|
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
|
}
|
|
@@ -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
|
+
};
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
#!/usr/bin/env python3
|
|
2
2
|
"""查询会话进展:POST /api/biz/v1/skill/get_thread,返回消息列表"""
|
|
3
3
|
|
|
4
|
-
from _common import extract_entries_from_run
|
|
5
4
|
import argparse
|
|
6
5
|
import json
|
|
7
6
|
import sys
|
|
8
7
|
import os
|
|
9
8
|
|
|
10
9
|
sys.path.insert(0, os.path.dirname(__file__))
|
|
11
|
-
from
|
|
10
|
+
from xyq_common import extract_entries_from_run
|
|
11
|
+
from xyq_common import get_thread
|
|
12
12
|
|
|
13
13
|
|
|
14
14
|
def main():
|
|
@@ -11,7 +11,7 @@ import urllib.request
|
|
|
11
11
|
import urllib.error
|
|
12
12
|
|
|
13
13
|
sys.path.insert(0, os.path.dirname(__file__))
|
|
14
|
-
from
|
|
14
|
+
from xyq_common import XYQ_BASE, ACCESS_KEY, UPLOAD_FILE_PATH, parse_response
|
|
15
15
|
|
|
16
16
|
# 允许的 MIME 类型前缀
|
|
17
17
|
ALLOWED_PREFIXES = ("image/", "video/")
|
|
File without changes
|