pinglet-cli 0.4.0 → 0.5.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 +21 -0
- package/README.ja.md +3 -3
- package/README.ko.md +3 -3
- package/README.md +3 -3
- package/dist/adapters/claude.js +10 -1
- package/dist/api.js +1 -1
- package/dist/cli.js +3 -2
- package/dist/commands/login.js +20 -11
- package/dist/commands/post.js +1 -1
- package/dist/commands/statusline.js +4 -3
- package/package.json +1 -1
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 mabyko
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.ja.md
CHANGED
|
@@ -42,11 +42,11 @@ Claude Code セッションの中からそのまま:
|
|
|
42
42
|
またはターミナルから:
|
|
43
43
|
|
|
44
44
|
```bash
|
|
45
|
-
pinglet login # GitHub ログイン — ブラウザが開き自動で完了します(初回のみ)
|
|
45
|
+
pinglet login # GitHub または Google ログイン — ブラウザが開き自動で完了します(初回のみ)
|
|
46
46
|
pinglet post "メッセージ"
|
|
47
47
|
```
|
|
48
48
|
|
|
49
|
-
|
|
49
|
+
読むだけならログイン不要で、**投稿にのみログイン(GitHub または Google)が必要です。**
|
|
50
50
|
|
|
51
51
|
いま何個のターミナルが一緒に起動しているかが statusline に表示されます:
|
|
52
52
|
|
|
@@ -67,7 +67,7 @@ statusline の言語はシステム言語に応じて自動選択されます(
|
|
|
67
67
|
| コマンド | 説明 |
|
|
68
68
|
|---|---|
|
|
69
69
|
| `pinglet install` | Claude Code に接続(Codex は `--codex` でオプトイン) |
|
|
70
|
-
| `pinglet login` | GitHub
|
|
70
|
+
| `pinglet login [--github \| --google]` | GitHub または Google アカウントを連携(投稿に必要)。フラグ省略時はブラウザで選択 |
|
|
71
71
|
| `pinglet post "メッセージ"` | Ping を送る |
|
|
72
72
|
| `pinglet ping` | いま表示されるメッセージをプレビュー |
|
|
73
73
|
| `pinglet doctor` | インストール・接続状態を診断 |
|
package/README.ko.md
CHANGED
|
@@ -42,11 +42,11 @@ Claude Code 세션 안에서 바로:
|
|
|
42
42
|
또는 터미널에서:
|
|
43
43
|
|
|
44
44
|
```bash
|
|
45
|
-
pinglet login # GitHub 로그인 — 브라우저가 열리고 자동으로 완료됩니다 (최초 1회)
|
|
45
|
+
pinglet login # GitHub 또는 Google 로그인 — 브라우저가 열리고 자동으로 완료됩니다 (최초 1회)
|
|
46
46
|
pinglet post "메시지"
|
|
47
47
|
```
|
|
48
48
|
|
|
49
|
-
읽기는 로그인 없이 가능하고, **작성에만 GitHub
|
|
49
|
+
읽기는 로그인 없이 가능하고, **작성에만 로그인(GitHub 또는 Google)이 필요합니다.**
|
|
50
50
|
|
|
51
51
|
지금 몇 개의 터미널이 함께 켜져 있는지는 statusline에서 보여줍니다:
|
|
52
52
|
|
|
@@ -67,7 +67,7 @@ statusline 언어는 시스템 언어에 따라 자동 선택됩니다(한국어
|
|
|
67
67
|
| 명령 | 설명 |
|
|
68
68
|
|---|---|
|
|
69
69
|
| `pinglet install` | Claude Code 연결 (Codex는 `--codex`로 opt-in) |
|
|
70
|
-
| `pinglet login` | GitHub 계정 연결 (메시지 작성에 필요) |
|
|
70
|
+
| `pinglet login [--github \| --google]` | GitHub 또는 Google 계정 연결 (메시지 작성에 필요). 플래그가 없으면 브라우저에서 선택 |
|
|
71
71
|
| `pinglet post "메시지"` | Ping 보내기 |
|
|
72
72
|
| `pinglet ping` | 지금 표시될 메시지 미리보기 |
|
|
73
73
|
| `pinglet doctor` | 설치·연결 상태 진단 |
|
package/README.md
CHANGED
|
@@ -42,11 +42,11 @@ Right from a Claude Code session:
|
|
|
42
42
|
Or from the terminal:
|
|
43
43
|
|
|
44
44
|
```bash
|
|
45
|
-
pinglet login # GitHub login — opens a browser and completes automatically (once)
|
|
45
|
+
pinglet login # GitHub or Google login — opens a browser and completes automatically (once)
|
|
46
46
|
pinglet post "message"
|
|
47
47
|
```
|
|
48
48
|
|
|
49
|
-
Reading requires no login; **only posting requires a GitHub
|
|
49
|
+
Reading requires no login; **only posting requires a login (GitHub or Google).**
|
|
50
50
|
|
|
51
51
|
The statusline shows how many terminals are coding alongside you right now:
|
|
52
52
|
|
|
@@ -67,7 +67,7 @@ left untouched). To opt out, add `"autoUpdate": false` to `~/.pinglet/config.jso
|
|
|
67
67
|
| Command | Description |
|
|
68
68
|
|---|---|
|
|
69
69
|
| `pinglet install` | Connect to Claude Code (opt in to Codex with `--codex`) |
|
|
70
|
-
| `pinglet login` | Link your GitHub account (required for posting) |
|
|
70
|
+
| `pinglet login [--github \| --google]` | Link your GitHub or Google account (required for posting). Without a flag you pick in the browser |
|
|
71
71
|
| `pinglet post "message"` | Send a Ping |
|
|
72
72
|
| `pinglet ping` | Preview the message that would be shown now |
|
|
73
73
|
| `pinglet doctor` | Diagnose installation and connection status |
|
package/dist/adapters/claude.js
CHANGED
|
@@ -73,6 +73,11 @@ function detectClaude() {
|
|
|
73
73
|
function statusLineCommand() {
|
|
74
74
|
return `node "${(0, config_1.cliPath)()}" statusline`;
|
|
75
75
|
}
|
|
76
|
+
/**
|
|
77
|
+
* statusline 이벤트 트리거는 유휴 세션에서 멈추므로(새 메시지가 있어야 재실행),
|
|
78
|
+
* 유휴 pane이 옛 온라인 터미널 수를 계속 표시하지 않게 고정 주기(초)로도 재실행한다.
|
|
79
|
+
*/
|
|
80
|
+
const STATUSLINE_REFRESH_INTERVAL_S = 30;
|
|
76
81
|
/** 예전 버전이 등록한 hook entry인지 식별 (command에 hook-prompt 포함 여부). */
|
|
77
82
|
function isPingletHookEntry(entry) {
|
|
78
83
|
return (entry.hooks?.some((h) => typeof h.command === "string" && h.command.includes("hook-prompt")) ?? false);
|
|
@@ -336,7 +341,11 @@ function installClaudeIntegration(config, options = {}) {
|
|
|
336
341
|
...(existing && !isOurs && { statusLineBackup: existing }),
|
|
337
342
|
};
|
|
338
343
|
(0, config_1.saveConfig)(config);
|
|
339
|
-
settings.statusLine = {
|
|
344
|
+
settings.statusLine = {
|
|
345
|
+
type: "command",
|
|
346
|
+
command: statusLineCommand(),
|
|
347
|
+
refreshInterval: STATUSLINE_REFRESH_INTERVAL_S,
|
|
348
|
+
};
|
|
340
349
|
uninstallPromptHook(settings); // 구버전 hook 방식 흔적 정리
|
|
341
350
|
// /pinglet 인라인 bash가 auto 모드 분류기에 막히지 않도록 allow 규칙 등록.
|
|
342
351
|
// 경로가 바뀐(예: node 버전 업) 옛 규칙은 정리하고 현재 규칙 하나만 둔다.
|
package/dist/api.js
CHANGED
|
@@ -134,7 +134,7 @@ async function sendHeartbeat(config, record) {
|
|
|
134
134
|
}
|
|
135
135
|
/**
|
|
136
136
|
* POST /messages — 메시지 작성 (분당 5개 제한).
|
|
137
|
-
* 작성은 GitHub
|
|
137
|
+
* 작성은 로그인(GitHub 또는 Google)이 필요하다 (읽기는 계속 익명).
|
|
138
138
|
*/
|
|
139
139
|
async function createMessage(config, text, category) {
|
|
140
140
|
const token = config.userToken;
|
package/dist/cli.js
CHANGED
|
@@ -19,8 +19,9 @@ const HELP = `pinglet v${config_1.VERSION} — AI가 생각하는 동안 만나
|
|
|
19
19
|
install [--api <url>] [--force] Claude Code integration 설치
|
|
20
20
|
[--claude | --codex] Codex는 OS 알림 방식이라 --codex로 opt-in (experimental)
|
|
21
21
|
uninstall [--purge] integration 제거 (--purge: ~/.pinglet까지 삭제)
|
|
22
|
-
login [--
|
|
23
|
-
|
|
22
|
+
login [--github | --google] 계정 연결 (GitHub 또는 Google, 생략 시 브라우저에서 선택)
|
|
23
|
+
[--token <jwt>]
|
|
24
|
+
post "메시지" [--category <c>] 메시지 작성 (로그인 필요, 읽기는 익명 가능)
|
|
24
25
|
doctor 설치/캐시/서버 상태 진단
|
|
25
26
|
ping 메시지 미리보기
|
|
26
27
|
|
package/dist/commands/login.js
CHANGED
|
@@ -72,12 +72,11 @@ div{text-align:center}p{color:#8b93a3}</style></head><body><div>
|
|
|
72
72
|
<h1>${ok ? "💌 로그인 완료" : "✗ 로그인 실패"}</h1>
|
|
73
73
|
<p>${ok ? "이 창을 닫고 터미널로 돌아가세요." : "터미널에서 다시 시도해 주세요."}</p>
|
|
74
74
|
</div></body></html>`;
|
|
75
|
-
/**
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
function loginViaLoopback(apiBaseUrl) {
|
|
75
|
+
/** provider가 없으면 백엔드의 로그인 방식 선택 페이지(/auth/login)를 연다. */
|
|
76
|
+
function loginPath(provider) {
|
|
77
|
+
return provider ? `/auth/${provider}` : "/auth/login";
|
|
78
|
+
}
|
|
79
|
+
function loginViaLoopback(apiBaseUrl, provider) {
|
|
81
80
|
return new Promise((resolve) => {
|
|
82
81
|
let finished = false;
|
|
83
82
|
const done = (token) => {
|
|
@@ -108,14 +107,19 @@ function loginViaLoopback(apiBaseUrl) {
|
|
|
108
107
|
server.on("error", () => done(null));
|
|
109
108
|
server.listen(0, "127.0.0.1", () => {
|
|
110
109
|
const port = server.address().port;
|
|
111
|
-
const url = `${apiBaseUrl}
|
|
112
|
-
console.log(
|
|
110
|
+
const url = `${apiBaseUrl}${loginPath(provider)}?cli_port=${port}`;
|
|
111
|
+
console.log(provider
|
|
112
|
+
? `브라우저에서 ${provider === "google" ? "Google" : "GitHub"} 로그인을 완료해 주세요…`
|
|
113
|
+
: "브라우저에서 GitHub 또는 Google 로그인을 완료해 주세요…");
|
|
113
114
|
console.log(` ${url}\n`);
|
|
114
115
|
openBrowser(url);
|
|
115
116
|
});
|
|
116
117
|
});
|
|
117
118
|
}
|
|
118
|
-
/**
|
|
119
|
+
/**
|
|
120
|
+
* 소셜 로그인(GitHub/Google) — 루프백 자동 수신, 실패 시 수동 붙여넣기 폴백.
|
|
121
|
+
* `--github` / `--google`로 방식을 고정하고, 없으면 브라우저에서 고른다.
|
|
122
|
+
*/
|
|
119
123
|
async function runLogin(args) {
|
|
120
124
|
const config = (0, config_1.loadConfig)();
|
|
121
125
|
let token;
|
|
@@ -123,13 +127,18 @@ async function runLogin(args) {
|
|
|
123
127
|
if (tokenIndex !== -1 && args[tokenIndex + 1]) {
|
|
124
128
|
token = args[tokenIndex + 1];
|
|
125
129
|
}
|
|
130
|
+
const provider = args.includes("--google")
|
|
131
|
+
? "google"
|
|
132
|
+
: args.includes("--github")
|
|
133
|
+
? "github"
|
|
134
|
+
: undefined;
|
|
126
135
|
if (!token) {
|
|
127
136
|
console.log(`\n로그인하면 이용약관(${config.apiBaseUrl}/terms)과 개인정보처리방침(${config.apiBaseUrl}/privacy)에 동의하는 것으로 간주됩니다.`);
|
|
128
|
-
token = (await loginViaLoopback(config.apiBaseUrl)) ?? undefined;
|
|
137
|
+
token = (await loginViaLoopback(config.apiBaseUrl, provider)) ?? undefined;
|
|
129
138
|
if (!token) {
|
|
130
139
|
// SSH 등 브라우저와 터미널이 다른 기계인 경우를 위한 폴백.
|
|
131
140
|
console.log("자동 로그인에 실패했습니다. 아래 URL에서 로그인 후 응답 JSON의 token 값을 붙여넣어 주세요.");
|
|
132
|
-
console.log(` ${config.apiBaseUrl}
|
|
141
|
+
console.log(` ${config.apiBaseUrl}${loginPath(provider)}\n`);
|
|
133
142
|
token = (await prompt("token: ")).trim();
|
|
134
143
|
}
|
|
135
144
|
}
|
package/dist/commands/post.js
CHANGED
|
@@ -45,7 +45,7 @@ async function runPost(args) {
|
|
|
45
45
|
if (!result.ok) {
|
|
46
46
|
switch (result.error) {
|
|
47
47
|
case "LOGIN_REQUIRED":
|
|
48
|
-
console.log("✗ 메시지 작성에는 GitHub
|
|
48
|
+
console.log("✗ 메시지 작성에는 로그인(GitHub 또는 Google)이 필요합니다. `pinglet login`을 실행하세요 (읽기는 로그인 없이 가능).");
|
|
49
49
|
break;
|
|
50
50
|
case "UNAUTHORIZED":
|
|
51
51
|
console.log("✗ 로그인이 만료됐습니다. `pinglet login`으로 다시 로그인하세요.");
|
|
@@ -43,10 +43,11 @@ const queue_1 = require("../queue");
|
|
|
43
43
|
const claude_1 = require("../adapters/claude");
|
|
44
44
|
const runtime_1 = require("../runtime");
|
|
45
45
|
/**
|
|
46
|
-
* online 캐시 유효 기간 — refresh(≈5분)
|
|
47
|
-
*
|
|
46
|
+
* online 캐시 유효 기간 — refresh(≈5분) 2주기. 서버의 온라인 판정 창
|
|
47
|
+
* (ONLINE_WINDOW_MS 10분)과 정렬해, 서버가 이미 오프라인으로 세는 시점에
|
|
48
|
+
* 클라이언트가 옛 숫자를 "지금"이라고 보여주지 않게 한다.
|
|
48
49
|
*/
|
|
49
|
-
const ONLINE_STALE_MS =
|
|
50
|
+
const ONLINE_STALE_MS = 10 * 60_000;
|
|
50
51
|
/** 신선한 online 캐시가 있을 때, 나를 제외한 켜진 터미널 수 (없거나 혼자면 null). */
|
|
51
52
|
function onlineOthers(now) {
|
|
52
53
|
const cache = (0, cache_1.loadOnline)();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pinglet-cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"description": "Short messages from other developers shown in your Claude Code spinner while the AI thinks — zero tokens, never reads your code. Claude Code / Codex integration",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|