@pippit-dev/cli 0.0.8 → 0.0.10

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 CHANGED
@@ -10,6 +10,7 @@ matching prebuilt binary for macOS, Linux, or Windows:
10
10
  ```bash
11
11
  npx @pippit-dev/cli@latest install
12
12
  export XYQ_ACCESS_KEY="<access-key>"
13
+ pippit-cli version
13
14
  pippit-cli short-drama +submit-run --message "写一个赛博朋克短剧开头"
14
15
  pippit-cli short-drama +upload-file --path ./story.md
15
16
  pippit-cli short-drama +get-thread --thread-id thread_123 --run-id run_456 --after-seq 0
@@ -23,6 +24,7 @@ Submit a Run task for the short drama scene:
23
24
 
24
25
  ```bash
25
26
  export XYQ_ACCESS_KEY="<access-key>"
27
+ go run . version
26
28
  go run . short-drama +submit-run --message "写一个赛博朋克短剧开头"
27
29
  go run . short-drama +upload-file --path ./story.md
28
30
  go run . short-drama +get-thread --thread-id thread_123 --run-id run_456 --after-seq 0
package/checksums.txt CHANGED
@@ -1,6 +1,6 @@
1
- d403f987a5f3cf416d0d183d0b7f45c6cd13ac36da37ca29480e8c9b53af75ea pippit-cli-0.0.8-darwin-amd64.tar.gz
2
- 69aa116a8dd6086f00769ac71aca9cb83c5ffe058187c42c212d35aadb06d817 pippit-cli-0.0.8-darwin-arm64.tar.gz
3
- cdb856501d5472f226bf061073aa2d2af2f61b28151ca908e48e1acc8d1261b4 pippit-cli-0.0.8-linux-amd64.tar.gz
4
- 6a8013ca271df7ddebba3ffcc4ed76ef79404ad6105893cda7db2969a5f51595 pippit-cli-0.0.8-linux-arm64.tar.gz
5
- 1fff575ecbef2d8ed5cc5c05b87d08dbad6f68b3aa1c5da13957cac9f887b4ce pippit-cli-0.0.8-windows-amd64.zip
6
- bfe3160bad9d536a7510486233cbe4bada0581996b142812edcabb741cc5d2de pippit-cli-0.0.8-windows-arm64.zip
1
+ 5aca1f46d99e5ab9d748cf14d4cfe5fa68b2d2cb248073db0c92d0de361e5fb8 pippit-cli-0.0.10-darwin-amd64.tar.gz
2
+ b56de7e3bdd202d449ea5658171b52dbde313c1e3f12f999c583a6b321624d11 pippit-cli-0.0.10-darwin-arm64.tar.gz
3
+ b9ddcbd19ffa7aada4c114f7be8b8d6fb870b9a0b9ffed99c0df196ce05658d4 pippit-cli-0.0.10-linux-amd64.tar.gz
4
+ 3b8a11becb6229f22c39e2c86caaa897f4ae9147e0960414c0d763ce00bbdd5b pippit-cli-0.0.10-linux-arm64.tar.gz
5
+ 26a57f485227f9674591ed20536baa281c443b5ac1c26711e064a77d9ebc6174 pippit-cli-0.0.10-windows-amd64.zip
6
+ 8fd4eca3a8977b901d74aa6455293c3c400151e5981491f6d3df1d568781c3eb pippit-cli-0.0.10-windows-arm64.zip
package/cmd/root.go CHANGED
@@ -7,8 +7,10 @@ import (
7
7
  // authcmd "github.com/Pippit-dev/pippit-cli/cmd/auth"
8
8
  "github.com/Pippit-dev/pippit-cli/cmd/short_drama"
9
9
  updatecmd "github.com/Pippit-dev/pippit-cli/cmd/update"
10
+ versioncmd "github.com/Pippit-dev/pippit-cli/cmd/version"
10
11
  "github.com/Pippit-dev/pippit-cli/internal/common"
11
12
  "github.com/Pippit-dev/pippit-cli/internal/config"
13
+ "github.com/Pippit-dev/pippit-cli/internal/version"
12
14
  "github.com/spf13/cobra"
13
15
  )
14
16
 
@@ -28,6 +30,7 @@ func newRootCommand(stdout, stderr io.Writer, runner *common.Runner) *cobra.Comm
28
30
  root := &cobra.Command{
29
31
  Use: "pippit-cli",
30
32
  Short: "Pippit CLI",
33
+ Version: version.Current(),
31
34
  SilenceUsage: true,
32
35
  SilenceErrors: true,
33
36
  }
@@ -36,5 +39,6 @@ func newRootCommand(stdout, stderr io.Writer, runner *common.Runner) *cobra.Comm
36
39
  // root.AddCommand(authcmd.NewCommand(stdout, stderr, runner)) // temporarily disabled; auth is via access key injection
37
40
  root.AddCommand(short_drama.NewCommand(stdout, stderr, runner))
38
41
  root.AddCommand(updatecmd.NewCommand(stdout, stderr))
42
+ root.AddCommand(versioncmd.NewCommand(stdout))
39
43
  return root
40
44
  }
@@ -12,6 +12,7 @@ import (
12
12
 
13
13
  "github.com/Pippit-dev/pippit-cli/internal/common"
14
14
  "github.com/Pippit-dev/pippit-cli/internal/config"
15
+ "github.com/Pippit-dev/pippit-cli/internal/version"
15
16
  "github.com/bytedance/sonic"
16
17
  "github.com/spf13/cobra"
17
18
  )
@@ -90,6 +91,44 @@ func TestRootIncludesUpdateCommand(t *testing.T) {
90
91
  }
91
92
  }
92
93
 
94
+ func TestRootIncludesVersionCommand(t *testing.T) {
95
+ var stdout, stderr bytes.Buffer
96
+ root := NewRootCommand(&stdout, &stderr)
97
+ cmd, _, err := root.Find([]string{"version"})
98
+ if err != nil {
99
+ t.Fatalf("Find(version) error = %v", err)
100
+ }
101
+ if cmd == nil || cmd.Name() != "version" {
102
+ t.Fatalf("Find(version) = %#v, want version command", cmd)
103
+ }
104
+ }
105
+
106
+ func TestVersionCommandPrintsVersion(t *testing.T) {
107
+ var stdout, stderr bytes.Buffer
108
+ root := NewRootCommand(&stdout, &stderr)
109
+ root.SetArgs([]string{"version"})
110
+
111
+ if err := root.Execute(); err != nil {
112
+ t.Fatalf("Execute() error = %v, stderr = %s", err, stderr.String())
113
+ }
114
+ if got := strings.TrimSpace(stdout.String()); got != version.Current() {
115
+ t.Fatalf("version output = %q, want %s", got, version.Current())
116
+ }
117
+ }
118
+
119
+ func TestVersionFlagPrintsVersion(t *testing.T) {
120
+ var stdout, stderr bytes.Buffer
121
+ root := NewRootCommand(&stdout, &stderr)
122
+ root.SetArgs([]string{"--version"})
123
+
124
+ if err := root.Execute(); err != nil {
125
+ t.Fatalf("Execute() error = %v, stderr = %s", err, stderr.String())
126
+ }
127
+ if got := stdout.String(); !strings.Contains(got, version.Current()) {
128
+ t.Fatalf("version flag output = %q, want version", got)
129
+ }
130
+ }
131
+
93
132
  func TestShortDramaSubmitRunRequiresMessage(t *testing.T) {
94
133
  var stdout, stderr bytes.Buffer
95
134
  root := NewRootCommand(&stdout, &stderr)
@@ -0,0 +1,21 @@
1
+ package versioncmd
2
+
3
+ import (
4
+ "fmt"
5
+ "io"
6
+
7
+ "github.com/Pippit-dev/pippit-cli/internal/version"
8
+ "github.com/spf13/cobra"
9
+ )
10
+
11
+ func NewCommand(stdout io.Writer) *cobra.Command {
12
+ return &cobra.Command{
13
+ Use: "version",
14
+ Short: "Print pippit-cli version",
15
+ Args: cobra.NoArgs,
16
+ RunE: func(cmd *cobra.Command, _ []string) error {
17
+ _, err := fmt.Fprintln(stdout, version.Current())
18
+ return err
19
+ },
20
+ }
21
+ }
@@ -0,0 +1,61 @@
1
+ package version
2
+
3
+ import (
4
+ "encoding/json"
5
+ "os"
6
+ "path/filepath"
7
+ "strings"
8
+ )
9
+
10
+ // Version is set by GoReleaser for release binaries.
11
+ var Version = "dev"
12
+
13
+ const packageName = "@pippit-dev/cli"
14
+
15
+ type packageJSON struct {
16
+ Name string `json:"name"`
17
+ Version string `json:"version"`
18
+ }
19
+
20
+ func Current() string {
21
+ if strings.TrimSpace(Version) != "" && Version != "dev" {
22
+ return strings.TrimSpace(Version)
23
+ }
24
+ if version := packageVersionFromWorktree(); version != "" {
25
+ return version
26
+ }
27
+ return Version
28
+ }
29
+
30
+ func packageVersionFromWorktree() string {
31
+ dir, err := os.Getwd()
32
+ if err != nil {
33
+ return ""
34
+ }
35
+ for {
36
+ version := packageVersion(filepath.Join(dir, "package.json"))
37
+ if version != "" {
38
+ return version
39
+ }
40
+ parent := filepath.Dir(dir)
41
+ if parent == dir {
42
+ return ""
43
+ }
44
+ dir = parent
45
+ }
46
+ }
47
+
48
+ func packageVersion(path string) string {
49
+ data, err := os.ReadFile(path)
50
+ if err != nil {
51
+ return ""
52
+ }
53
+ var pkg packageJSON
54
+ if err := json.Unmarshal(data, &pkg); err != nil {
55
+ return ""
56
+ }
57
+ if pkg.Name != packageName {
58
+ return ""
59
+ }
60
+ return strings.TrimSpace(pkg.Version)
61
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pippit-dev/cli",
3
- "version": "0.0.8",
3
+ "version": "0.0.10",
4
4
  "description": "Pippit CLI",
5
5
  "bin": {
6
6
  "pippit-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/version-check.js",
38
39
  "checksums.txt",
39
40
  "README.md",
40
41
  "LICENSE"
package/scripts/run.js CHANGED
@@ -3,6 +3,7 @@
3
3
  const { execFileSync } = require("child_process");
4
4
  const fs = require("fs");
5
5
  const path = require("path");
6
+ const { maybeWarnNewVersion } = require("./version-check");
6
7
 
7
8
  const ext = process.platform === "win32" ? ".exe" : "";
8
9
  const bin = path.join(__dirname, "..", "bin", "pippit-cli" + ext);
@@ -39,6 +40,8 @@ if (process.platform === "win32" && fs.existsSync(oldBin)) {
39
40
  if (args[0] === "install") {
40
41
  require("./install-wizard.js");
41
42
  } else {
43
+ maybeWarnNewVersion(args);
44
+
42
45
  if (!fs.existsSync(bin)) {
43
46
  try {
44
47
  execFileSync(process.execPath, [path.join(__dirname, "install.js")], {
@@ -0,0 +1,96 @@
1
+ const fs = require("fs");
2
+ const os = require("os");
3
+ const path = require("path");
4
+ const { runSilent } = require("./platform");
5
+ const { DEFAULT_PKG } = require("./skills");
6
+
7
+ const CHECK_INTERVAL_MS = 24 * 60 * 60 * 1000;
8
+
9
+ function defaultCacheFile() {
10
+ return path.join(os.homedir(), ".pippit-cli", "version-check.json");
11
+ }
12
+
13
+ function currentVersion() {
14
+ return require("../package.json").version.replace(/-.*$/, "");
15
+ }
16
+
17
+ function parseSemver(version) {
18
+ const match = String(version || "").trim().match(/^v?(\d+)\.(\d+)\.(\d+)/);
19
+ if (!match) return null;
20
+ return match.slice(1).map(Number);
21
+ }
22
+
23
+ function compareSemver(a, b) {
24
+ const parsedA = parseSemver(a);
25
+ const parsedB = parseSemver(b);
26
+ if (!parsedA || !parsedB) return 0;
27
+ for (let i = 0; i < 3; i++) {
28
+ const diff = parsedA[i] - parsedB[i];
29
+ if (diff !== 0) return diff;
30
+ }
31
+ return 0;
32
+ }
33
+
34
+ function readCache(cacheFile) {
35
+ try {
36
+ return JSON.parse(fs.readFileSync(cacheFile, "utf8"));
37
+ } catch (_) {
38
+ return null;
39
+ }
40
+ }
41
+
42
+ function writeCache(cacheFile, data) {
43
+ try {
44
+ fs.mkdirSync(path.dirname(cacheFile), { recursive: true });
45
+ fs.writeFileSync(cacheFile, JSON.stringify(data), "utf8");
46
+ } catch (_) {
47
+ // Version checks must never block normal CLI commands.
48
+ }
49
+ }
50
+
51
+ function fetchLatestVersion(pkg = DEFAULT_PKG) {
52
+ return runSilent("npm", ["view", pkg, "version"], { timeout: 3000 }).toString().trim();
53
+ }
54
+
55
+ function shouldSkip(args, env) {
56
+ const cmd = args[0];
57
+ return (
58
+ env.PIPPIT_CLI_DISABLE_UPDATE_CHECK === "1" ||
59
+ env.CI ||
60
+ cmd === "install" ||
61
+ cmd === "update"
62
+ );
63
+ }
64
+
65
+ function maybeWarnNewVersion(args = [], opts = {}) {
66
+ const env = opts.env || process.env;
67
+ if (shouldSkip(args, env)) return;
68
+
69
+ const now = opts.now || Date.now();
70
+ const cacheFile = opts.cacheFile || defaultCacheFile();
71
+ const cache = readCache(cacheFile);
72
+ const cacheFresh = cache && now - cache.checkedAt < CHECK_INTERVAL_MS;
73
+
74
+ let latest = cacheFresh ? cache.latest : "";
75
+ if (!latest) {
76
+ try {
77
+ latest = (opts.fetchLatestVersion || fetchLatestVersion)(opts.pkg || DEFAULT_PKG);
78
+ writeCache(cacheFile, { latest, checkedAt: now });
79
+ } catch (_) {
80
+ return;
81
+ }
82
+ }
83
+
84
+ const current = opts.currentVersion || currentVersion();
85
+ if (compareSemver(latest, current) <= 0) return;
86
+
87
+ const warn = opts.warn || console.error;
88
+ warn(`[pippit-cli] New version available: ${current} -> ${latest}. Run: pippit-cli update`);
89
+ }
90
+
91
+ module.exports = {
92
+ CHECK_INTERVAL_MS,
93
+ compareSemver,
94
+ maybeWarnNewVersion,
95
+ parseSemver,
96
+ };