planbee 0.1.0 → 0.1.1
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 +50 -39
- package/bin/planbee.js +1 -1
- package/package.json +2 -6
package/README.md
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
# PlanBee CLI
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
Claude
|
|
3
|
+
Command-line client for [PlanBee](https://planbee.cloud) — agent coordination,
|
|
4
|
+
Claude Code hooks and voice notifications.
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
This package is a client. It requires a PlanBee server (cloud or self-hosted)
|
|
7
|
+
and is not usable without access to one. Get started at
|
|
8
|
+
[planbee.cloud](https://planbee.cloud).
|
|
8
9
|
|
|
9
10
|
## Installation
|
|
10
11
|
|
|
@@ -13,64 +14,74 @@ npm install -g planbee
|
|
|
13
14
|
planbee --version
|
|
14
15
|
```
|
|
15
16
|
|
|
16
|
-
Node.js 18
|
|
17
|
+
Node.js 18 or newer.
|
|
17
18
|
|
|
18
|
-
##
|
|
19
|
+
## Updating
|
|
20
|
+
|
|
21
|
+
npm does not update global packages automatically. To upgrade to the latest
|
|
22
|
+
release:
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
npm install -g planbee@latest
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Login
|
|
19
29
|
|
|
20
30
|
```bash
|
|
21
31
|
planbee auth login --email you@example.com
|
|
22
32
|
```
|
|
23
33
|
|
|
24
|
-
|
|
25
|
-
`~/.planbee/cli-auth.json`
|
|
26
|
-
|
|
34
|
+
This creates a long-lived CLI token (PAT) and stores it in
|
|
35
|
+
`~/.planbee/cli-auth.json` with `0600` permissions. Alternatively, an existing
|
|
36
|
+
token can be stored with `planbee auth login --token <token>`.
|
|
27
37
|
|
|
28
|
-
|
|
38
|
+
Against your own server:
|
|
29
39
|
|
|
30
40
|
```bash
|
|
31
|
-
planbee --local <
|
|
32
|
-
PLANBEE_API_URL=https://… planbee … #
|
|
41
|
+
planbee --local <command> # http://localhost:3456
|
|
42
|
+
PLANBEE_API_URL=https://… planbee … # any endpoint
|
|
33
43
|
```
|
|
34
44
|
|
|
35
|
-
##
|
|
45
|
+
## What is sent to the server
|
|
36
46
|
|
|
37
|
-
|
|
47
|
+
The client is not a read-only viewer. So you know what happens:
|
|
38
48
|
|
|
39
|
-
- **Session
|
|
40
|
-
|
|
41
|
-
- **Claude
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
- **
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
49
|
+
- **Session and task data:** topic, task list, progress, status and the state
|
|
50
|
+
objects you set yourself (`planbee progress`).
|
|
51
|
+
- **Claude Code transcripts:** once the hooks are installed, the client reads the
|
|
52
|
+
conversation files under `~/.claude/projects/<project>/<session>.jsonl`
|
|
53
|
+
incrementally and uploads the new lines to the server so the conversation is
|
|
54
|
+
visible in the dashboard. This includes **the complete history, including your
|
|
55
|
+
prompts and the model responses.**
|
|
56
|
+
- **Machine name:** when a CLI token is created, the hostname is sent as the
|
|
57
|
+
token label (`cli-<hostname>`) so you can tell tokens apart.
|
|
58
|
+
- **Messages** between agents and the text of voice notifications
|
|
59
|
+
(`planbee speak`).
|
|
50
60
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
61
|
+
Without installed hooks, no transcripts are transferred. Hooks are only set up
|
|
62
|
+
by `planbee hooks install`; the command writes to the `.claude/settings.json`
|
|
63
|
+
of the given project.
|
|
54
64
|
|
|
55
|
-
|
|
56
|
-
|
|
65
|
+
If you run your own server (`--local` / `PLANBEE_API_URL`), this data goes
|
|
66
|
+
there exclusively.
|
|
57
67
|
|
|
58
68
|
## Hooks
|
|
59
69
|
|
|
60
70
|
```bash
|
|
61
|
-
planbee hooks install --project /
|
|
71
|
+
planbee hooks install --project /path/to/project
|
|
62
72
|
planbee hooks status
|
|
63
73
|
```
|
|
64
74
|
|
|
65
|
-
##
|
|
75
|
+
## Author and support
|
|
66
76
|
|
|
67
|
-
|
|
77
|
+
[planbee.cloud](https://planbee.cloud) — infin8 world llc,
|
|
78
|
+
[www.infin8.world](https://www.infin8.world)
|
|
68
79
|
|
|
69
|
-
##
|
|
80
|
+
## License
|
|
70
81
|
|
|
71
|
-
|
|
72
|
-
|
|
82
|
+
Proprietary, see `LICENSE`: use as a client is permitted, resale and reuse of
|
|
83
|
+
the source code are not.
|
|
73
84
|
|
|
74
|
-
|
|
75
|
-
`THIRD-PARTY-NOTICES.txt` (44
|
|
76
|
-
`bin/planbee.js.LEGAL.txt`;
|
|
85
|
+
The license texts of the bundled open-source packages are included in full in
|
|
86
|
+
`THIRD-PARTY-NOTICES.txt` (44 packages, MIT/ISC) and in
|
|
87
|
+
`bin/planbee.js.LEGAL.txt`; for those components they take precedence.
|
package/bin/planbee.js
CHANGED
|
@@ -392,7 +392,7 @@ Found ${Fe.bold(n.length)} sessions (${Fe.green(`${s.length} new`)}, ${Fe.gray(`
|
|
|
392
392
|
`),console.log(Fe.bold(" Provider Session ID Project First Prompt Date")),console.log(` ${"\u2500".repeat(95)}`);for(let r of n){let i=mB[r.provider]||"\u26AA",a=r.provider.padEnd(10),c=(r.sessionId||"").substring(0,8),l=(r.projectName||"\u2014").substring(0,14).padEnd(14),u=(r.firstPrompt||r.summary||"\u2014").substring(0,35).padEnd(35),p=r.timestamps?.modified?new Date(r.timestamps.modified).toLocaleDateString():"\u2014",d=r.alreadyImported?Fe.gray(" \u2713"):Fe.green(" \u2605");console.log(`${d} ${i} ${a} ${c} ${l} ${u} ${p}`)}if((t.import||t.importAll)&&s.length>0){console.log(`
|
|
393
393
|
${Fe.cyan(`Importing ${s.length} sessions...`)}`);try{let i=(await JE.post(`${ji}/api/v1/sessions/discover/import`,{sessions:s},{timeout:6e4})).data;if(console.log(Fe.green(`\u2713 Imported: ${i.imported}`)),i.skipped>0&&console.log(Fe.yellow(`\u2298 Skipped: ${i.skipped}`)),i.failed?.length>0){console.log(Fe.red(`\u2717 Failed: ${i.failed.length}`));for(let a of i.failed)console.log(Fe.red(` - ${a.sessionId}: ${a.error}`))}}catch(r){console.error(Fe.red(`Error: import failed, PlanBee API unreachable (${ji}/api/v1/sessions/discover/import).`)),console.error(Fe.red(` ${r.message}`)),process.exit(1)}}else s.length>0&&!t.import&&!t.importAll&&console.log(`
|
|
394
394
|
${Fe.gray("Use --import or --import-all to import new sessions.")}`)}catch(e){console.error(Fe.red(`Error: ${e.message}`)),process.exit(1)}}}});var XE=D((cU,YE)=>{function hB(t,e={}){let n=["CLI Authentication Status"],s=t||{},o=e.patSnapshot,r=e.jwtSnapshot;if(o){let i=o.daysOld!=null?`${o.daysOld}d`:"?",a=VE(s,"pat",!1);n.push(` PAT (cli-auth.json): ${a} (age ${i})`)}else n.push(" PAT (cli-auth.json): --");if(r){let i=gB(r.minutesLeft),a=VE(s,"jwt",!!r.expired);n.push(` JWT (auth.json): ${a} (${i})`)}else n.push(" JWT (auth.json): --");return s.kind?n.push(` Active source: ${s.kind.toUpperCase()}`):n.push(" Active source: none"),s.email&&n.push(` Account: ${s.email}`),s.valid||(n.push(""),s.errorCode==="MISSING_TOKEN"?(n.push(" No CLI token found. Run:"),n.push(" planbee auth login --github")):s.expiredError?(n.push(""),n.push(" Token rejected. Run ONE of:"),n.push(" planbee auth login --github (opens browser, easiest)"),n.push(" planbee auth login --google"),n.push(" planbee auth login --email <you> --password <pw>")):(s.errorCode==="TRANSIENT"||s.errorCode==="NETWORK")&&(n.push(""),n.push(` Cannot reach server right now (${s.errorCode}: ${s.errorMessage||"n/a"}).`),n.push(" Token may still be valid; will retry on next command."))),n.join(`
|
|
395
|
-
`)}YE.exports={formatAuthStatus:hB};function VE(t,e,n){return t.kind!==e?n?"expired":"standby":t.valid?"valid":t.expiredError?"EXPIRED":"unreachable"}function gB(t){return t==null?"?":t<0?"expired":`${t}m left`}});var tD=D((lU,eD)=>{var QE=de(),yB=require("os"),Zn=it(),{resolveApiUrl:ZE}=te(),bB=ci(),{formatAuthStatus:xB}=XE();async function vB(t,e,n){let s=ZE(n),o;try{o=(await QE.post(`${s}/auth/login`,{email:t,password:e},{timeout:1e4})).data}catch(l){let u=l.response?.data?.error||l.response?.data?.details||l.message;throw new Error(`Login failed: ${u}`)}let r=o.access_token||o.session?.access_token;if(!r)throw new Error("Login failed: no access token in server response");let i;try{i=await QE.post(`${s}/api/v1/cli-tokens`,{name:`cli-${yB.hostname()}`},{headers:{Authorization:`Bearer ${r}`},timeout:1e4})}catch(l){let u=l.response?.data?.error||l.message;throw new Error(`Could not issue CLI token: ${u}`)}let{token:a}=i.data;if(!a)throw new Error("Could not issue CLI token: server returned no token");let c=o.user||o.session?.user||{};Zn.save({token:a,api_url:s,user:{id:c.id||null,email:c.email||t},created_at:new Date().toISOString()}),n.json?console.log(JSON.stringify({success:!0,user:{email:c.email||t}},null,2)):(console.log("Login successful"),console.log(`Welcome, ${c.email||t}`))}async function wB(t){if(t.github||t.google){console.error(`Error: OAuth login (--${t.github?"github":"google"}) is not available in the standalone planbee CLI. Use --email/--password, or log in via the PlanBee app and run \`planbee auth login --token <pat>\`.`),process.exit(1);return}if(t.token){Zn.save({token:t.token,api_url:ZE(t),user:null,created_at:new Date().toISOString()}),console.log("Token saved to ~/.planbee/cli-auth.json");return}let{email:e,password:n}=t;(!e||!n)&&(console.error("Error: Email and password are required"),console.error("Usage: planbee auth login --email <email> --password <pass>"),console.error(" Or: planbee auth login --token <personal-access-token>"),process.exit(1));try{await vB(e,n,t)}catch(s){t.json?console.log(JSON.stringify({success:!1,error:s.message},null,2)):console.error(s.message),process.exit(1)}}async function EB(t){let e=Zn.load();if(!e||!e.token){t.json?console.log(JSON.stringify({success:!0,message:"Already logged out"})):console.log("Not logged in");return}Zn.clear(),t.json?console.log(JSON.stringify({success:!0,message:"Logged out successfully"})):console.log("Logged out successfully")}async function DB(t){let e=await bB.validateAuth();if(t.json){console.log(JSON.stringify({authenticated:e.valid,user:e.user||(e.email?{email:e.email}:null),active_source:e.kind,pat:e.kind==="pat"?{store:e.store,daysOld:e.daysOld}:null,error:e.expiredError?{code:e.errorCode,message:e.expiredError.message}:null},null,2));return}let n=Zn.load(),s=n&&n.token?{daysOld:e.kind==="pat"?e.daysOld:null}:null;console.log(xB(e,{patSnapshot:s,jwtSnapshot:null}))}async function SB(t,e){switch(t){case"login":await wB(e);break;case"logout":await EB(e);break;case"status":case"whoami":await DB(e);break;default:console.error(`Unknown auth subcommand: ${t}`),console.error("Available subcommands: login, logout, status"),process.exit(1)}}eD.exports={authCommand:SB,loadToken:Zn.load.bind(Zn)}});var nD=D((uU,kB)=>{kB.exports={name:"planbee",version:"0.1.0",description:"PlanBee CLI - agent coordination, hooks, and voice notifications for Claude Code",license:"SEE LICENSE IN LICENSE",bin:{planbee:"bin/planbee.js"},files:["bin","LICENSE","THIRD-PARTY-NOTICES.txt"],engines:{node:">=18"},scripts:{build:"node scripts/build.js && node scripts/third-party-notices.js",prepublishOnly:"npm run build"},dependencies:{},devDependencies:{axios:"^1.6.2",yargs:"^17.7.2",i18next:"^26.2.0",esbuild:"^0.24.0"},repository:{type:"git",url:"git+https://git.infin8.world/infin8/planbee-cli.git"},author:"infin8 world llc (https://www.infin8.world)",homepage:"https://www.infin8.world"}});var AB=de(),{resolveApiUrl:_B}=te(),{isLinearEnabled:CB}=nh(),{validatePathAbsolute:OB}=Qa(),TB=`${_B()}/notify`,sD=1,oD=5e3,rD=100,PB=.5,$B=2,NB=0,IB=1,RB=["info","success","error","warning","progress","question","joke","finished_user_interaction_required"],FB=["happy","sad","excited","serious","calm","neutral","cheerful"],Ku=0,cD=1,Vo=2,zu=3;function lD(t){return!t||t.length<sD?`Message must be at least ${sD} character`:t.length>oD?`Message must not exceed ${oD} characters`:null}function uD(t){return t&&t.length>rD?`Title must not exceed ${rD} characters`:null}function pD(t){return OB(t)}function Wu(t,e,n,s){let o=parseFloat(t);return Number.isNaN(o)?`${s} must be a valid number`:o<e||o>n?`${s} must be between ${e} and ${n}`:null}function dD(t,e){return t&&!e||!t&&e?"Both --project and --path must be provided together":null}function iD(t,e=!1){e||console.error(`Error: ${t}`)}function aD(t,e=!1,n=!1){e||console.log(n?JSON.stringify(t,null,2):t)}function fD(t){let{id:e,status:n}=t;return n==="queued"?`[OK] Message queued (ID: ${e})`:`[OK] Message sent (ID: ${e})`}async function mD(t){let e={message:t.message};t.project&&t.path&&(e.project=t.project,e.path=t.path),t.type&&(e.type=t.type),t.title&&(e.title=t.title),t.mood&&(e.mood=t.mood),t.speed!==void 0&&(e.speech_speed=parseFloat(t.speed)),t.volume!==void 0&&(e.volume=parseFloat(t.volume)),t.voiceId&&(e.voice_id=t.voiceId);try{return{success:!0,data:(await AB.post(TB,e,{headers:{"Content-Type":"application/json"},timeout:5e3})).data}}catch(n){if(n.code==="ECONNREFUSED"||n.code==="ETIMEDOUT")return{success:!1,error:"Cannot connect to PlanBee server",exitCode:zu};if(n.response){let{status:s,data:o}=n.response;return s===503?{success:!1,error:"PlanBee server is offline",exitCode:zu}:s===404?{success:!1,error:"Project not found. Use --register to register project first.",exitCode:Vo}:{success:!1,error:`HTTP ${s}: ${o.error||o.message||"Unknown error"}`,exitCode:Vo}}return{success:!1,error:n.message||"Unknown error occurred",exitCode:Vo}}}function hD(){return process.argv.includes("--json")}var Ju={tasks:"planbee tasks <session-id> --json",status:"planbee status <session-id> --json",transcript:"planbee transcript <session-id> --json",send:'planbee send <session-id> "<message>" --json',spawn:'planbee spawn --task "<task>" --json'};function gD(){let t=process.argv[2];return t&&Ju[t]?Ju[t]:"planbee --help --json"}function yD(){return function(e,n,s){if(!e&&!n)return;let o=e||n?.message||"Unknown error";if(hD()){let r=gD();console.log(JSON.stringify({error:!0,message:o,suggestion:r})),process.exit(1)}else console.error(`Error: ${o}`),s.showHelp(),process.exit(1)}}async function jB(){let t=Fg(),{hideBin:e}=Lg(),n=Hg(),s=Wg(),o=Kg(),r=Qg(),i=ey(),a=ny(),c=iy(),l=uy(),u=dy(),p=my(),d=gy(),f=by(),m=vy(),h=Ey(),g=Sy(),b=_y(),v=Oy(),E=rx(),S=dx(),C=Rx(),B=hv(),L=wv(),$=Av(),I=Cv(),R=Pv(),U=Bv(),Q=Uv(),M=Wv(),z=Gv(),ge=Yv(),oe=Zv(),xe=nw(),Ee=gw(),ve=Ew(),Me=kw(),F=Ou(),H=T0(),W=N0(),N=z0(),ce=Q0(),pe=eE(),Z=nE(),me=oE(),_e=aE(),ie=lE(),Ue=pE(),ze=fE(),le=hE(),Xe=CE(),w=TE(),_=$E(),j=IE(),A=LE(),k=UE(),P=WE(),O=GE(),{authCommand:q}=tD(),G=await t(e(process.argv)).scriptName("planbee").version(nD().version).fail(yD()).usage("Usage: $0 <command> [options]").command(n).command(CB()?[{command:"linear",describe:"Linear integration commands",builder:ae=>ae.command(s).command(o).command(r).command(i).command(a).command(c).command(l).command(u).command(p).command(d).command(f).command(m).command(h).command(g).command(b).demandCommand(1,"You need to specify a linear subcommand").help(),handler:()=>{}}]:[]).command("auth <subcommand>","Authentication commands (login, logout, whoami)",ae=>ae.positional("subcommand",{describe:"Auth subcommand",choices:["login","logout","status","whoami"]}).option("email",{type:"string",description:"Email address"}).option("password",{type:"string",description:"Password"}).option("token",{type:"string",description:"Existing personal access token to store directly"}),async ae=>{await q(ae.subcommand,ae)}).command(E).command(S).command(oe).command(xe).command(Ee).command(C.send).command(C.sendToQueen).command(B).command(L).command($).command(Q).command("swarm","Swarm management commands",ae=>ae.command(M).command(z).demandCommand(1,"You need to specify a swarm subcommand").help()).command("providers","Provider management commands",ae=>ae.command(ge).demandCommand(1,"You need to specify a providers subcommand").help()).command("memory","Memory management commands",ae=>ae.command(I.store).command(I.get).command(I.list).command(I.delete).command(I.export).command(I.import).command(I.cleanup).command(I.history).command(I.diff).demandCommand(1,"You need to specify a memory subcommand").help()).command(R.agent).command(U.listChildren).command(ve).command(Me).command(F).command(H).command(W).command(v).command("audio","Audio and TTS configuration",ae=>ae.command(N).demandCommand(1,"You need to specify an audio subcommand").help()).command("hooks","Manage PlanBee hooks in projects",ae=>ae.command(ce).command(pe).command(Z).demandCommand(1,"You need to specify a hooks subcommand").help()).command("search","Search agents and transcripts",ae=>ae.command(me).command(_e).demandCommand(1,"You need to specify a search subcommand").help()).command(ie).command(Ue).command(ze).command(le).command(Xe).command(w).command(_).command(j).command(A).command(k).command(P).command(O).option("project",{type:"string",description:"Project identifier",global:!1}).option("path",{type:"string",description:"Absolute project path",global:!1}).option("message",{type:"string",description:"Message to send (1-5000 characters)",global:!1}).option("type",{type:"string",description:"Message type",choices:RB,default:"info",global:!1}).option("title",{type:"string",description:"Short title (max 100 chars)",global:!1}).option("mood",{type:"string",description:"Voice mood",choices:FB,default:"neutral",global:!1}).option("speed",{type:"number",description:"Speech speed (0.5-2.0)",default:1,global:!1}).option("volume",{type:"number",description:"Volume (0.0-1.0)",default:.8,global:!1}).option("voice-id",{type:"string",description:"Override voice selection",global:!1}).option("quiet",{type:"boolean",description:"Suppress stdout",default:!1,global:!1}).option("json",{type:"boolean",description:"Output JSON response",default:!1,global:!1}).option("local",{type:"boolean",description:"Use local dev server (http://localhost:3456) instead of cloud",default:!1,global:!0,coerce:ae=>(ae&&(process.env.PLANBEE_MODE="local"),ae)}).help("h").alias("h","help").example('$0 --project myapp --path /home/user/myapp --message "Build complete"').example('$0 --message "Quick notification" --type success').example('$0 register --folder /path/to/workspace --task "Research task" --agent-type researcher').example('$0 spawn --type coder --task "Implement feature" --parent session-id-here').example(`$0 memory store --key task-status --value '{"status": "completed"}'`).epilogue(`Modes: cloud (default, https://planbee.infin8.world), local (--local / PLANBEE_MODE=local -> http://localhost:3456).
|
|
395
|
+
`)}YE.exports={formatAuthStatus:hB};function VE(t,e,n){return t.kind!==e?n?"expired":"standby":t.valid?"valid":t.expiredError?"EXPIRED":"unreachable"}function gB(t){return t==null?"?":t<0?"expired":`${t}m left`}});var tD=D((lU,eD)=>{var QE=de(),yB=require("os"),Zn=it(),{resolveApiUrl:ZE}=te(),bB=ci(),{formatAuthStatus:xB}=XE();async function vB(t,e,n){let s=ZE(n),o;try{o=(await QE.post(`${s}/auth/login`,{email:t,password:e},{timeout:1e4})).data}catch(l){let u=l.response?.data?.error||l.response?.data?.details||l.message;throw new Error(`Login failed: ${u}`)}let r=o.access_token||o.session?.access_token;if(!r)throw new Error("Login failed: no access token in server response");let i;try{i=await QE.post(`${s}/api/v1/cli-tokens`,{name:`cli-${yB.hostname()}`},{headers:{Authorization:`Bearer ${r}`},timeout:1e4})}catch(l){let u=l.response?.data?.error||l.message;throw new Error(`Could not issue CLI token: ${u}`)}let{token:a}=i.data;if(!a)throw new Error("Could not issue CLI token: server returned no token");let c=o.user||o.session?.user||{};Zn.save({token:a,api_url:s,user:{id:c.id||null,email:c.email||t},created_at:new Date().toISOString()}),n.json?console.log(JSON.stringify({success:!0,user:{email:c.email||t}},null,2)):(console.log("Login successful"),console.log(`Welcome, ${c.email||t}`))}async function wB(t){if(t.github||t.google){console.error(`Error: OAuth login (--${t.github?"github":"google"}) is not available in the standalone planbee CLI. Use --email/--password, or log in via the PlanBee app and run \`planbee auth login --token <pat>\`.`),process.exit(1);return}if(t.token){Zn.save({token:t.token,api_url:ZE(t),user:null,created_at:new Date().toISOString()}),console.log("Token saved to ~/.planbee/cli-auth.json");return}let{email:e,password:n}=t;(!e||!n)&&(console.error("Error: Email and password are required"),console.error("Usage: planbee auth login --email <email> --password <pass>"),console.error(" Or: planbee auth login --token <personal-access-token>"),process.exit(1));try{await vB(e,n,t)}catch(s){t.json?console.log(JSON.stringify({success:!1,error:s.message},null,2)):console.error(s.message),process.exit(1)}}async function EB(t){let e=Zn.load();if(!e||!e.token){t.json?console.log(JSON.stringify({success:!0,message:"Already logged out"})):console.log("Not logged in");return}Zn.clear(),t.json?console.log(JSON.stringify({success:!0,message:"Logged out successfully"})):console.log("Logged out successfully")}async function DB(t){let e=await bB.validateAuth();if(t.json){console.log(JSON.stringify({authenticated:e.valid,user:e.user||(e.email?{email:e.email}:null),active_source:e.kind,pat:e.kind==="pat"?{store:e.store,daysOld:e.daysOld}:null,error:e.expiredError?{code:e.errorCode,message:e.expiredError.message}:null},null,2));return}let n=Zn.load(),s=n&&n.token?{daysOld:e.kind==="pat"?e.daysOld:null}:null;console.log(xB(e,{patSnapshot:s,jwtSnapshot:null}))}async function SB(t,e){switch(t){case"login":await wB(e);break;case"logout":await EB(e);break;case"status":case"whoami":await DB(e);break;default:console.error(`Unknown auth subcommand: ${t}`),console.error("Available subcommands: login, logout, status"),process.exit(1)}}eD.exports={authCommand:SB,loadToken:Zn.load.bind(Zn)}});var nD=D((uU,kB)=>{kB.exports={name:"planbee",version:"0.1.1",description:"PlanBee CLI - agent coordination, hooks, and voice notifications for Claude Code",license:"SEE LICENSE IN LICENSE",bin:{planbee:"bin/planbee.js"},files:["bin","LICENSE","THIRD-PARTY-NOTICES.txt"],engines:{node:">=18"},scripts:{build:"node scripts/build.js && node scripts/third-party-notices.js",prepublishOnly:"npm run build"},dependencies:{},devDependencies:{axios:"^1.6.2",yargs:"^17.7.2",i18next:"^26.2.0",esbuild:"^0.24.0"},author:"infin8 world llc (https://www.infin8.world)",homepage:"https://planbee.cloud"}});var AB=de(),{resolveApiUrl:_B}=te(),{isLinearEnabled:CB}=nh(),{validatePathAbsolute:OB}=Qa(),TB=`${_B()}/notify`,sD=1,oD=5e3,rD=100,PB=.5,$B=2,NB=0,IB=1,RB=["info","success","error","warning","progress","question","joke","finished_user_interaction_required"],FB=["happy","sad","excited","serious","calm","neutral","cheerful"],Ku=0,cD=1,Vo=2,zu=3;function lD(t){return!t||t.length<sD?`Message must be at least ${sD} character`:t.length>oD?`Message must not exceed ${oD} characters`:null}function uD(t){return t&&t.length>rD?`Title must not exceed ${rD} characters`:null}function pD(t){return OB(t)}function Wu(t,e,n,s){let o=parseFloat(t);return Number.isNaN(o)?`${s} must be a valid number`:o<e||o>n?`${s} must be between ${e} and ${n}`:null}function dD(t,e){return t&&!e||!t&&e?"Both --project and --path must be provided together":null}function iD(t,e=!1){e||console.error(`Error: ${t}`)}function aD(t,e=!1,n=!1){e||console.log(n?JSON.stringify(t,null,2):t)}function fD(t){let{id:e,status:n}=t;return n==="queued"?`[OK] Message queued (ID: ${e})`:`[OK] Message sent (ID: ${e})`}async function mD(t){let e={message:t.message};t.project&&t.path&&(e.project=t.project,e.path=t.path),t.type&&(e.type=t.type),t.title&&(e.title=t.title),t.mood&&(e.mood=t.mood),t.speed!==void 0&&(e.speech_speed=parseFloat(t.speed)),t.volume!==void 0&&(e.volume=parseFloat(t.volume)),t.voiceId&&(e.voice_id=t.voiceId);try{return{success:!0,data:(await AB.post(TB,e,{headers:{"Content-Type":"application/json"},timeout:5e3})).data}}catch(n){if(n.code==="ECONNREFUSED"||n.code==="ETIMEDOUT")return{success:!1,error:"Cannot connect to PlanBee server",exitCode:zu};if(n.response){let{status:s,data:o}=n.response;return s===503?{success:!1,error:"PlanBee server is offline",exitCode:zu}:s===404?{success:!1,error:"Project not found. Use --register to register project first.",exitCode:Vo}:{success:!1,error:`HTTP ${s}: ${o.error||o.message||"Unknown error"}`,exitCode:Vo}}return{success:!1,error:n.message||"Unknown error occurred",exitCode:Vo}}}function hD(){return process.argv.includes("--json")}var Ju={tasks:"planbee tasks <session-id> --json",status:"planbee status <session-id> --json",transcript:"planbee transcript <session-id> --json",send:'planbee send <session-id> "<message>" --json',spawn:'planbee spawn --task "<task>" --json'};function gD(){let t=process.argv[2];return t&&Ju[t]?Ju[t]:"planbee --help --json"}function yD(){return function(e,n,s){if(!e&&!n)return;let o=e||n?.message||"Unknown error";if(hD()){let r=gD();console.log(JSON.stringify({error:!0,message:o,suggestion:r})),process.exit(1)}else console.error(`Error: ${o}`),s.showHelp(),process.exit(1)}}async function jB(){let t=Fg(),{hideBin:e}=Lg(),n=Hg(),s=Wg(),o=Kg(),r=Qg(),i=ey(),a=ny(),c=iy(),l=uy(),u=dy(),p=my(),d=gy(),f=by(),m=vy(),h=Ey(),g=Sy(),b=_y(),v=Oy(),E=rx(),S=dx(),C=Rx(),B=hv(),L=wv(),$=Av(),I=Cv(),R=Pv(),U=Bv(),Q=Uv(),M=Wv(),z=Gv(),ge=Yv(),oe=Zv(),xe=nw(),Ee=gw(),ve=Ew(),Me=kw(),F=Ou(),H=T0(),W=N0(),N=z0(),ce=Q0(),pe=eE(),Z=nE(),me=oE(),_e=aE(),ie=lE(),Ue=pE(),ze=fE(),le=hE(),Xe=CE(),w=TE(),_=$E(),j=IE(),A=LE(),k=UE(),P=WE(),O=GE(),{authCommand:q}=tD(),G=await t(e(process.argv)).scriptName("planbee").version(nD().version).fail(yD()).usage("Usage: $0 <command> [options]").command(n).command(CB()?[{command:"linear",describe:"Linear integration commands",builder:ae=>ae.command(s).command(o).command(r).command(i).command(a).command(c).command(l).command(u).command(p).command(d).command(f).command(m).command(h).command(g).command(b).demandCommand(1,"You need to specify a linear subcommand").help(),handler:()=>{}}]:[]).command("auth <subcommand>","Authentication commands (login, logout, whoami)",ae=>ae.positional("subcommand",{describe:"Auth subcommand",choices:["login","logout","status","whoami"]}).option("email",{type:"string",description:"Email address"}).option("password",{type:"string",description:"Password"}).option("token",{type:"string",description:"Existing personal access token to store directly"}),async ae=>{await q(ae.subcommand,ae)}).command(E).command(S).command(oe).command(xe).command(Ee).command(C.send).command(C.sendToQueen).command(B).command(L).command($).command(Q).command("swarm","Swarm management commands",ae=>ae.command(M).command(z).demandCommand(1,"You need to specify a swarm subcommand").help()).command("providers","Provider management commands",ae=>ae.command(ge).demandCommand(1,"You need to specify a providers subcommand").help()).command("memory","Memory management commands",ae=>ae.command(I.store).command(I.get).command(I.list).command(I.delete).command(I.export).command(I.import).command(I.cleanup).command(I.history).command(I.diff).demandCommand(1,"You need to specify a memory subcommand").help()).command(R.agent).command(U.listChildren).command(ve).command(Me).command(F).command(H).command(W).command(v).command("audio","Audio and TTS configuration",ae=>ae.command(N).demandCommand(1,"You need to specify an audio subcommand").help()).command("hooks","Manage PlanBee hooks in projects",ae=>ae.command(ce).command(pe).command(Z).demandCommand(1,"You need to specify a hooks subcommand").help()).command("search","Search agents and transcripts",ae=>ae.command(me).command(_e).demandCommand(1,"You need to specify a search subcommand").help()).command(ie).command(Ue).command(ze).command(le).command(Xe).command(w).command(_).command(j).command(A).command(k).command(P).command(O).option("project",{type:"string",description:"Project identifier",global:!1}).option("path",{type:"string",description:"Absolute project path",global:!1}).option("message",{type:"string",description:"Message to send (1-5000 characters)",global:!1}).option("type",{type:"string",description:"Message type",choices:RB,default:"info",global:!1}).option("title",{type:"string",description:"Short title (max 100 chars)",global:!1}).option("mood",{type:"string",description:"Voice mood",choices:FB,default:"neutral",global:!1}).option("speed",{type:"number",description:"Speech speed (0.5-2.0)",default:1,global:!1}).option("volume",{type:"number",description:"Volume (0.0-1.0)",default:.8,global:!1}).option("voice-id",{type:"string",description:"Override voice selection",global:!1}).option("quiet",{type:"boolean",description:"Suppress stdout",default:!1,global:!1}).option("json",{type:"boolean",description:"Output JSON response",default:!1,global:!1}).option("local",{type:"boolean",description:"Use local dev server (http://localhost:3456) instead of cloud",default:!1,global:!0,coerce:ae=>(ae&&(process.env.PLANBEE_MODE="local"),ae)}).help("h").alias("h","help").example('$0 --project myapp --path /home/user/myapp --message "Build complete"').example('$0 --message "Quick notification" --type success').example('$0 register --folder /path/to/workspace --task "Research task" --agent-type researcher').example('$0 spawn --type coder --task "Implement feature" --parent session-id-here').example(`$0 memory store --key task-status --value '{"status": "completed"}'`).epilogue(`Modes: cloud (default, https://planbee.infin8.world), local (--local / PLANBEE_MODE=local -> http://localhost:3456).
|
|
396
396
|
Override the API base URL entirely with PLANBEE_API_URL.
|
|
397
397
|
|
|
398
398
|
infin8 -- infin8 world llc, www.infin8.world`).strict().parseAsync(),ee=["linear","register","spawn","start-agent","devices","send","send-to-queen","inbox","remote-control","memory","wait","status","list-children","tree","auth","progress","tasks","internal-hook","audio","hooks","search","transcript","todo","plan","bee","icon","watch-rules","swarm","providers","dashboard","agents","activity","system-load","test-lock","discover"];if(Array.isArray(G._)&&G._.length>0&&ee.includes(G._[0]))return;let Qe=[lD(G.message),uD(G.title),dD(G.project,G.path),G.path?pD(G.path):null,Wu(G.speed,PB,$B,"Speed"),Wu(G.volume,NB,IB,"Volume")];for(let ae of Qe)ae&&(iD(ae,G.quiet),process.exit(cD));let je=await mD({message:G.message,project:G.project,path:G.path,type:G.type,title:G.title,mood:G.mood,speed:G.speed,volume:G.volume,voiceId:G.voiceId});je.success?(G.json?aD(je.data,G.quiet,!0):aD(fD(je.data),G.quiet,!1),process.exit(Ku)):(iD(je.error,G.quiet),process.exit(je.exitCode))}function LB(){let t=n=>{let s=process.argv.indexOf(`--${n}`);return s!==-1?process.argv[s+1]:void 0},e=Ou();return Promise.resolve(e.handler({type:t("type"),session:t("session"),"transcript-path":t("transcript-path"),deliver:process.argv.includes("--deliver")}))}if(require.main===module){let t=process.argv[2]==="internal-hook";(t?LB():jB()).catch(n=>{console.error("Fatal error:",n.message),process.exit(t?Ku:Vo)})}module.exports={validateMessage:lD,validateTitle:uD,validateAbsolutePath:pD,validateRange:Wu,validateProjectContext:dD,sendNotification:mD,formatResponse:fD,isJsonMode:hD,buildJsonFailHandler:yD,buildSuggestion:gD,COMMAND_SUGGESTIONS:Ju,EXIT_SUCCESS:Ku,EXIT_VALIDATION_ERROR:cD,EXIT_SYSTEM_ERROR:Vo,EXIT_APP_OFFLINE:zu};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "planbee",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1",
|
|
4
4
|
"description": "PlanBee CLI - agent coordination, hooks, and voice notifications for Claude Code",
|
|
5
5
|
"license": "SEE LICENSE IN LICENSE",
|
|
6
6
|
"bin": {
|
|
@@ -25,10 +25,6 @@
|
|
|
25
25
|
"i18next": "^26.2.0",
|
|
26
26
|
"esbuild": "^0.24.0"
|
|
27
27
|
},
|
|
28
|
-
"repository": {
|
|
29
|
-
"type": "git",
|
|
30
|
-
"url": "git+https://git.infin8.world/infin8/planbee-cli.git"
|
|
31
|
-
},
|
|
32
28
|
"author": "infin8 world llc (https://www.infin8.world)",
|
|
33
|
-
"homepage": "https://
|
|
29
|
+
"homepage": "https://planbee.cloud"
|
|
34
30
|
}
|