@pplethai/cli 0.4.0 → 0.4.2
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 +1 -1
- package/dist/bin.js +53 -15
- package/package.json +3 -2
- package/skills/pple-platform/references/design-system.md +7 -2
- package/templates/golden-path/package.json +1 -0
- package/templates/golden-path/web/App.tsx +129 -49
- package/templates/golden-path/web/app.css +13 -22
- package/templates/golden-path/web/main.tsx +1 -1
- package/templates/golden-path/web/pple.ts +13 -2
- package/dist/api.js +0 -108
- package/dist/cli.js +0 -151
- package/dist/commands/auth.js +0 -32
- package/dist/commands/deploy.js +0 -113
- package/dist/commands/env.js +0 -70
- package/dist/commands/info.js +0 -238
- package/dist/commands/init.js +0 -159
- package/dist/commands/upgrade.js +0 -29
- package/dist/credentials.js +0 -53
- package/dist/deps.js +0 -87
- package/dist/device-flow.js +0 -122
- package/dist/errors.js +0 -16
- package/dist/git.js +0 -127
- package/dist/link.js +0 -59
- package/dist/node-deps.js +0 -107
- package/dist/npm.js +0 -127
- package/dist/scaffold.js +0 -58
- package/dist/session.js +0 -29
- package/dist/skills.js +0 -86
- package/dist/ui.js +0 -12
- package/dist/update.js +0 -142
package/README.md
CHANGED
|
@@ -109,7 +109,7 @@ echo '{ "updateCheck": false }' > ~/.config/pple/config.json # this machine
|
|
|
109
109
|
npm install
|
|
110
110
|
npm test # drives whole commands against a fake Provisioner and real git
|
|
111
111
|
npm run typecheck
|
|
112
|
-
npm run build # bundles the template and Skills,
|
|
112
|
+
npm run build # bundles the template and Skills, then esbuild → dist/bin.js
|
|
113
113
|
```
|
|
114
114
|
|
|
115
115
|
Tests run the real command path — real `git` in a temp directory, a fake
|
package/dist/bin.js
CHANGED
|
@@ -1,16 +1,54 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import os from "node:
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
process.exitCode = 1;
|
|
16
|
-
|
|
2
|
+
import Rr from"node:os";var s=class extends Error{constructor(r,n){super(r);this.hint=n;this.name="CliError"}hint},et=new s("\u0E04\u0E38\u0E13\u0E22\u0E31\u0E07\u0E44\u0E21\u0E48\u0E44\u0E14\u0E49\u0E40\u0E02\u0E49\u0E32\u0E2A\u0E39\u0E48\u0E23\u0E30\u0E1A\u0E1A","\u0E23\u0E31\u0E19 `pple auth login` \u0E01\u0E48\u0E2D\u0E19"),x=new s("\u0E01\u0E32\u0E23\u0E40\u0E02\u0E49\u0E32\u0E2A\u0E39\u0E48\u0E23\u0E30\u0E1A\u0E1A\u0E02\u0E2D\u0E07\u0E04\u0E38\u0E13\u0E2B\u0E21\u0E14\u0E2D\u0E32\u0E22\u0E38\u0E41\u0E25\u0E49\u0E27","\u0E23\u0E31\u0E19 `pple auth login` \u0E40\u0E1E\u0E37\u0E48\u0E2D\u0E40\u0E02\u0E49\u0E32\u0E2A\u0E39\u0E48\u0E23\u0E30\u0E1A\u0E1A\u0E2D\u0E35\u0E01\u0E04\u0E23\u0E31\u0E49\u0E07");var $=class{constructor(e,r){this.deps=e;this.token=r}deps;token;me(){return this.request("GET","/me")}app(e){return this.request("GET",`/apps/${encodeURIComponent(e)}`,{slug:e})}createApp(e){return this.request("POST","/apps",{body:{name:e}})}repoToken(e){return this.request("POST",`/apps/${encodeURIComponent(e)}/repo-token`,{slug:e})}deploys(e){return this.request("GET",`/apps/${encodeURIComponent(e)}/deploys`,{slug:e}).then(r=>r.deploys)}env(e){return this.request("GET",`/apps/${encodeURIComponent(e)}/env`,{slug:e}).then(r=>r.env)}metrics(e){return this.request("GET",`/apps/${encodeURIComponent(e)}/metrics`,{slug:e})}collaborators(e){return this.request("GET",`/apps/${encodeURIComponent(e)}/collaborators`,{slug:e}).then(r=>r.collaborators)}requests(e){return this.request("GET",`/apps/${encodeURIComponent(e)}/requests`,{slug:e}).then(r=>r.requests)}invites(e){return this.request("GET",`/apps/${encodeURIComponent(e)}/invites`,{slug:e}).then(r=>r.invites)}setEnv(e,r,n,i){return this.request("PUT",`/apps/${encodeURIComponent(e)}/env/${encodeURIComponent(r)}`,{slug:e,body:{value:n,secret:i}})}deleteEnv(e,r){return this.request("DELETE",`/apps/${encodeURIComponent(e)}/env/${encodeURIComponent(r)}`,{slug:e,envKey:r})}async request(e,r,n={}){let i=`${this.deps.config.apiBase}${r}`,o={authorization:`Bearer ${this.token}`},u;n.body!==void 0&&(o["content-type"]="application/json",u=JSON.stringify(n.body));let a=await this.deps.fetch(i,{method:e,headers:o,body:u}).catch(()=>null);if(!a)throw new s("\u0E40\u0E0A\u0E37\u0E48\u0E2D\u0E21\u0E15\u0E48\u0E2D PPLE Platform \u0E44\u0E21\u0E48\u0E44\u0E14\u0E49","\u0E15\u0E23\u0E27\u0E08\u0E2A\u0E2D\u0E1A\u0E01\u0E32\u0E23\u0E40\u0E0A\u0E37\u0E48\u0E2D\u0E21\u0E15\u0E48\u0E2D\u0E2D\u0E34\u0E19\u0E40\u0E17\u0E2D\u0E23\u0E4C\u0E40\u0E19\u0E47\u0E15\u0E41\u0E25\u0E49\u0E27\u0E25\u0E2D\u0E07\u0E43\u0E2B\u0E21\u0E48\u0E2D\u0E35\u0E01\u0E04\u0E23\u0E31\u0E49\u0E07");if(a.ok)return a.status===204?void 0:await a.json();let c=await a.json().catch(()=>({}));throw me(a.status,c.error,n)}};function me(t,e,r={}){let{slug:n,envKey:i}=r;return t===401?x:e==="not_org_member"?new s("PPLE ID \u0E02\u0E2D\u0E07\u0E04\u0E38\u0E13\u0E22\u0E31\u0E07\u0E44\u0E21\u0E48\u0E44\u0E14\u0E49\u0E2D\u0E22\u0E39\u0E48\u0E43\u0E19\u0E2D\u0E07\u0E04\u0E4C\u0E01\u0E23\u0E02\u0E2D\u0E07\u0E1E\u0E23\u0E23\u0E04 \u0E08\u0E36\u0E07\u0E2A\u0E23\u0E49\u0E32\u0E07\u0E41\u0E2D\u0E1B\u0E44\u0E21\u0E48\u0E44\u0E14\u0E49","\u0E01\u0E23\u0E38\u0E13\u0E32\u0E15\u0E34\u0E14\u0E15\u0E48\u0E2D\u0E2B\u0E31\u0E27\u0E2B\u0E19\u0E49\u0E32\u0E17\u0E35\u0E21\u0E02\u0E2D\u0E07\u0E04\u0E38\u0E13\u0E40\u0E1E\u0E37\u0E48\u0E2D\u0E40\u0E1E\u0E34\u0E48\u0E21\u0E2A\u0E34\u0E17\u0E18\u0E34\u0E4C \u0E41\u0E25\u0E49\u0E27\u0E25\u0E2D\u0E07\u0E43\u0E2B\u0E21\u0E48\u0E2D\u0E35\u0E01\u0E04\u0E23\u0E31\u0E49\u0E07"):e==="agreement_required"?new s("\u0E04\u0E38\u0E13\u0E22\u0E31\u0E07\u0E44\u0E21\u0E48\u0E44\u0E14\u0E49\u0E22\u0E2D\u0E21\u0E23\u0E31\u0E1A\u0E02\u0E49\u0E2D\u0E15\u0E01\u0E25\u0E07\u0E1C\u0E39\u0E49\u0E1E\u0E31\u0E12\u0E19\u0E32","\u0E22\u0E2D\u0E21\u0E23\u0E31\u0E1A\u0E44\u0E14\u0E49\u0E17\u0E35\u0E48 https://console.ppleth.ai \u0E41\u0E25\u0E49\u0E27\u0E23\u0E31\u0E19\u0E04\u0E33\u0E2A\u0E31\u0E48\u0E07\u0E19\u0E35\u0E49\u0E2D\u0E35\u0E01\u0E04\u0E23\u0E31\u0E49\u0E07"):e==="app_has_no_repo"?new s(`${n?`"${n}"`:"\u0E41\u0E2D\u0E1B\u0E19\u0E35\u0E49"} \u0E22\u0E31\u0E07\u0E15\u0E31\u0E49\u0E07\u0E04\u0E48\u0E32\u0E44\u0E21\u0E48\u0E40\u0E2A\u0E23\u0E47\u0E08`,"\u0E23\u0E2D\u0E2A\u0E31\u0E01\u0E04\u0E23\u0E39\u0E48\u0E41\u0E25\u0E49\u0E27\u0E25\u0E2D\u0E07\u0E43\u0E2B\u0E21\u0E48\u0E2D\u0E35\u0E01\u0E04\u0E23\u0E31\u0E49\u0E07 \u0E2B\u0E32\u0E01\u0E22\u0E31\u0E07\u0E40\u0E1B\u0E47\u0E19\u0E41\u0E1A\u0E1A\u0E19\u0E35\u0E49 \u0E01\u0E23\u0E38\u0E13\u0E32\u0E15\u0E34\u0E14\u0E15\u0E48\u0E2D\u0E17\u0E35\u0E21\u0E41\u0E1E\u0E25\u0E15\u0E1F\u0E2D\u0E23\u0E4C\u0E21"):e==="invalid_key"?new s("\u0E04\u0E35\u0E22\u0E4C\u0E19\u0E35\u0E49\u0E43\u0E0A\u0E49\u0E40\u0E1B\u0E47\u0E19\u0E0A\u0E37\u0E48\u0E2D\u0E44\u0E21\u0E48\u0E44\u0E14\u0E49","\u0E04\u0E35\u0E22\u0E4C\u0E15\u0E49\u0E2D\u0E07\u0E02\u0E36\u0E49\u0E19\u0E15\u0E49\u0E19\u0E14\u0E49\u0E27\u0E22\u0E15\u0E31\u0E27\u0E2D\u0E31\u0E01\u0E29\u0E23\u0E2B\u0E23\u0E37\u0E2D\u0E02\u0E35\u0E14\u0E25\u0E48\u0E32\u0E07 \u0E15\u0E32\u0E21\u0E14\u0E49\u0E27\u0E22\u0E15\u0E31\u0E27\u0E2D\u0E31\u0E01\u0E29\u0E23 \u0E15\u0E31\u0E27\u0E40\u0E25\u0E02 \u0E2B\u0E23\u0E37\u0E2D\u0E02\u0E35\u0E14\u0E25\u0E48\u0E32\u0E07"):e==="reserved_key"?new s("\u0E04\u0E35\u0E22\u0E4C\u0E19\u0E35\u0E49\u0E16\u0E39\u0E01\u0E2A\u0E07\u0E27\u0E19\u0E44\u0E27\u0E49\u0E42\u0E14\u0E22\u0E41\u0E1E\u0E25\u0E15\u0E1F\u0E2D\u0E23\u0E4C\u0E21","\u0E40\u0E25\u0E37\u0E2D\u0E01\u0E0A\u0E37\u0E48\u0E2D\u0E2D\u0E37\u0E48\u0E19 \u2014 APP_SLUG, DB, FILES, NOTIFY_* \u0E41\u0E25\u0E30 PPLE_DEPLOY_ID \u0E16\u0E39\u0E01\u0E43\u0E0A\u0E49\u0E44\u0E1B\u0E41\u0E25\u0E49\u0E27"):e==="invalid_value"?new s("\u0E1A\u0E31\u0E19\u0E17\u0E36\u0E01\u0E04\u0E48\u0E32\u0E19\u0E35\u0E49\u0E44\u0E21\u0E48\u0E2A\u0E33\u0E40\u0E23\u0E47\u0E08","\u0E2A\u0E48\u0E07\u0E04\u0E48\u0E32\u0E21\u0E32\u0E40\u0E1B\u0E47\u0E19 argument \u0E1C\u0E48\u0E32\u0E19 `--file` \u0E2B\u0E23\u0E37\u0E2D\u0E17\u0E32\u0E07 stdin"):t===404?i?new s(`\u0E41\u0E2D\u0E1B\u0E19\u0E35\u0E49\u0E44\u0E21\u0E48\u0E44\u0E14\u0E49\u0E15\u0E31\u0E49\u0E07\u0E04\u0E48\u0E32 "${i}" \u0E44\u0E27\u0E49`,"\u0E23\u0E31\u0E19 `pple env list` \u0E40\u0E1E\u0E37\u0E48\u0E2D\u0E14\u0E39\u0E04\u0E48\u0E32\u0E17\u0E35\u0E48\u0E15\u0E31\u0E49\u0E07\u0E44\u0E27\u0E49"):new s(n?`\u0E44\u0E21\u0E48\u0E21\u0E35\u0E41\u0E2D\u0E1B\u0E0A\u0E37\u0E48\u0E2D "${n}" \u0E17\u0E35\u0E48\u0E40\u0E1B\u0E47\u0E19\u0E02\u0E2D\u0E07\u0E04\u0E38\u0E13`:"\u0E44\u0E21\u0E48\u0E1E\u0E1A\u0E2A\u0E34\u0E48\u0E07\u0E19\u0E35\u0E49\u0E1A\u0E19\u0E41\u0E1E\u0E25\u0E15\u0E1F\u0E2D\u0E23\u0E4C\u0E21","\u0E15\u0E23\u0E27\u0E08\u0E2A\u0E2D\u0E1A\u0E23\u0E32\u0E22\u0E01\u0E32\u0E23\u0E41\u0E2D\u0E1B\u0E44\u0E14\u0E49\u0E17\u0E35\u0E48 https://console.ppleth.ai"):t>=500||e==="sso_unavailable"?new s("PPLE Platform \u0E01\u0E33\u0E25\u0E31\u0E07\u0E21\u0E35\u0E1B\u0E31\u0E0D\u0E2B\u0E32\u0E43\u0E19\u0E02\u0E13\u0E30\u0E19\u0E35\u0E49","\u0E23\u0E2D\u0E2A\u0E31\u0E01\u0E04\u0E23\u0E39\u0E48\u0E41\u0E25\u0E49\u0E27\u0E25\u0E2D\u0E07\u0E43\u0E2B\u0E21\u0E48\u0E2D\u0E35\u0E01\u0E04\u0E23\u0E31\u0E49\u0E07 \u0E2B\u0E32\u0E01\u0E22\u0E31\u0E07\u0E40\u0E01\u0E34\u0E14\u0E02\u0E36\u0E49\u0E19\u0E2D\u0E35\u0E01 \u0E01\u0E23\u0E38\u0E13\u0E32\u0E41\u0E08\u0E49\u0E07\u0E17\u0E35\u0E21\u0E41\u0E1E\u0E25\u0E15\u0E1F\u0E2D\u0E23\u0E4C\u0E21"):new s("PPLE Platform \u0E1B\u0E0F\u0E34\u0E40\u0E2A\u0E18\u0E04\u0E33\u0E02\u0E2D\u0E19\u0E35\u0E49",e?`\u0E02\u0E49\u0E2D\u0E04\u0E27\u0E32\u0E21\u0E08\u0E32\u0E01\u0E23\u0E30\u0E1A\u0E1A: ${e}`:void 0)}import D from"node:fs/promises";import ge from"node:path";var de="credentials.json",rt=384,ye=448;function T(t){return ge.join(t.configDir,de)}async function nt(t){let e=await D.readFile(T(t),"utf8").catch(()=>null);if(e===null)return null;let r;try{r=JSON.parse(e)}catch{return null}return typeof r.accessToken!="string"||r.ssoBase!==t.config.ssoBase?null:{accessToken:r.accessToken,refreshToken:typeof r.refreshToken=="string"?r.refreshToken:null,expiresAt:typeof r.expiresAt=="number"?r.expiresAt:null,ssoBase:r.ssoBase}}async function S(t,e){await D.mkdir(t.configDir,{recursive:!0,mode:ye}),await D.writeFile(T(t),`${JSON.stringify(e,null,2)}
|
|
3
|
+
`,{mode:rt}),await D.chmod(T(t),rt)}async function it(t){try{return await D.unlink(T(t)),!0}catch{return!1}}var we="/oauth/v2/device_authorization",st="/oauth/v2/token",he="urn:ietf:params:oauth:grant-type:device_code",at="openid profile offline_access";function F(t){return{method:"POST",headers:{"content-type":"application/x-www-form-urlencoded"},body:new URLSearchParams(t).toString()}}function q(t){return new s(`\u0E40\u0E0A\u0E37\u0E48\u0E2D\u0E21\u0E15\u0E48\u0E2D PPLE ID (${t}) \u0E40\u0E1E\u0E37\u0E48\u0E2D\u0E40\u0E02\u0E49\u0E32\u0E2A\u0E39\u0E48\u0E23\u0E30\u0E1A\u0E1A\u0E44\u0E21\u0E48\u0E44\u0E14\u0E49`,"\u0E15\u0E23\u0E27\u0E08\u0E2A\u0E2D\u0E1A\u0E01\u0E32\u0E23\u0E40\u0E0A\u0E37\u0E48\u0E2D\u0E21\u0E15\u0E48\u0E2D\u0E2D\u0E34\u0E19\u0E40\u0E17\u0E2D\u0E23\u0E4C\u0E40\u0E19\u0E47\u0E15\u0E41\u0E25\u0E49\u0E27\u0E25\u0E2D\u0E07 `pple auth login` \u0E2D\u0E35\u0E01\u0E04\u0E23\u0E31\u0E49\u0E07")}async function ut(t){let{ssoBase:e,clientId:r}=t.config,n=await t.fetch(`${e}${we}`,F({client_id:r,scope:at})).catch(()=>null);if(!n||!n.ok)throw q(e);let i=await n.json().catch(()=>({}));if(!i.device_code||!i.user_code||!i.verification_uri)throw q(e);return{deviceCode:i.device_code,userCode:i.user_code,verificationUri:i.verification_uri,verificationUriComplete:i.verification_uri_complete??null,expiresInMs:(i.expires_in??600)*1e3,intervalMs:(i.interval??5)*1e3}}async function lt(t,e){let{ssoBase:r,clientId:n}=t.config,i=t.now()+e.expiresInMs,o=e.intervalMs;for(;t.now()<i;){await t.sleep(o);let u=await t.fetch(`${r}${st}`,F({client_id:n,grant_type:he,device_code:e.deviceCode})).catch(()=>null);if(!u)throw q(r);let a=await u.json().catch(()=>({}));if(u.ok&&a.access_token)return pt(t,a);switch(a.error){case"authorization_pending":break;case"slow_down":o+=5e3;break;case"access_denied":throw new s("\u0E01\u0E32\u0E23\u0E40\u0E02\u0E49\u0E32\u0E2A\u0E39\u0E48\u0E23\u0E30\u0E1A\u0E1A\u0E16\u0E39\u0E01\u0E1B\u0E0F\u0E34\u0E40\u0E2A\u0E18\u0E43\u0E19\u0E40\u0E1A\u0E23\u0E32\u0E27\u0E4C\u0E40\u0E0B\u0E2D\u0E23\u0E4C","\u0E2B\u0E32\u0E01\u0E44\u0E21\u0E48\u0E43\u0E0A\u0E48\u0E04\u0E38\u0E13\u0E17\u0E35\u0E48\u0E1B\u0E0F\u0E34\u0E40\u0E2A\u0E18 \u0E43\u0E2B\u0E49\u0E23\u0E31\u0E19 `pple auth login` \u0E2D\u0E35\u0E01\u0E04\u0E23\u0E31\u0E49\u0E07");case"expired_token":throw ot();default:throw new s("PPLE ID \u0E1B\u0E0F\u0E34\u0E40\u0E2A\u0E18\u0E01\u0E32\u0E23\u0E40\u0E02\u0E49\u0E32\u0E2A\u0E39\u0E48\u0E23\u0E30\u0E1A\u0E1A",a.error_description??"\u0E25\u0E2D\u0E07 `pple auth login` \u0E2D\u0E35\u0E01\u0E04\u0E23\u0E31\u0E49\u0E07")}}throw ot()}function ot(){return new s("\u0E23\u0E2B\u0E31\u0E2A\u0E40\u0E02\u0E49\u0E32\u0E2A\u0E39\u0E48\u0E23\u0E30\u0E1A\u0E1A\u0E2B\u0E21\u0E14\u0E2D\u0E32\u0E22\u0E38\u0E01\u0E48\u0E2D\u0E19\u0E44\u0E14\u0E49\u0E23\u0E31\u0E1A\u0E01\u0E32\u0E23\u0E2D\u0E19\u0E38\u0E21\u0E31\u0E15\u0E34","\u0E23\u0E31\u0E19 `pple auth login` \u0E2D\u0E35\u0E01\u0E04\u0E23\u0E31\u0E49\u0E07 \u2014 \u0E02\u0E31\u0E49\u0E19\u0E15\u0E2D\u0E19\u0E43\u0E19\u0E40\u0E1A\u0E23\u0E32\u0E27\u0E4C\u0E40\u0E0B\u0E2D\u0E23\u0E4C\u0E15\u0E49\u0E2D\u0E07\u0E17\u0E33\u0E43\u0E2B\u0E49\u0E40\u0E2A\u0E23\u0E47\u0E08\u0E20\u0E32\u0E22\u0E43\u0E19\u0E44\u0E21\u0E48\u0E01\u0E35\u0E48\u0E19\u0E32\u0E17\u0E35")}async function ct(t,e){let{ssoBase:r,clientId:n}=t.config,i=await t.fetch(`${r}${st}`,F({client_id:n,grant_type:"refresh_token",refresh_token:e,scope:at})).catch(()=>null);if(!i||!i.ok)return null;let o=await i.json().catch(()=>({}));return o.access_token?{...pt(t,o),refreshToken:o.refresh_token??e}:null}function pt(t,e){return{accessToken:e.access_token,refreshToken:e.refresh_token??null,expiresAt:typeof e.expires_in=="number"?t.now()+e.expires_in*1e3:null}}var ve=6e4;async function Pe(t){let e=await nt(t);if(!e)throw et;if(!(e.expiresAt!==null&&e.expiresAt-t.now()<ve))return e.accessToken;if(e.refreshToken){let n=await ct(t,e.refreshToken);if(n)return await S(t,{...n,ssoBase:t.config.ssoBase}),n.accessToken}throw x}async function p(t){return new $(t,await Pe(t))}async function ft(t){let e=await ut(t);t.out.say("\u0E40\u0E02\u0E49\u0E32\u0E2A\u0E39\u0E48\u0E23\u0E30\u0E1A\u0E1A\u0E42\u0E14\u0E22\u0E40\u0E1B\u0E34\u0E14\u0E2B\u0E19\u0E49\u0E32\u0E19\u0E35\u0E49\u0E41\u0E25\u0E49\u0E27\u0E01\u0E23\u0E2D\u0E01\u0E23\u0E2B\u0E31\u0E2A:"),t.out.say(),t.out.say(` ${e.verificationUri}`),t.out.say(` \u0E23\u0E2B\u0E31\u0E2A: ${e.userCode}`),t.out.say(),t.out.say("\u0E01\u0E33\u0E25\u0E31\u0E07\u0E23\u0E2D\u0E43\u0E2B\u0E49\u0E04\u0E38\u0E13\u0E2D\u0E19\u0E38\u0E21\u0E31\u0E15\u0E34\u0E01\u0E32\u0E23\u0E40\u0E02\u0E49\u0E32\u0E2A\u0E39\u0E48\u0E23\u0E30\u0E1A\u0E1A\u2026"),await t.openBrowser(e.verificationUriComplete??e.verificationUri);let r=await lt(t,e);await S(t,{...r,ssoBase:t.config.ssoBase});let n=await new $(t,r.accessToken).me();t.out.say(`\u0E40\u0E02\u0E49\u0E32\u0E2A\u0E39\u0E48\u0E23\u0E30\u0E1A\u0E1A\u0E43\u0E19\u0E0A\u0E37\u0E48\u0E2D ${n.name??n.sub} \u0E41\u0E25\u0E49\u0E27`),n.isBuilder||t.out.say("\u0E2D\u0E35\u0E01\u0E2B\u0E19\u0E36\u0E48\u0E07\u0E02\u0E31\u0E49\u0E19\u0E15\u0E2D\u0E19\u0E01\u0E48\u0E2D\u0E19\u0E2A\u0E23\u0E49\u0E32\u0E07\u0E41\u0E2D\u0E1B\u0E44\u0E14\u0E49: \u0E22\u0E2D\u0E21\u0E23\u0E31\u0E1A\u0E02\u0E49\u0E2D\u0E15\u0E01\u0E25\u0E07\u0E1C\u0E39\u0E49\u0E1E\u0E31\u0E12\u0E19\u0E32\u0E17\u0E35\u0E48 https://console.ppleth.ai")}async function mt(t){let e=await it(t);t.out.say(e?"\u0E2D\u0E2D\u0E01\u0E08\u0E32\u0E01\u0E23\u0E30\u0E1A\u0E1A\u0E41\u0E25\u0E49\u0E27":"\u0E04\u0E38\u0E13\u0E22\u0E31\u0E07\u0E44\u0E21\u0E48\u0E44\u0E14\u0E49\u0E40\u0E02\u0E49\u0E32\u0E2A\u0E39\u0E48\u0E23\u0E30\u0E1A\u0E1A")}async function G(t){let e=await(await p(t)).me();t.out.say(`\u0E40\u0E02\u0E49\u0E32\u0E2A\u0E39\u0E48\u0E23\u0E30\u0E1A\u0E1A\u0E43\u0E19\u0E0A\u0E37\u0E48\u0E2D ${e.name??e.sub} \u0E41\u0E25\u0E49\u0E27`),e.isBuilder||t.out.say("\u0E04\u0E38\u0E13\u0E22\u0E31\u0E07\u0E44\u0E21\u0E48\u0E44\u0E14\u0E49\u0E22\u0E2D\u0E21\u0E23\u0E31\u0E1A\u0E02\u0E49\u0E2D\u0E15\u0E01\u0E25\u0E07\u0E1C\u0E39\u0E49\u0E1E\u0E31\u0E12\u0E19\u0E32 \u2014 \u0E22\u0E2D\u0E21\u0E23\u0E31\u0E1A\u0E44\u0E14\u0E49\u0E17\u0E35\u0E48 https://console.ppleth.ai")}var R="main",Ee="x-access-token";async function d(t,e,r,n){return t.run("git",n?["-c","credential.helper=",...r]:r,{cwd:e,env:{GIT_TERMINAL_PROMPT:"0",...n?{GIT_ASKPASS:t.gitAskpass,PPLE_GIT_USER:Ee,PPLE_GIT_TOKEN:n.token}:{}}})}function gt(t){return["-c",`user.name=${t.author.name}`,"-c",`user.email=${t.author.email}`]}function dt(t){return/authentication|could not read|403|denied|not found/i.test(`${t.stdout}
|
|
4
|
+
${t.stderr}`)}function yt(t,e){return new s(`\u0E41\u0E1E\u0E25\u0E15\u0E1F\u0E2D\u0E23\u0E4C\u0E21\u0E44\u0E21\u0E48\u0E2D\u0E19\u0E38\u0E0D\u0E32\u0E15\u0E43\u0E2B\u0E49\u0E40\u0E04\u0E23\u0E37\u0E48\u0E2D\u0E07\u0E19\u0E35\u0E49${t}`,`\u0E15\u0E23\u0E27\u0E08\u0E2A\u0E2D\u0E1A\u0E27\u0E48\u0E32\u0E41\u0E2D\u0E1B\u0E22\u0E31\u0E07\u0E40\u0E1B\u0E47\u0E19\u0E02\u0E2D\u0E07\u0E04\u0E38\u0E13\u0E2D\u0E22\u0E39\u0E48\u0E17\u0E35\u0E48 https://console.ppleth.ai \u0E41\u0E25\u0E49\u0E27\u0E23\u0E31\u0E19 \`${e}\` \u0E2D\u0E35\u0E01\u0E04\u0E23\u0E31\u0E49\u0E07`)}function wt(t){return new s("\u0E2D\u0E48\u0E32\u0E19\u0E42\u0E1F\u0E25\u0E40\u0E14\u0E2D\u0E23\u0E4C\u0E02\u0E2D\u0E07\u0E41\u0E2D\u0E1B\u0E44\u0E21\u0E48\u0E44\u0E14\u0E49",t.stderr.trim())}async function k(t,e,r,n,i){let o=await d(t,e,r,i).catch(()=>{throw new s("\u0E40\u0E04\u0E23\u0E37\u0E48\u0E2D\u0E07\u0E19\u0E35\u0E49\u0E22\u0E31\u0E07\u0E44\u0E21\u0E48\u0E21\u0E35\u0E40\u0E04\u0E23\u0E37\u0E48\u0E2D\u0E07\u0E21\u0E37\u0E2D\u0E17\u0E35\u0E48 PPLE CLI \u0E15\u0E49\u0E2D\u0E07\u0E43\u0E0A\u0E49","\u0E15\u0E34\u0E14\u0E15\u0E31\u0E49\u0E07 git (https://git-scm.com/downloads) \u0E41\u0E25\u0E49\u0E27\u0E23\u0E31\u0E19\u0E04\u0E33\u0E2A\u0E31\u0E48\u0E07\u0E2D\u0E35\u0E01\u0E04\u0E23\u0E31\u0E49\u0E07")});if(o.code!==0)throw n(o);return o}async function ht(t,e,r,n){await k(t,t.cwd,["clone",e,r],i=>dt(i)?yt("\u0E40\u0E02\u0E49\u0E32\u0E16\u0E36\u0E07\u0E42\u0E04\u0E49\u0E14\u0E02\u0E2D\u0E07\u0E41\u0E2D\u0E1B\u0E04\u0E38\u0E13","pple init"):new s("\u0E14\u0E36\u0E07\u0E42\u0E04\u0E49\u0E14\u0E02\u0E2D\u0E07\u0E41\u0E2D\u0E1B\u0E44\u0E21\u0E48\u0E2A\u0E33\u0E40\u0E23\u0E47\u0E08",i.stderr.trim()),n)}async function I(t,e){return(await k(t,e,["status","--porcelain"],wt)).stdout.trim()!==""}async function L(t,e,r,n){await k(t,e,["add","-A"],wt),await k(t,e,[...gt(n),"commit","-m",r],i=>new s("\u0E1A\u0E31\u0E19\u0E17\u0E36\u0E01\u0E01\u0E32\u0E23\u0E40\u0E1B\u0E25\u0E35\u0E48\u0E22\u0E19\u0E41\u0E1B\u0E25\u0E07\u0E02\u0E2D\u0E07\u0E04\u0E38\u0E13\u0E44\u0E21\u0E48\u0E2A\u0E33\u0E40\u0E23\u0E47\u0E08",i.stderr.trim()))}async function vt(t,e){return(await k(t,e,["rev-parse","HEAD"],n=>new s("\u0E2D\u0E48\u0E32\u0E19\u0E1B\u0E23\u0E30\u0E27\u0E31\u0E15\u0E34\u0E02\u0E2D\u0E07\u0E41\u0E2D\u0E1B\u0E44\u0E21\u0E48\u0E2A\u0E33\u0E40\u0E23\u0E47\u0E08",n.stderr.trim()))).stdout.trim()}async function Pt(t,e,r){await d(t,e,["fetch","origin",R],r);let n=await d(t,e,["rev-parse","HEAD"]),i=await d(t,e,["rev-parse",`origin/${R}`]);return n.code!==0||i.code!==0?!1:n.stdout.trim()===i.stdout.trim()}async function $t(t,e,r){let n=["push","origin",`HEAD:${R}`],i=await d(t,e,n,r);if(i.code===0)return;let o=`${i.stdout}
|
|
5
|
+
${i.stderr}`;if(!/rejected|non-fast-forward|fetch first/i.test(o))throw dt(i)?yt("\u0E2A\u0E48\u0E07\u0E01\u0E32\u0E23\u0E40\u0E1B\u0E25\u0E35\u0E48\u0E22\u0E19\u0E41\u0E1B\u0E25\u0E07\u0E44\u0E1B\u0E22\u0E31\u0E07\u0E41\u0E2D\u0E1B\u0E02\u0E2D\u0E07\u0E04\u0E38\u0E13","pple deploy"):new s("\u0E2A\u0E48\u0E07\u0E01\u0E32\u0E23\u0E40\u0E1B\u0E25\u0E35\u0E48\u0E22\u0E19\u0E41\u0E1B\u0E25\u0E07\u0E02\u0E2D\u0E07\u0E04\u0E38\u0E13\u0E44\u0E21\u0E48\u0E2A\u0E33\u0E40\u0E23\u0E47\u0E08",i.stderr.trim());if(t.out.say("\u0E21\u0E35\u0E04\u0E19\u0E2D\u0E37\u0E48\u0E19\u0E41\u0E01\u0E49\u0E44\u0E02\u0E41\u0E2D\u0E1B\u0E19\u0E35\u0E49 \u2014 \u0E01\u0E33\u0E25\u0E31\u0E07\u0E19\u0E33\u0E07\u0E32\u0E19\u0E02\u0E2D\u0E07\u0E40\u0E02\u0E32\u0E40\u0E02\u0E49\u0E32\u0E21\u0E32\u0E01\u0E48\u0E2D\u0E19\u2026"),(await d(t,e,[...gt(r),"pull","--rebase","origin",R],r)).code!==0)throw await d(t,e,["rebase","--abort"]),new s("\u0E01\u0E32\u0E23\u0E40\u0E1B\u0E25\u0E35\u0E48\u0E22\u0E19\u0E41\u0E1B\u0E25\u0E07\u0E02\u0E2D\u0E07\u0E04\u0E38\u0E13\u0E02\u0E31\u0E14\u0E41\u0E22\u0E49\u0E07\u0E01\u0E31\u0E1A\u0E17\u0E35\u0E48\u0E04\u0E19\u0E2D\u0E37\u0E48\u0E19\u0E14\u0E35\u0E1E\u0E25\u0E2D\u0E22\u0E44\u0E1B\u0E41\u0E25\u0E49\u0E27","\u0E43\u0E2B\u0E49 AI coding agent \u0E02\u0E2D\u0E07\u0E04\u0E38\u0E13\u0E23\u0E27\u0E21\u0E2A\u0E2D\u0E07\u0E40\u0E27\u0E2D\u0E23\u0E4C\u0E0A\u0E31\u0E19\u0E40\u0E02\u0E49\u0E32\u0E14\u0E49\u0E27\u0E22\u0E01\u0E31\u0E19 \u0E41\u0E25\u0E49\u0E27\u0E23\u0E31\u0E19 `pple deploy` \u0E2D\u0E35\u0E01\u0E04\u0E23\u0E31\u0E49\u0E07");let a=await d(t,e,n,r);if(a.code!==0)throw new s("\u0E2A\u0E48\u0E07\u0E01\u0E32\u0E23\u0E40\u0E1B\u0E25\u0E35\u0E48\u0E22\u0E19\u0E41\u0E1B\u0E25\u0E07\u0E02\u0E2D\u0E07\u0E04\u0E38\u0E13\u0E44\u0E21\u0E48\u0E2A\u0E33\u0E40\u0E23\u0E47\u0E08",a.stderr.trim())}import K from"node:fs/promises";import A from"node:path";var H=".pple",Et="app.json";async function Dt(t,e){await K.mkdir(A.join(t,H),{recursive:!0}),await K.writeFile(A.join(t,H,Et),`${JSON.stringify(e,null,2)}
|
|
6
|
+
`)}async function y(t){let e=await V(t);if(e)return e;throw new s("\u0E42\u0E1F\u0E25\u0E40\u0E14\u0E2D\u0E23\u0E4C\u0E19\u0E35\u0E49\u0E44\u0E21\u0E48\u0E43\u0E0A\u0E48\u0E41\u0E2D\u0E1B PPLE","\u0E40\u0E02\u0E49\u0E32\u0E44\u0E1B\u0E43\u0E19\u0E42\u0E1F\u0E25\u0E40\u0E14\u0E2D\u0E23\u0E4C\u0E02\u0E2D\u0E07\u0E41\u0E2D\u0E1B \u0E2B\u0E23\u0E37\u0E2D\u0E23\u0E31\u0E19 `pple init <app>` \u0E40\u0E1E\u0E37\u0E48\u0E2D\u0E15\u0E31\u0E49\u0E07\u0E04\u0E48\u0E32\u0E41\u0E2D\u0E1B\u0E43\u0E2B\u0E21\u0E48")}async function V(t){let e=A.resolve(t.cwd);for(;;){let r=A.join(e,H,Et),n=await K.readFile(r,"utf8").catch(()=>null);if(n!==null){let o=De(n);if(o)return{...o,dir:e};throw new s("\u0E01\u0E32\u0E23\u0E40\u0E0A\u0E37\u0E48\u0E2D\u0E21\u0E42\u0E22\u0E07\u0E41\u0E2D\u0E1B\u0E19\u0E35\u0E49\u0E01\u0E31\u0E1A\u0E41\u0E1E\u0E25\u0E15\u0E1F\u0E2D\u0E23\u0E4C\u0E21\u0E40\u0E2A\u0E35\u0E22\u0E2B\u0E32\u0E22","\u0E23\u0E31\u0E19 `pple init <app>` \u0E43\u0E19\u0E42\u0E1F\u0E25\u0E40\u0E14\u0E2D\u0E23\u0E4C\u0E43\u0E2B\u0E21\u0E48\u0E40\u0E1E\u0E37\u0E48\u0E2D\u0E15\u0E31\u0E49\u0E07\u0E04\u0E48\u0E32\u0E2D\u0E35\u0E01\u0E04\u0E23\u0E31\u0E49\u0E07")}let i=A.dirname(e);if(i===e)break;e=i}return null}function De(t){try{let e=JSON.parse(t);return typeof e.slug!="string"||e.slug===""?null:{slug:e.slug,apiBase:typeof e.apiBase=="string"?e.apiBase:"",url:typeof e.url=="string"?e.url:""}}catch{return null}}import{createHash as be}from"node:crypto";import g from"node:fs/promises";import w from"node:path";import{realpath as ke}from"node:fs/promises";import J from"node:path";var Y="@pplethai/cli",m=`npm install -g ${Y}`;async function N(t){let e=await t.fetch(`${t.config.registryBase}/${Y}/latest`,{headers:{accept:"application/json"}}).catch(()=>null);if(!e?.ok)return null;let r=await e.json().catch(()=>null);return typeof r?.version=="string"&&r.version!==""?r.version:null}async function O(t){let e=await t.run("npm",["root","-g"],{cwd:t.cwd}).catch(()=>null);if(!e||e.code!==0)return!1;let r=e.stdout.trim();return r===""?!1:Ae(r,t.packageDir)}function j(t,e){return t.run("npm",["install","-g",`${Y}@${e}`],{cwd:t.cwd}).catch(r=>({code:1,stdout:"",stderr:r instanceof Error?r.message:String(r)}))}async function Ae(t,e){let[r,n]=await Promise.all([kt(t),kt(e)]),i=J.relative(r,n);return i!==""&&!i.startsWith("..")&&!J.isAbsolute(i)}async function kt(t){return ke(t).catch(()=>J.resolve(t))}function B(t,e){let r=At(t),n=At(e);if(!r)return!1;if(!n)return!0;for(let i=0;i<3;i+=1)if(r.parts[i]!==n.parts[i])return r.parts[i]>n.parts[i];return _e(r.prerelease,n.prerelease)>0}function At(t){let e=/^v?(\d+)\.(\d+)\.(\d+)(?:-([0-9A-Za-z.-]+))?/.exec(t.trim());return e?{parts:[Number(e[1]),Number(e[2]),Number(e[3])],prerelease:e[4]?e[4].split("."):[]}:null}function _e(t,e){if(t.length===0&&e.length===0)return 0;if(t.length===0)return 1;if(e.length===0)return-1;for(let r=0;r<Math.max(t.length,e.length);r+=1){let n=t[r],i=e[r];if(n===void 0)return-1;if(i===void 0)return 1;let o=/^\d+$/.test(n)&&/^\d+$/.test(i);if(n!==i)return o?Number(n)>Number(i)?1:-1:n>i?1:-1}return 0}function _t(t){return`${t.stderr}
|
|
7
|
+
${t.stdout}`.split(`
|
|
8
|
+
`).map(r=>r.replace(/^npm (ERR!|error|warn)\s*/i,"").trim()).filter(r=>r!=="").slice(0,3).join(`
|
|
9
|
+
`)||"\u0E2B\u0E22\u0E38\u0E14\u0E17\u0E33\u0E07\u0E32\u0E19\u0E42\u0E14\u0E22\u0E44\u0E21\u0E48\u0E44\u0E14\u0E49\u0E23\u0E30\u0E1A\u0E38\u0E2A\u0E32\u0E40\u0E2B\u0E15\u0E38"}var xt=w.join(".claude","skills","pple-platform"),bt=`${xt.split(w.sep).join("/")}/`;async function U(t,e){let r=t.skillsDir;if(await g.readdir(r).catch(()=>null)===null)throw new s("\u0E44\u0E21\u0E48\u0E1E\u0E1A Skill \u0E02\u0E2D\u0E07 PPLE Platform \u0E43\u0E19\u0E01\u0E32\u0E23\u0E15\u0E34\u0E14\u0E15\u0E31\u0E49\u0E07 CLI \u0E0A\u0E38\u0E14\u0E19\u0E35\u0E49",`\u0E15\u0E34\u0E14\u0E15\u0E31\u0E49\u0E07 CLI \u0E43\u0E2B\u0E21\u0E48 (\`${m}\`) \u0E41\u0E25\u0E49\u0E27\u0E25\u0E2D\u0E07\u0E2D\u0E35\u0E01\u0E04\u0E23\u0E31\u0E49\u0E07`);let i=w.join(e,xt),o=await Ct(i);await Ce(r,i),await xe(e);let u=await Ct(i);o!==u&&t.out.say(o===null?"\u0E15\u0E34\u0E14\u0E15\u0E31\u0E49\u0E07 Skill \u0E02\u0E2D\u0E07\u0E41\u0E1E\u0E25\u0E15\u0E1F\u0E2D\u0E23\u0E4C\u0E21\u0E41\u0E25\u0E49\u0E27":"\u0E2D\u0E31\u0E1B\u0E40\u0E14\u0E15 Skill \u0E02\u0E2D\u0E07\u0E41\u0E1E\u0E25\u0E15\u0E1F\u0E2D\u0E23\u0E4C\u0E21\u0E41\u0E25\u0E49\u0E27")}async function Ce(t,e){await g.rm(e,{recursive:!0,force:!0}),await Tt(t,e)}async function Tt(t,e){await g.mkdir(e,{recursive:!0});for(let r of await g.readdir(t,{withFileTypes:!0})){if(r.name===".DS_Store")continue;let n=w.join(t,r.name),i=w.join(e,r.name);r.isDirectory()?await Tt(n,i):await g.copyFile(n,i)}}async function Ct(t){let e=await St(t).catch(()=>null);if(e===null)return null;let r=be("sha256");for(let n of e.sort())r.update(n),r.update("\0"),r.update(await g.readFile(w.join(t,n))),r.update("\0");return r.digest("hex")}async function St(t,e=""){let r=await g.readdir(t,{withFileTypes:!0}),n=[];for(let i of r){if(i.name===".DS_Store")continue;let o=e===""?i.name:`${e}/${i.name}`;i.isDirectory()?n.push(...await St(w.join(t,i.name),o)):n.push(o)}return n}async function xe(t){let e=w.join(t,".gitignore"),r=await g.readFile(e,"utf8").catch(()=>"");if(r.split(`
|
|
10
|
+
`).some(o=>o.trim()===bt))return;let i=r.endsWith(`
|
|
11
|
+
`)||r===""?r:`${r}
|
|
12
|
+
`;await g.writeFile(e,`${i}${bt}
|
|
13
|
+
`)}var Te=3e3,Se=3*6e4,Re=10*6e4,Ie=20;async function Rt(t,e){let r=await y(t);if(r.apiBase!==""&&r.apiBase!==t.config.apiBase)throw new s("\u0E41\u0E2D\u0E1B\u0E19\u0E35\u0E49\u0E2D\u0E22\u0E39\u0E48\u0E1A\u0E19 PPLE Platform \u0E04\u0E19\u0E25\u0E30\u0E15\u0E31\u0E27\u0E01\u0E31\u0E1A\u0E17\u0E35\u0E48\u0E04\u0E38\u0E13\u0E40\u0E02\u0E49\u0E32\u0E2A\u0E39\u0E48\u0E23\u0E30\u0E1A\u0E1A\u0E2D\u0E22\u0E39\u0E48",`\u0E41\u0E2D\u0E1B\u0E19\u0E35\u0E49\u0E16\u0E39\u0E01\u0E15\u0E31\u0E49\u0E07\u0E04\u0E48\u0E32\u0E44\u0E27\u0E49\u0E01\u0E31\u0E1A ${r.apiBase}`);let n=await p(t),i=await n.app(r.slug);if(i.status==="retired")throw new s(`"${i.name}" \u0E16\u0E39\u0E01\u0E1B\u0E25\u0E14\u0E23\u0E30\u0E27\u0E32\u0E07\u0E41\u0E25\u0E49\u0E27`,"\u0E41\u0E2D\u0E1B\u0E17\u0E35\u0E48\u0E1B\u0E25\u0E14\u0E23\u0E30\u0E27\u0E32\u0E07\u0E41\u0E25\u0E49\u0E27\u0E14\u0E35\u0E1E\u0E25\u0E2D\u0E22\u0E44\u0E21\u0E48\u0E44\u0E14\u0E49 \u0E2B\u0E32\u0E01\u0E15\u0E49\u0E2D\u0E07\u0E01\u0E32\u0E23\u0E2A\u0E32\u0E19\u0E07\u0E32\u0E19\u0E19\u0E35\u0E49\u0E15\u0E48\u0E2D \u0E43\u0E2B\u0E49\u0E2A\u0E23\u0E49\u0E32\u0E07\u0E41\u0E2D\u0E1B\u0E43\u0E2B\u0E21\u0E48\u0E43\u0E19\u0E04\u0E2D\u0E19\u0E42\u0E0B\u0E25");if(i.status!=="ready")throw new s(`"${i.name}" \u0E22\u0E31\u0E07\u0E44\u0E21\u0E48\u0E1E\u0E23\u0E49\u0E2D\u0E21\u0E23\u0E31\u0E1A\u0E01\u0E32\u0E23\u0E40\u0E1B\u0E25\u0E35\u0E48\u0E22\u0E19\u0E41\u0E1B\u0E25\u0E07`,i.error?`\u0E01\u0E32\u0E23\u0E15\u0E31\u0E49\u0E07\u0E04\u0E48\u0E32\u0E1E\u0E1A\u0E1B\u0E31\u0E0D\u0E2B\u0E32: ${i.error}`:"\u0E15\u0E23\u0E27\u0E08\u0E2A\u0E2D\u0E1A\u0E44\u0E14\u0E49\u0E17\u0E35\u0E48 https://console.ppleth.ai \u0E41\u0E25\u0E49\u0E27\u0E25\u0E2D\u0E07\u0E43\u0E2B\u0E21\u0E48\u0E43\u0E19\u0E2D\u0E35\u0E01\u0E2A\u0E31\u0E01\u0E04\u0E23\u0E39\u0E48");let o=await n.repoToken(r.slug);if(await U(t,r.dir),await I(t,r.dir))t.out.say("\u0E01\u0E33\u0E25\u0E31\u0E07\u0E1A\u0E31\u0E19\u0E17\u0E36\u0E01\u0E01\u0E32\u0E23\u0E40\u0E1B\u0E25\u0E35\u0E48\u0E22\u0E19\u0E41\u0E1B\u0E25\u0E07\u0E02\u0E2D\u0E07\u0E04\u0E38\u0E13\u2026"),await L(t,r.dir,e.message??`\u0E2D\u0E31\u0E1B\u0E40\u0E14\u0E15 ${i.name}`,o);else if(await Pt(t,r.dir,o)){t.out.say(`\u0E44\u0E21\u0E48\u0E21\u0E35\u0E01\u0E32\u0E23\u0E40\u0E1B\u0E25\u0E35\u0E48\u0E22\u0E19\u0E41\u0E1B\u0E25\u0E07\u0E43\u0E2B\u0E21\u0E48 \u2014 ${i.name} \u0E43\u0E0A\u0E49\u0E07\u0E32\u0E19\u0E2D\u0E22\u0E39\u0E48\u0E41\u0E25\u0E49\u0E27\u0E17\u0E35\u0E48 ${i.url}`);return}t.out.say("\u0E01\u0E33\u0E25\u0E31\u0E07\u0E2A\u0E48\u0E07\u0E01\u0E32\u0E23\u0E40\u0E1B\u0E25\u0E35\u0E48\u0E22\u0E19\u0E41\u0E1B\u0E25\u0E07\u0E02\u0E2D\u0E07\u0E04\u0E38\u0E13\u2026"),await $t(t,r.dir,o);let u=await vt(t,r.dir);t.out.say("\u0E01\u0E33\u0E25\u0E31\u0E07\u0E1A\u0E34\u0E25\u0E14\u0E4C\u0E41\u0E2D\u0E1B\u0E02\u0E2D\u0E07\u0E04\u0E38\u0E13\u2026 (\u0E1B\u0E01\u0E15\u0E34\u0E43\u0E0A\u0E49\u0E40\u0E27\u0E25\u0E32\u0E23\u0E32\u0E27\u0E2B\u0E19\u0E36\u0E48\u0E07\u0E19\u0E32\u0E17\u0E35)");let a=await Le(t,n,r.slug,u);Oe(t,i,a)}async function Le(t,e,r,n){let i=t.now(),o;for(;;){let a=(await e.deploys(r)).find(fe=>fe.commit===n);if(a&&(o=a,a.status!=="building"))return a;if(t.now()-i>=(o?Re:Se))throw new s(o?"\u0E2A\u0E48\u0E07\u0E01\u0E32\u0E23\u0E40\u0E1B\u0E25\u0E35\u0E48\u0E22\u0E19\u0E41\u0E1B\u0E25\u0E07\u0E02\u0E2D\u0E07\u0E04\u0E38\u0E13\u0E41\u0E25\u0E49\u0E27 \u0E41\u0E15\u0E48\u0E01\u0E32\u0E23\u0E1A\u0E34\u0E25\u0E14\u0E4C\u0E43\u0E0A\u0E49\u0E40\u0E27\u0E25\u0E32\u0E19\u0E32\u0E19\u0E01\u0E27\u0E48\u0E32\u0E17\u0E35\u0E48\u0E04\u0E32\u0E14\u0E44\u0E27\u0E49":"\u0E2A\u0E48\u0E07\u0E01\u0E32\u0E23\u0E40\u0E1B\u0E25\u0E35\u0E48\u0E22\u0E19\u0E41\u0E1B\u0E25\u0E07\u0E02\u0E2D\u0E07\u0E04\u0E38\u0E13\u0E41\u0E25\u0E49\u0E27 \u0E41\u0E15\u0E48\u0E41\u0E1E\u0E25\u0E15\u0E1F\u0E2D\u0E23\u0E4C\u0E21\u0E22\u0E31\u0E07\u0E44\u0E21\u0E48\u0E40\u0E23\u0E34\u0E48\u0E21\u0E1A\u0E34\u0E25\u0E14\u0E4C",`\u0E15\u0E34\u0E14\u0E15\u0E32\u0E21\u0E08\u0E19\u0E40\u0E2A\u0E23\u0E47\u0E08\u0E44\u0E14\u0E49\u0E17\u0E35\u0E48 https://console.ppleth.ai/apps/${r}`);await t.sleep(Te)}}var Ne="superseded by a newer deploy";function Oe(t,e,r){if(r.status==="failed"){if(r.error===Ne)throw new s("\u0E21\u0E35\u0E01\u0E32\u0E23\u0E14\u0E35\u0E1E\u0E25\u0E2D\u0E22\u0E04\u0E23\u0E31\u0E49\u0E07\u0E43\u0E2B\u0E21\u0E48\u0E21\u0E32\u0E41\u0E17\u0E19\u0E17\u0E35\u0E48\u0E04\u0E23\u0E31\u0E49\u0E07\u0E17\u0E35\u0E48\u0E04\u0E38\u0E13\u0E01\u0E33\u0E25\u0E31\u0E07\u0E23\u0E2D\u0E2D\u0E22\u0E39\u0E48",`\u0E15\u0E34\u0E14\u0E15\u0E32\u0E21\u0E01\u0E32\u0E23\u0E14\u0E35\u0E1E\u0E25\u0E2D\u0E22\u0E04\u0E23\u0E31\u0E49\u0E07\u0E19\u0E31\u0E49\u0E19\u0E44\u0E14\u0E49\u0E17\u0E35\u0E48 https://console.ppleth.ai/apps/${e.slug}`);let i=r.log?je(r.log,Ie):r.error;throw i&&(t.out.say(),t.out.say(i),t.out.say()),new s(`\u0E1A\u0E34\u0E25\u0E14\u0E4C ${e.name} \u0E44\u0E21\u0E48\u0E2A\u0E33\u0E40\u0E23\u0E47\u0E08 \u0E2A\u0E34\u0E48\u0E07\u0E17\u0E35\u0E48\u0E43\u0E0A\u0E49\u0E07\u0E32\u0E19\u0E2D\u0E22\u0E39\u0E48\u0E08\u0E36\u0E07\u0E22\u0E31\u0E07\u0E44\u0E21\u0E48\u0E40\u0E1B\u0E25\u0E35\u0E48\u0E22\u0E19\u0E41\u0E1B\u0E25\u0E07`,i?"\u0E2A\u0E48\u0E07\u0E02\u0E49\u0E2D\u0E04\u0E27\u0E32\u0E21\u0E14\u0E49\u0E32\u0E19\u0E1A\u0E19\u0E43\u0E2B\u0E49 AI coding agent \u0E02\u0E2D\u0E07\u0E04\u0E38\u0E13 \u2014 \u0E43\u0E19\u0E19\u0E31\u0E49\u0E19\u0E1A\u0E2D\u0E01\u0E27\u0E48\u0E32\u0E15\u0E49\u0E2D\u0E07\u0E41\u0E01\u0E49\u0E2D\u0E30\u0E44\u0E23":`\u0E14\u0E39\u0E23\u0E32\u0E22\u0E25\u0E30\u0E40\u0E2D\u0E35\u0E22\u0E14\u0E44\u0E14\u0E49\u0E17\u0E35\u0E48 https://console.ppleth.ai/apps/${e.slug}`)}let n=r.migrations.applied??[];if(n.length>0&&t.out.say(`\u0E43\u0E0A\u0E49 migration ${n.length} \u0E23\u0E32\u0E22\u0E01\u0E32\u0E23\u0E01\u0E31\u0E1A\u0E10\u0E32\u0E19\u0E02\u0E49\u0E2D\u0E21\u0E39\u0E25\u0E02\u0E2D\u0E07\u0E04\u0E38\u0E13\u0E41\u0E25\u0E49\u0E27`),r.status==="unverified"){t.out.say(`\u0E2D\u0E31\u0E1B\u0E40\u0E14\u0E15 ${e.name} \u0E41\u0E25\u0E49\u0E27 \u0E41\u0E15\u0E48\u0E41\u0E2D\u0E1B\u0E22\u0E31\u0E07\u0E44\u0E21\u0E48\u0E15\u0E2D\u0E1A\u0E2A\u0E19\u0E2D\u0E07`),t.out.say(`\u0E23\u0E2D\u0E2A\u0E31\u0E01\u0E04\u0E23\u0E39\u0E48 \u0E41\u0E25\u0E49\u0E27\u0E40\u0E1B\u0E34\u0E14 ${e.url}`);return}t.out.say(`${e.name} \u0E43\u0E0A\u0E49\u0E07\u0E32\u0E19\u0E44\u0E14\u0E49\u0E41\u0E25\u0E49\u0E27\u0E17\u0E35\u0E48 ${e.url}`)}function je(t,e){return t.split(`
|
|
14
|
+
`).slice(-e).join(`
|
|
15
|
+
`).trim()}import Be from"node:fs/promises";import Ue from"node:path";async function It(t){let e=await y(t),n=await(await p(t)).env(e.slug);if(n.length===0){t.out.say("\u0E22\u0E31\u0E07\u0E44\u0E21\u0E48\u0E44\u0E14\u0E49\u0E15\u0E31\u0E49\u0E07\u0E04\u0E48\u0E32\u0E43\u0E14 \u0E46"),t.out.say("\u0E15\u0E31\u0E27\u0E41\u0E1B\u0E23\u0E17\u0E35\u0E48\u0E04\u0E38\u0E13\u0E15\u0E31\u0E49\u0E07\u0E08\u0E30\u0E21\u0E35\u0E1C\u0E25\u0E43\u0E19\u0E01\u0E32\u0E23\u0E14\u0E35\u0E1E\u0E25\u0E2D\u0E22\u0E04\u0E23\u0E31\u0E49\u0E07\u0E16\u0E31\u0E14\u0E44\u0E1B");return}for(let i of n)i.secret?t.out.say(`${i.key}=(secret)`):t.out.say(`${i.key}=${i.value??""}`);t.out.say(""),t.out.say("\u0E08\u0E30\u0E21\u0E35\u0E1C\u0E25\u0E43\u0E19\u0E01\u0E32\u0E23\u0E14\u0E35\u0E1E\u0E25\u0E2D\u0E22\u0E04\u0E23\u0E31\u0E49\u0E07\u0E16\u0E31\u0E14\u0E44\u0E1B")}async function Lt(t,e){let r=await y(t),n=await Me(t,e),o=await(await p(t)).setEnv(r.slug,e.key,n,e.secret);t.out.say(`\u0E1A\u0E31\u0E19\u0E17\u0E36\u0E01 ${o.key}${o.secret?" (secret)":""} \u0E41\u0E25\u0E49\u0E27`),t.out.say("\u0E08\u0E30\u0E21\u0E35\u0E1C\u0E25\u0E43\u0E19\u0E01\u0E32\u0E23\u0E14\u0E35\u0E1E\u0E25\u0E2D\u0E22\u0E04\u0E23\u0E31\u0E49\u0E07\u0E16\u0E31\u0E14\u0E44\u0E1B")}async function Nt(t,e){let r=await y(t);await(await p(t)).deleteEnv(r.slug,e),t.out.say(`\u0E25\u0E1A ${e} \u0E41\u0E25\u0E49\u0E27`),t.out.say("\u0E08\u0E30\u0E21\u0E35\u0E1C\u0E25\u0E43\u0E19\u0E01\u0E32\u0E23\u0E14\u0E35\u0E1E\u0E25\u0E2D\u0E22\u0E04\u0E23\u0E31\u0E49\u0E07\u0E16\u0E31\u0E14\u0E44\u0E1B")}async function Me(t,e){if(e.file!==void 0&&e.value!==void 0)throw new s("\u0E2A\u0E48\u0E07\u0E04\u0E48\u0E32\u0E21\u0E32\u0E40\u0E1B\u0E47\u0E19 argument \u0E2B\u0E23\u0E37\u0E2D\u0E1C\u0E48\u0E32\u0E19 `--file` \u0E2D\u0E22\u0E48\u0E32\u0E07\u0E43\u0E14\u0E2D\u0E22\u0E48\u0E32\u0E07\u0E2B\u0E19\u0E36\u0E48\u0E07 \u0E44\u0E21\u0E48\u0E43\u0E0A\u0E48\u0E17\u0E31\u0E49\u0E07\u0E2A\u0E2D\u0E07\u0E2D\u0E22\u0E48\u0E32\u0E07");if(e.file!==void 0){let r=Ue.resolve(t.cwd,e.file),n=await Be.readFile(r,"utf8").catch(()=>null);if(n===null)throw new s(`\u0E2D\u0E48\u0E32\u0E19\u0E44\u0E1F\u0E25\u0E4C ${e.file} \u0E44\u0E21\u0E48\u0E44\u0E14\u0E49`,"\u0E15\u0E23\u0E27\u0E08\u0E2A\u0E2D\u0E1A\u0E1E\u0E32\u0E18\u0E41\u0E25\u0E49\u0E27\u0E25\u0E2D\u0E07\u0E43\u0E2B\u0E21\u0E48\u0E2D\u0E35\u0E01\u0E04\u0E23\u0E31\u0E49\u0E07");return n}if(e.value!==void 0)return e.value;if(t.interactive)throw new s("`pple env set` \u0E15\u0E49\u0E2D\u0E07\u0E23\u0E30\u0E1A\u0E38\u0E04\u0E48\u0E32","\u0E2A\u0E48\u0E07\u0E04\u0E48\u0E32\u0E21\u0E32\u0E40\u0E1B\u0E47\u0E19 argument \u0E1C\u0E48\u0E32\u0E19 `--file` \u0E2B\u0E23\u0E37\u0E2D pipe \u0E17\u0E32\u0E07 stdin");return t.readStdin()}var Fe=20,Ge=/[\u0E31\u0E34-\u0E3A\u0E47-\u0E4E]/g;function l(t,e){let r=t.replace(Ge,"").length;return t+" ".repeat(Math.max(0,e-r))}var Ke={ready:"\u0E1E\u0E23\u0E49\u0E2D\u0E21\u0E43\u0E0A\u0E49\u0E07\u0E32\u0E19",provisioning:"\u0E01\u0E33\u0E25\u0E31\u0E07\u0E08\u0E31\u0E14\u0E40\u0E15\u0E23\u0E35\u0E22\u0E21",failed:"\u0E25\u0E49\u0E21\u0E40\u0E2B\u0E25\u0E27",retired:"\u0E1B\u0E25\u0E14\u0E23\u0E30\u0E27\u0E32\u0E07\u0E41\u0E25\u0E49\u0E27"},Ot={draft:"\u0E09\u0E1A\u0E31\u0E1A\u0E23\u0E48\u0E32\u0E07",beta:"\u0E17\u0E14\u0E25\u0E2D\u0E07\u0E43\u0E0A\u0E49",live:"\u0E40\u0E1C\u0E22\u0E41\u0E1E\u0E23\u0E48\u0E08\u0E23\u0E34\u0E07"},He={owner:"\u0E40\u0E08\u0E49\u0E32\u0E02\u0E2D\u0E07",collaborator:"\u0E1C\u0E39\u0E49\u0E23\u0E48\u0E27\u0E21\u0E1E\u0E31\u0E12\u0E19\u0E32"},jt={live:"\u0E43\u0E0A\u0E49\u0E07\u0E32\u0E19\u0E2D\u0E22\u0E39\u0E48",building:"\u0E01\u0E33\u0E25\u0E31\u0E07\u0E1A\u0E34\u0E25\u0E14\u0E4C",unverified:"\u0E22\u0E31\u0E07\u0E44\u0E21\u0E48\u0E22\u0E37\u0E19\u0E22\u0E31\u0E19",failed:"\u0E25\u0E49\u0E21\u0E40\u0E2B\u0E25\u0E27"},Ve={pending:"\u0E23\u0E2D\u0E14\u0E33\u0E40\u0E19\u0E34\u0E19\u0E01\u0E32\u0E23",approved:"\u0E2D\u0E19\u0E38\u0E21\u0E31\u0E15\u0E34\u0E41\u0E25\u0E49\u0E27",denied:"\u0E1B\u0E0F\u0E34\u0E40\u0E2A\u0E18\u0E41\u0E25\u0E49\u0E27"};function v(t,e){return t[e]??e}async function Bt(t,e){let r=await Je(t,e),n=await p(t),i=await n.app(r),o=i.role!=="collaborator",[u,a,c,P]=await Promise.all([n.metrics(r),n.deploys(r),n.env(r),o?Ye(n,r):Promise.resolve(null)]);We(t,i),Xe(t,u),ze(t,a),Ze(t,c),P&&(Qe(t,i,P.requests,P.invites),tr(t,P.collaborators),er(t,P.requests)),t.out.say(""),t.out.say("\u0E2B\u0E32\u0E01\u0E15\u0E49\u0E2D\u0E07\u0E01\u0E32\u0E23\u0E40\u0E1B\u0E25\u0E35\u0E48\u0E22\u0E19\u0E42\u0E04\u0E27\u0E15\u0E32 \u0E04\u0E48\u0E32 env \u0E1C\u0E39\u0E49\u0E23\u0E48\u0E27\u0E21\u0E1E\u0E31\u0E12\u0E19\u0E32 \u0E2B\u0E23\u0E37\u0E2D\u0E01\u0E32\u0E23\u0E40\u0E1C\u0E22\u0E41\u0E1E\u0E23\u0E48 \u0E43\u0E0A\u0E49 https://console.ppleth.ai")}async function Je(t,e){if(e)return e;try{return(await y(t)).slug}catch(r){throw r instanceof s&&r.message==="\u0E42\u0E1F\u0E25\u0E40\u0E14\u0E2D\u0E23\u0E4C\u0E19\u0E35\u0E49\u0E44\u0E21\u0E48\u0E43\u0E0A\u0E48\u0E41\u0E2D\u0E1B PPLE"?new s("\u0E41\u0E2D\u0E1B\u0E44\u0E2B\u0E19? `pple info` \u0E15\u0E49\u0E2D\u0E07\u0E21\u0E35 App Link \u0E2B\u0E23\u0E37\u0E2D slug","\u0E40\u0E02\u0E49\u0E32\u0E44\u0E1B\u0E43\u0E19\u0E42\u0E1F\u0E25\u0E40\u0E14\u0E2D\u0E23\u0E4C\u0E02\u0E2D\u0E07\u0E41\u0E2D\u0E1B \u0E43\u0E2A\u0E48 slug (`pple info <slug>`) \u0E2B\u0E23\u0E37\u0E2D\u0E40\u0E1B\u0E34\u0E14 https://console.ppleth.ai"):r}}async function Ye(t,e){let[r,n,i]=await Promise.all([t.collaborators(e),t.requests(e),t.invites(e)]);return{collaborators:r,requests:n,invites:i}}function We(t,e){t.out.say(e.name),t.out.say(` ${l("slug",18)}${e.slug}`),t.out.say(` ${l("URL",18)}${e.url}`),e.customAddress&&t.out.say(` ${l("\u0E17\u0E35\u0E48\u0E2D\u0E22\u0E39\u0E48\u0E17\u0E35\u0E48\u0E01\u0E33\u0E2B\u0E19\u0E14\u0E40\u0E2D\u0E07",18)}${e.customAddress}`),t.out.say(` ${l("\u0E2A\u0E16\u0E32\u0E19\u0E30",18)}${v(Ke,e.status)}`),t.out.say(` ${l("\u0E01\u0E32\u0E23\u0E40\u0E1C\u0E22\u0E41\u0E1E\u0E23\u0E48",18)}${v(Ot,e.tier??"draft")}`),e.role&&t.out.say(` ${l("\u0E1A\u0E17\u0E1A\u0E32\u0E17\u0E02\u0E2D\u0E07\u0E04\u0E38\u0E13",18)}${v(He,e.role)}`),e.deploy&&t.out.say(` ${l("\u0E01\u0E32\u0E23\u0E14\u0E35\u0E1E\u0E25\u0E2D\u0E22\u0E1B\u0E31\u0E08\u0E08\u0E38\u0E1A\u0E31\u0E19",18)}${v(jt,e.deploy.status)}`+(e.deploy.message?` \u2014 ${e.deploy.message}`:"")),e.error&&t.out.say(` ${l("\u0E02\u0E49\u0E2D\u0E1C\u0E34\u0E14\u0E1E\u0E25\u0E32\u0E14",18)}${e.error}`)}function Xe(t,e){t.out.say(""),t.out.say("\u0E01\u0E32\u0E23\u0E43\u0E0A\u0E49\u0E07\u0E32\u0E19\u0E41\u0E25\u0E30\u0E42\u0E04\u0E27\u0E15\u0E32\u0E17\u0E23\u0E31\u0E1E\u0E22\u0E32\u0E01\u0E23"),t.out.say(` ${l("CPU \u0E15\u0E48\u0E2D request",20)}${e.limits.cpuMs} ms`),t.out.say(` ${l("\u0E01\u0E32\u0E23\u0E41\u0E08\u0E49\u0E07\u0E40\u0E15\u0E37\u0E2D\u0E19",20)}${_(e.usage.notificationsSent)}`+(e.usage.notificationsSent===null?" (\u0E14\u0E39\u0E02\u0E49\u0E2D\u0E21\u0E39\u0E25\u0E44\u0E21\u0E48\u0E44\u0E14\u0E49\u0E43\u0E19\u0E02\u0E13\u0E30\u0E19\u0E35\u0E49)":` \u0E08\u0E32\u0E01\u0E42\u0E04\u0E27\u0E15\u0E32 ${_(e.limits.notificationsPerDay)} \u0E04\u0E23\u0E31\u0E49\u0E07\u0E27\u0E31\u0E19\u0E19\u0E35\u0E49`)),t.out.say(` ${l("\u0E02\u0E49\u0E2D\u0E1C\u0E34\u0E14\u0E1E\u0E25\u0E32\u0E14 (24 \u0E0A\u0E21.)",20)}${_(e.usage.errors)}`+(e.usage.errors===null?" (\u0E14\u0E39\u0E02\u0E49\u0E2D\u0E21\u0E39\u0E25\u0E44\u0E21\u0E48\u0E44\u0E14\u0E49\u0E43\u0E19\u0E02\u0E13\u0E30\u0E19\u0E35\u0E49)":e.usage.errors===0?" (\u0E44\u0E21\u0E48\u0E21\u0E35\u0E43\u0E19 24 \u0E0A\u0E31\u0E48\u0E27\u0E42\u0E21\u0E07\u0E17\u0E35\u0E48\u0E1C\u0E48\u0E32\u0E19\u0E21\u0E32)":e.usage.requests===null?" (\u0E04\u0E33\u0E02\u0E2D\u0E17\u0E35\u0E48\u0E25\u0E49\u0E21\u0E40\u0E2B\u0E25\u0E27\u0E43\u0E19 24 \u0E0A\u0E31\u0E48\u0E27\u0E42\u0E21\u0E07\u0E17\u0E35\u0E48\u0E1C\u0E48\u0E32\u0E19\u0E21\u0E32)":` \u0E08\u0E32\u0E01\u0E17\u0E31\u0E49\u0E07\u0E2B\u0E21\u0E14 ${_(e.usage.requests)} \u0E04\u0E33\u0E02\u0E2D`)),t.out.say(` ${l("\u0E1C\u0E39\u0E49\u0E43\u0E0A\u0E49\u0E41\u0E2D\u0E1B",20)}${_(e.usage.appUsers)}`+(e.usage.appUsers===null?" (\u0E14\u0E39\u0E02\u0E49\u0E2D\u0E21\u0E39\u0E25\u0E44\u0E21\u0E48\u0E44\u0E14\u0E49\u0E43\u0E19\u0E02\u0E13\u0E30\u0E19\u0E35\u0E49)":""))}function _(t){return t===null?"\u2014":String(t)}function ze(t,e){if(t.out.say(""),t.out.say("\u0E01\u0E32\u0E23\u0E14\u0E35\u0E1E\u0E25\u0E2D\u0E22\u0E25\u0E48\u0E32\u0E2A\u0E38\u0E14"),e.length===0){t.out.say(" \u0E22\u0E31\u0E07\u0E44\u0E21\u0E48\u0E21\u0E35");return}for(let r of e.slice(0,10)){let n=r.commit.slice(0,7),i=r.message?` \u2014 ${r.message}`:"",o=v(jt,r.status);t.out.say(` ${l(o,13)} ${n}${i}`)}}function Ze(t,e){if(t.out.say(""),t.out.say("\u0E04\u0E48\u0E32 env"),e.length===0){t.out.say(" \u0E22\u0E31\u0E07\u0E44\u0E21\u0E48\u0E44\u0E14\u0E49\u0E15\u0E31\u0E49\u0E07\u0E04\u0E48\u0E32\u0E43\u0E14 \u0E46");return}for(let r of e)r.secret?t.out.say(` ${r.key}=(secret)`):t.out.say(` ${r.key}=${r.value??""}`)}function Qe(t,e,r,n){t.out.say(""),t.out.say("\u0E01\u0E32\u0E23\u0E40\u0E1C\u0E22\u0E41\u0E1E\u0E23\u0E48"),t.out.say(` ${l("\u0E23\u0E30\u0E14\u0E31\u0E1A",18)}${v(Ot,e.tier??"draft")}`),e.customAddress&&t.out.say(` ${l("\u0E17\u0E35\u0E48\u0E2D\u0E22\u0E39\u0E48\u0E17\u0E35\u0E48\u0E01\u0E33\u0E2B\u0E19\u0E14\u0E40\u0E2D\u0E07",18)}${e.customAddress}`);let i=r.find(o=>o.type==="publish"&&o.status==="pending");if(i&&t.out.say(` ${l("\u0E04\u0E33\u0E02\u0E2D\u0E17\u0E35\u0E48\u0E23\u0E2D\u0E2D\u0E22\u0E39\u0E48",18)}${Ut(i)}`),e.tier==="beta"){let o=n.filter(u=>u.status!=="DECLINED").length;t.out.say(` ${l("\u0E04\u0E33\u0E40\u0E0A\u0E34\u0E0D\u0E17\u0E14\u0E25\u0E2D\u0E07\u0E43\u0E0A\u0E49",18)}\u0E43\u0E0A\u0E49\u0E44\u0E1B ${o} \u0E08\u0E32\u0E01 ${Fe} \u0E17\u0E35\u0E48\u0E19\u0E31\u0E48\u0E07`)}}function tr(t,e){if(t.out.say(""),t.out.say("\u0E1C\u0E39\u0E49\u0E23\u0E48\u0E27\u0E21\u0E1E\u0E31\u0E12\u0E19\u0E32"),e.length===0){t.out.say(" \u0E22\u0E31\u0E07\u0E44\u0E21\u0E48\u0E21\u0E35");return}for(let r of e){let n=r.maskedName??"\u0E1C\u0E39\u0E49\u0E23\u0E48\u0E27\u0E21\u0E1E\u0E31\u0E12\u0E19\u0E32",i=r.phoneNumber?` (${r.phoneNumber})`:"";t.out.say(` ${n}${i}`)}}function er(t,e){if(t.out.say(""),t.out.say("\u0E1B\u0E23\u0E30\u0E27\u0E31\u0E15\u0E34\u0E04\u0E33\u0E02\u0E2D"),e.length===0){t.out.say(" \u0E22\u0E31\u0E07\u0E44\u0E21\u0E48\u0E21\u0E35");return}for(let r of e.slice(0,10)){let n=r.reason?` \u2014 ${r.reason}`:"",i=v(Ve,r.status);t.out.say(` ${l(i,13)} ${Ut(r)}${n}`)}}function Ut(t){if(t.type==="publish"){let r=Array.isArray(t.payload.roles)?t.payload.roles:[],n=typeof t.payload.customAddress=="string"?` \xB7 \u0E17\u0E35\u0E48 ${t.payload.customAddress}`:"";return`\u0E04\u0E33\u0E02\u0E2D\u0E40\u0E1C\u0E22\u0E41\u0E1E\u0E23\u0E48 \xB7 \u0E02\u0E36\u0E49\u0E19\u0E40\u0E1C\u0E22\u0E41\u0E1E\u0E23\u0E48\u0E08\u0E23\u0E34\u0E07 \xB7 ${r.length===0?"\u0E17\u0E38\u0E01\u0E04\u0E19":r.join(", ")}${n}`}if(t.type==="retire")return"\u0E04\u0E33\u0E02\u0E2D\u0E1B\u0E25\u0E14\u0E23\u0E30\u0E27\u0E32\u0E07 \xB7 \u0E1B\u0E25\u0E14\u0E23\u0E30\u0E27\u0E32\u0E07\u0E41\u0E2D\u0E1B";let e=[];return typeof t.payload.cpuMs=="number"&&e.push(`CPU ${t.payload.cpuMs} ms/request`),typeof t.payload.notificationsPerDay=="number"&&e.push(`\u0E01\u0E32\u0E23\u0E41\u0E08\u0E49\u0E07\u0E40\u0E15\u0E37\u0E2D\u0E19 ${t.payload.notificationsPerDay} \u0E04\u0E23\u0E31\u0E49\u0E07/\u0E27\u0E31\u0E19`),`\u0E04\u0E33\u0E02\u0E2D\u0E40\u0E1E\u0E34\u0E48\u0E21\u0E42\u0E04\u0E27\u0E15\u0E32 \xB7 \u0E02\u0E2D\u0E40\u0E1E\u0E34\u0E48\u0E21 ${e.length>0?e.join(" \u0E41\u0E25\u0E30 "):"\u0E42\u0E04\u0E27\u0E15\u0E32"}`}import Kt from"node:fs/promises";import b from"node:path";import E from"node:fs/promises";import Mt from"node:path";var rr=new Set([".git","node_modules","dist",".wrangler",".dev.vars",".env"]),nr=new Map([["gitignore",".gitignore"]]),ir="pple-app",or=new Set(["package.json","package-lock.json","wrangler.jsonc"]);async function qt(t,e,r){if(await E.readdir(t).catch(()=>null)===null)throw new s("\u0E44\u0E21\u0E48\u0E1E\u0E1A\u0E40\u0E17\u0E21\u0E40\u0E1E\u0E25\u0E15\u0E41\u0E2D\u0E1B PPLE \u0E43\u0E19\u0E01\u0E32\u0E23\u0E15\u0E34\u0E14\u0E15\u0E31\u0E49\u0E07 CLI \u0E0A\u0E38\u0E14\u0E19\u0E35\u0E49",`\u0E15\u0E34\u0E14\u0E15\u0E31\u0E49\u0E07 CLI \u0E43\u0E2B\u0E21\u0E48 (\`${m}\`) \u0E41\u0E25\u0E49\u0E27\u0E25\u0E2D\u0E07\u0E2D\u0E35\u0E01\u0E04\u0E23\u0E31\u0E49\u0E07`);let i=[];return await Ft({from:t,to:e,prefix:"",slug:r,written:i}),i.sort()}async function Ft(t){for(let e of await E.readdir(t.from,{withFileTypes:!0})){if(rr.has(e.name))continue;let r=nr.get(e.name)??e.name,n=Mt.join(t.from,e.name),i=Mt.join(t.to,r),o=t.prefix===""?r:`${t.prefix}/${r}`;if(e.isDirectory()){await E.mkdir(i,{recursive:!0}),await Ft({...t,from:n,to:i,prefix:o});continue}if(or.has(r)){let u=await E.readFile(n,"utf8");await E.writeFile(i,sr(u,ir,t.slug))}else await E.copyFile(n,i);t.written.push(o)}}function sr(t,e,r){return t.split(e).join(r)}var ar=3e3,ur=5*6e4;async function Ht(t,e){let r=await p(t),n=e.slug?await r.app(e.slug):await pr(t,r,await cr(t,e.name));if(!n.repo)throw new s(`"${n.name}" \u0E22\u0E31\u0E07\u0E15\u0E31\u0E49\u0E07\u0E04\u0E48\u0E32\u0E44\u0E21\u0E48\u0E40\u0E2A\u0E23\u0E47\u0E08`,`\u0E23\u0E2D\u0E2A\u0E31\u0E01\u0E04\u0E23\u0E39\u0E48\u0E41\u0E25\u0E49\u0E27\u0E23\u0E31\u0E19 \`pple init ${n.slug}\` \u0E2B\u0E32\u0E01\u0E22\u0E31\u0E07\u0E40\u0E1B\u0E47\u0E19\u0E41\u0E1A\u0E1A\u0E19\u0E35\u0E49 \u0E01\u0E23\u0E38\u0E13\u0E32\u0E15\u0E34\u0E14\u0E15\u0E48\u0E2D\u0E17\u0E35\u0E21\u0E41\u0E1E\u0E25\u0E15\u0E1F\u0E2D\u0E23\u0E4C\u0E21`);n.status==="provisioning"&&t.out.say("\u0E41\u0E2D\u0E1B\u0E02\u0E2D\u0E07\u0E04\u0E38\u0E13\u0E22\u0E31\u0E07\u0E2D\u0E22\u0E39\u0E48\u0E23\u0E30\u0E2B\u0E27\u0E48\u0E32\u0E07\u0E01\u0E32\u0E23\u0E15\u0E31\u0E49\u0E07\u0E04\u0E48\u0E32\u0E1A\u0E19\u0E41\u0E1E\u0E25\u0E15\u0E1F\u0E2D\u0E23\u0E4C\u0E21\u2026");let i=b.resolve(t.cwd,e.dir??n.slug);await mr(i);let o=await r.repoToken(n.slug);if(t.out.say(`\u0E01\u0E33\u0E25\u0E31\u0E07\u0E15\u0E31\u0E49\u0E07\u0E04\u0E48\u0E32 "${n.name}" \u0E43\u0E19 ${b.basename(i)}/\u2026`),await ht(t,fr(t,n.repo),i,o),await gr(i))throw new s(`"${n.name}" \u0E21\u0E35\u0E42\u0E04\u0E49\u0E14\u0E2D\u0E22\u0E39\u0E48\u0E41\u0E25\u0E49\u0E27 \u0E08\u0E36\u0E07\u0E44\u0E21\u0E48\u0E21\u0E35\u0E2D\u0E30\u0E44\u0E23\u0E15\u0E49\u0E2D\u0E07\u0E15\u0E31\u0E49\u0E07\u0E04\u0E48\u0E32`,"\u0E17\u0E33\u0E07\u0E32\u0E19\u0E43\u0E19\u0E42\u0E1F\u0E25\u0E40\u0E14\u0E2D\u0E23\u0E4C\u0E19\u0E31\u0E49\u0E19\u0E41\u0E25\u0E49\u0E27\u0E23\u0E31\u0E19 `pple deploy` \u0E40\u0E1E\u0E37\u0E48\u0E2D\u0E19\u0E33\u0E01\u0E32\u0E23\u0E40\u0E1B\u0E25\u0E35\u0E48\u0E22\u0E19\u0E41\u0E1B\u0E25\u0E07\u0E02\u0E36\u0E49\u0E19\u0E43\u0E0A\u0E49\u0E07\u0E32\u0E19\u0E08\u0E23\u0E34\u0E07");await qt(t.templateDir,i,n.slug),await Dt(i,{slug:n.slug,apiBase:t.config.apiBase,url:n.url}),await U(t,i),await I(t,i)&&await L(t,i,"\u0E40\u0E23\u0E34\u0E48\u0E21\u0E08\u0E32\u0E01\u0E40\u0E17\u0E21\u0E40\u0E1E\u0E25\u0E15\u0E21\u0E32\u0E15\u0E23\u0E10\u0E32\u0E19\u0E02\u0E2D\u0E07 PPLE",o);let u=await lr(t,i);dr(t,n,i,u)}async function lr(t,e){t.out.say("\u0E01\u0E33\u0E25\u0E31\u0E07\u0E15\u0E34\u0E14\u0E15\u0E31\u0E49\u0E07\u0E41\u0E1E\u0E47\u0E01\u0E40\u0E01\u0E08\u0E41\u0E25\u0E30\u0E40\u0E15\u0E23\u0E35\u0E22\u0E21\u0E10\u0E32\u0E19\u0E02\u0E49\u0E2D\u0E21\u0E39\u0E25\u0E1A\u0E19\u0E40\u0E04\u0E23\u0E37\u0E48\u0E2D\u0E07\u2026");let r=[["npm",["install"]],["npm",["run","db:migrate:local"]]];for(let[n,i]of r){let o=await t.run(n,i,{cwd:e}).catch(()=>null);if(!o||o.code!==0)return!1}return!0}async function cr(t,e){if(await V(t))throw new s("\u0E42\u0E1F\u0E25\u0E40\u0E14\u0E2D\u0E23\u0E4C\u0E19\u0E35\u0E49\u0E40\u0E0A\u0E37\u0E48\u0E2D\u0E21\u0E01\u0E31\u0E1A\u0E41\u0E2D\u0E1B PPLE \u0E2D\u0E22\u0E39\u0E48\u0E41\u0E25\u0E49\u0E27","\u0E23\u0E31\u0E19 `pple info` \u0E2B\u0E23\u0E37\u0E2D `pple deploy` \u0E17\u0E35\u0E48\u0E19\u0E35\u0E48 \u0E2B\u0E23\u0E37\u0E2D\u0E22\u0E49\u0E32\u0E22\u0E44\u0E1B\u0E42\u0E1F\u0E25\u0E40\u0E14\u0E2D\u0E23\u0E4C\u0E2D\u0E37\u0E48\u0E19\u0E40\u0E1E\u0E37\u0E48\u0E2D\u0E2A\u0E23\u0E49\u0E32\u0E07\u0E41\u0E2D\u0E1B\u0E43\u0E2B\u0E21\u0E48");if(e!==void 0){let n=e.trim();if(!n)throw new s("`--name` \u0E15\u0E49\u0E2D\u0E07\u0E23\u0E30\u0E1A\u0E38\u0E0A\u0E37\u0E48\u0E2D\u0E41\u0E2D\u0E1B",'\u0E15\u0E31\u0E27\u0E2D\u0E22\u0E48\u0E32\u0E07: `pple init --name "\u0E25\u0E07\u0E17\u0E30\u0E40\u0E1A\u0E35\u0E22\u0E19\u0E2D\u0E32\u0E2A\u0E32\u0E2A\u0E21\u0E31\u0E04\u0E23"`');return n}if(!t.interactive)throw new s("`pple init` \u0E15\u0E49\u0E2D\u0E07\u0E23\u0E30\u0E1A\u0E38\u0E0A\u0E37\u0E48\u0E2D\u0E41\u0E2D\u0E1B",'\u0E43\u0E2A\u0E48 `--name "\u0E0A\u0E37\u0E48\u0E2D\u0E41\u0E2D\u0E1B\u0E02\u0E2D\u0E07\u0E04\u0E38\u0E13"` \u0E2B\u0E23\u0E37\u0E2D\u0E23\u0E31\u0E19\u0E43\u0E19\u0E40\u0E17\u0E2D\u0E23\u0E4C\u0E21\u0E34\u0E19\u0E31\u0E25\u0E40\u0E1E\u0E37\u0E48\u0E2D\u0E43\u0E2B\u0E49\u0E23\u0E30\u0E1A\u0E1A\u0E16\u0E32\u0E21');let r=(await t.ask("\u0E0A\u0E37\u0E48\u0E2D\u0E41\u0E2D\u0E1B:")).trim();if(!r)throw new s("\u0E15\u0E49\u0E2D\u0E07\u0E23\u0E30\u0E1A\u0E38\u0E0A\u0E37\u0E48\u0E2D\u0E41\u0E2D\u0E1B\u0E40\u0E1E\u0E37\u0E48\u0E2D\u0E2A\u0E23\u0E49\u0E32\u0E07\u0E41\u0E2D\u0E1B",'\u0E25\u0E2D\u0E07\u0E43\u0E2B\u0E21\u0E48\u0E2D\u0E35\u0E01\u0E04\u0E23\u0E31\u0E49\u0E07 \u0E2B\u0E23\u0E37\u0E2D\u0E43\u0E2A\u0E48 `--name "\u0E0A\u0E37\u0E48\u0E2D\u0E41\u0E2D\u0E1B\u0E02\u0E2D\u0E07\u0E04\u0E38\u0E13"`');return r}async function pr(t,e,r){t.out.say(`\u0E01\u0E33\u0E25\u0E31\u0E07\u0E2A\u0E23\u0E49\u0E32\u0E07 "${r}" \u0E1A\u0E19\u0E41\u0E1E\u0E25\u0E15\u0E1F\u0E2D\u0E23\u0E4C\u0E21\u2026`);let n=await e.createApp(r);if(Gt(n))return n;t.out.say("\u0E01\u0E33\u0E25\u0E31\u0E07\u0E23\u0E2D\u0E41\u0E1E\u0E25\u0E15\u0E1F\u0E2D\u0E23\u0E4C\u0E21\u0E15\u0E31\u0E49\u0E07\u0E04\u0E48\u0E32\u0E43\u0E2B\u0E49\u0E40\u0E2A\u0E23\u0E47\u0E08\u2026");let i=t.now();for(;;){if(n.status==="failed")throw new s(`\u0E15\u0E31\u0E49\u0E07\u0E04\u0E48\u0E32 "${n.name}" \u0E1A\u0E19\u0E41\u0E1E\u0E25\u0E15\u0E1F\u0E2D\u0E23\u0E4C\u0E21\u0E44\u0E21\u0E48\u0E2A\u0E33\u0E40\u0E23\u0E47\u0E08`,n.error?`${n.error} slug \u0E02\u0E2D\u0E07\u0E41\u0E2D\u0E1B\u0E04\u0E37\u0E2D ${n.slug} \u2014 \u0E01\u0E23\u0E38\u0E13\u0E32\u0E15\u0E34\u0E14\u0E15\u0E48\u0E2D\u0E17\u0E35\u0E21\u0E41\u0E1E\u0E25\u0E15\u0E1F\u0E2D\u0E23\u0E4C\u0E21 \u0E2B\u0E23\u0E37\u0E2D\u0E25\u0E2D\u0E07 \`pple init ${n.slug}\` \u0E20\u0E32\u0E22\u0E2B\u0E25\u0E31\u0E07`:`slug \u0E02\u0E2D\u0E07\u0E41\u0E2D\u0E1B\u0E04\u0E37\u0E2D ${n.slug} \u2014 \u0E01\u0E23\u0E38\u0E13\u0E32\u0E15\u0E34\u0E14\u0E15\u0E48\u0E2D\u0E17\u0E35\u0E21\u0E41\u0E1E\u0E25\u0E15\u0E1F\u0E2D\u0E23\u0E4C\u0E21 \u0E2B\u0E23\u0E37\u0E2D\u0E25\u0E2D\u0E07 \`pple init ${n.slug}\` \u0E20\u0E32\u0E22\u0E2B\u0E25\u0E31\u0E07`);if(t.now()-i>=ur)throw new s(`"${n.name}" \u0E22\u0E31\u0E07\u0E2D\u0E22\u0E39\u0E48\u0E23\u0E30\u0E2B\u0E27\u0E48\u0E32\u0E07\u0E01\u0E32\u0E23\u0E15\u0E31\u0E49\u0E07\u0E04\u0E48\u0E32\u0E1A\u0E19\u0E41\u0E1E\u0E25\u0E15\u0E1F\u0E2D\u0E23\u0E4C\u0E21`,`\u0E25\u0E2D\u0E07\u0E43\u0E2B\u0E21\u0E48\u0E14\u0E49\u0E27\u0E22 \`pple init ${n.slug}\` \u0E43\u0E19\u0E2D\u0E35\u0E01\u0E2A\u0E31\u0E01\u0E04\u0E23\u0E39\u0E48`);if(await t.sleep(ar),n=await e.app(n.slug),Gt(n))return n}}function Gt(t){return t.status==="ready"&&t.repo!==null}function fr(t,e){return`${t.config.repoBase}/${e}.git`}async function mr(t){let e=await Kt.readdir(t).catch(()=>null);if(e!==null&&e.length>0)throw new s(`\u0E42\u0E1F\u0E25\u0E40\u0E14\u0E2D\u0E23\u0E4C ${b.basename(t)}/ \u0E21\u0E35\u0E44\u0E1F\u0E25\u0E4C\u0E2D\u0E22\u0E39\u0E48\u0E41\u0E25\u0E49\u0E27`,"\u0E23\u0E31\u0E19 `pple init` \u0E17\u0E35\u0E48\u0E2D\u0E37\u0E48\u0E19 \u0E2B\u0E23\u0E37\u0E2D\u0E43\u0E2A\u0E48 `--dir <folder>` \u0E40\u0E1E\u0E37\u0E48\u0E2D\u0E40\u0E25\u0E37\u0E2D\u0E01\u0E42\u0E1F\u0E25\u0E40\u0E14\u0E2D\u0E23\u0E4C\u0E2D\u0E37\u0E48\u0E19")}async function gr(t){return Kt.access(b.join(t,"package.json")).then(()=>!0).catch(()=>!1)}function dr(t,e,r,n){let i=b.basename(r);t.out.say(),t.out.say(`"${e.name}" \u0E1E\u0E23\u0E49\u0E2D\u0E21\u0E43\u0E2B\u0E49\u0E17\u0E33\u0E07\u0E32\u0E19\u0E41\u0E25\u0E49\u0E27\u0E43\u0E19 ${i}/`),t.out.say(`\u0E41\u0E2D\u0E1B\u0E08\u0E30\u0E43\u0E0A\u0E49\u0E07\u0E32\u0E19\u0E44\u0E14\u0E49\u0E17\u0E35\u0E48 ${e.url}`),t.out.say(),t.out.say("\u0E02\u0E31\u0E49\u0E19\u0E15\u0E48\u0E2D\u0E44\u0E1B:"),t.out.say(` cd ${i}`),n||(t.out.say(" npm install"),t.out.say(" npm run db:migrate:local")),t.out.say(" npm run dev # \u0E14\u0E39\u0E1C\u0E25\u0E1A\u0E19\u0E40\u0E04\u0E23\u0E37\u0E48\u0E2D\u0E07\u0E19\u0E35\u0E49"),t.out.say(" pple deploy # \u0E19\u0E33\u0E02\u0E36\u0E49\u0E19\u0E43\u0E0A\u0E49\u0E07\u0E32\u0E19\u0E08\u0E23\u0E34\u0E07")}import W from"node:fs/promises";import X from"node:path";var yr=1440*60*1e3,Vt="update-check.json",wr="config.json",hr=new Set(["upgrade","help","--help","-h"]);function Jt(t){return t.length>0&&!hr.has(t[0])}function z(t,e){t.out.say(`\u0E21\u0E35 pple \u0E40\u0E27\u0E2D\u0E23\u0E4C\u0E0A\u0E31\u0E19\u0E43\u0E2B\u0E21\u0E48 (${e}) \u0E04\u0E38\u0E13\u0E43\u0E0A\u0E49\u0E40\u0E27\u0E2D\u0E23\u0E4C\u0E0A\u0E31\u0E19 ${t.version}`)}function Z(t){t.out.say("pple \u0E0A\u0E38\u0E14\u0E19\u0E35\u0E49\u0E44\u0E21\u0E48\u0E44\u0E14\u0E49\u0E15\u0E34\u0E14\u0E15\u0E31\u0E49\u0E07\u0E1C\u0E48\u0E32\u0E19 npm \u0E01\u0E32\u0E23\u0E2D\u0E31\u0E1B\u0E40\u0E14\u0E15\u0E17\u0E35\u0E48\u0E19\u0E35\u0E48\u0E2D\u0E32\u0E08\u0E17\u0E33\u0E43\u0E2B\u0E49\u0E04\u0E38\u0E13"),t.out.say("\u0E21\u0E35 pple \u0E2A\u0E2D\u0E07\u0E40\u0E27\u0E2D\u0E23\u0E4C\u0E0A\u0E31\u0E19 \u0E01\u0E23\u0E38\u0E13\u0E32\u0E2D\u0E31\u0E1B\u0E40\u0E14\u0E15\u0E14\u0E49\u0E27\u0E22\u0E27\u0E34\u0E18\u0E35\u0E40\u0E14\u0E34\u0E21\u0E17\u0E35\u0E48\u0E04\u0E38\u0E13\u0E15\u0E34\u0E14\u0E15\u0E31\u0E49\u0E07\u0E44\u0E27\u0E49"),t.out.say(`\u0E2B\u0E23\u0E37\u0E2D\u0E15\u0E34\u0E14\u0E15\u0E31\u0E49\u0E07\u0E14\u0E49\u0E27\u0E22 npm:
|
|
16
|
+
|
|
17
|
+
${m}`)}function Q(t){return`${_t(t)}
|
|
18
|
+
|
|
19
|
+
\u0E25\u0E2D\u0E07\u0E23\u0E31\u0E19\u0E04\u0E33\u0E2A\u0E31\u0E48\u0E07\u0E19\u0E35\u0E49\u0E14\u0E49\u0E27\u0E22\u0E15\u0E31\u0E27\u0E40\u0E2D\u0E07:
|
|
20
|
+
|
|
21
|
+
${m}`}async function Yt(t,e){if(!await Pr(t))return null;await $r(t);let r=await N(t);if(r===null||!B(r,t.version))return null;if(z(t,r),!await O(t))return Z(t),t.out.say(),null;if(!t.interactive)return t.out.say("\u0E23\u0E31\u0E19 `pple upgrade` \u0E40\u0E21\u0E37\u0E48\u0E2D\u0E04\u0E38\u0E13\u0E1E\u0E23\u0E49\u0E2D\u0E21"),t.out.say(),null;if(!await t.confirm("\u0E2D\u0E31\u0E1B\u0E40\u0E14\u0E15 pple \u0E15\u0E2D\u0E19\u0E19\u0E35\u0E49\u0E40\u0E25\u0E22\u0E44\u0E2B\u0E21?"))return t.out.say(),null;let n=await j(t,r);return n.code!==0?await vr(t,r,n):(t.out.say(`pple \u0E40\u0E1B\u0E47\u0E19\u0E40\u0E27\u0E2D\u0E23\u0E4C\u0E0A\u0E31\u0E19 ${r} \u0E41\u0E25\u0E49\u0E27 \u0E01\u0E33\u0E25\u0E31\u0E07\u0E17\u0E33\u0E07\u0E32\u0E19\u0E15\u0E48\u0E2D\u0E08\u0E32\u0E01\u0E17\u0E35\u0E48\u0E04\u0E49\u0E32\u0E07\u0E44\u0E27\u0E49\u2026`),t.out.say(),t.reexec(e))}async function vr(t,e,r){return t.out.say(`\u0E2D\u0E31\u0E1B\u0E40\u0E14\u0E15 pple \u0E40\u0E1B\u0E47\u0E19 ${e} \u0E44\u0E21\u0E48\u0E2A\u0E33\u0E40\u0E23\u0E47\u0E08`),t.out.say(Q(r)),t.out.say(),await t.confirm(`\u0E43\u0E0A\u0E49 pple ${t.version} \u0E17\u0E33\u0E07\u0E32\u0E19\u0E15\u0E48\u0E2D\u0E44\u0E1B\u0E01\u0E48\u0E2D\u0E19\u0E44\u0E2B\u0E21?`)?(t.out.say(),null):(t.out.say("\u0E2B\u0E22\u0E38\u0E14\u0E41\u0E25\u0E49\u0E27 \u0E44\u0E21\u0E48\u0E21\u0E35\u0E2D\u0E30\u0E44\u0E23\u0E40\u0E1B\u0E25\u0E35\u0E48\u0E22\u0E19\u0E41\u0E1B\u0E25\u0E07"),1)}async function Pr(t){if(!t.updateChecks||!await Er(t))return!1;let e=await Wt(X.join(t.configDir,Vt));return typeof e?.lastCheckedAt!="number"?!0:t.now()-e.lastCheckedAt>=yr}async function $r(t){let e={lastCheckedAt:t.now()};await W.mkdir(t.configDir,{recursive:!0}).then(()=>W.writeFile(X.join(t.configDir,Vt),`${JSON.stringify(e,null,2)}
|
|
22
|
+
`)).catch(()=>{})}async function Er(t){return(await Wt(X.join(t.configDir,wr)))?.updateCheck!==!1}async function Wt(t){let e=await W.readFile(t,"utf8").catch(()=>null);if(e===null)return null;try{return JSON.parse(e)}catch{return null}}async function Xt(t){let e=await N(t);if(e===null)throw new s("\u0E40\u0E0A\u0E37\u0E48\u0E2D\u0E21\u0E15\u0E48\u0E2D npm \u0E40\u0E1E\u0E37\u0E48\u0E2D\u0E15\u0E23\u0E27\u0E08\u0E2B\u0E32\u0E40\u0E27\u0E2D\u0E23\u0E4C\u0E0A\u0E31\u0E19\u0E43\u0E2B\u0E21\u0E48\u0E02\u0E2D\u0E07 pple \u0E44\u0E21\u0E48\u0E44\u0E14\u0E49",`\u0E15\u0E23\u0E27\u0E08\u0E2A\u0E2D\u0E1A\u0E01\u0E32\u0E23\u0E40\u0E0A\u0E37\u0E48\u0E2D\u0E21\u0E15\u0E48\u0E2D\u0E2D\u0E34\u0E19\u0E40\u0E17\u0E2D\u0E23\u0E4C\u0E40\u0E19\u0E47\u0E15 \u0E2B\u0E23\u0E37\u0E2D\u0E2D\u0E31\u0E1B\u0E40\u0E01\u0E23\u0E14\u0E42\u0E14\u0E22\u0E15\u0E23\u0E07:
|
|
23
|
+
|
|
24
|
+
${m}`);if(!B(e,t.version)){t.out.say(`\u0E04\u0E38\u0E13\u0E43\u0E0A\u0E49 pple \u0E40\u0E27\u0E2D\u0E23\u0E4C\u0E0A\u0E31\u0E19\u0E25\u0E48\u0E32\u0E2A\u0E38\u0E14\u0E2D\u0E22\u0E39\u0E48\u0E41\u0E25\u0E49\u0E27 (${t.version})`);return}if(!await O(t)){z(t,e),t.out.say(),Z(t);return}t.out.say(`\u0E01\u0E33\u0E25\u0E31\u0E07\u0E2D\u0E31\u0E1B\u0E40\u0E14\u0E15 pple ${t.version} \u2192 ${e}\u2026`);let r=await j(t,e);if(r.code!==0)throw new s(`\u0E2D\u0E31\u0E1B\u0E40\u0E14\u0E15 pple \u0E40\u0E1B\u0E47\u0E19 ${e} \u0E44\u0E21\u0E48\u0E2A\u0E33\u0E40\u0E23\u0E47\u0E08`,Q(r));t.out.say(`pple \u0E40\u0E1B\u0E47\u0E19\u0E40\u0E27\u0E2D\u0E23\u0E4C\u0E0A\u0E31\u0E19 ${e} \u0E41\u0E25\u0E49\u0E27`)}var zt=`pple \u2014 \u0E2A\u0E23\u0E49\u0E32\u0E07\u0E41\u0E25\u0E30\u0E2A\u0E48\u0E07\u0E41\u0E2D\u0E1B\u0E02\u0E36\u0E49\u0E19 PPLE Platform
|
|
25
|
+
|
|
26
|
+
pple auth login \u0E40\u0E02\u0E49\u0E32\u0E2A\u0E39\u0E48\u0E23\u0E30\u0E1A\u0E1A\u0E14\u0E49\u0E27\u0E22 PPLE ID \u0E02\u0E2D\u0E07\u0E04\u0E38\u0E13
|
|
27
|
+
pple auth logout \u0E25\u0E1A\u0E01\u0E32\u0E23\u0E40\u0E02\u0E49\u0E32\u0E2A\u0E39\u0E48\u0E23\u0E30\u0E1A\u0E1A\u0E2D\u0E2D\u0E01\u0E08\u0E32\u0E01\u0E40\u0E04\u0E23\u0E37\u0E48\u0E2D\u0E07\u0E19\u0E35\u0E49
|
|
28
|
+
pple whoami \u0E14\u0E39\u0E27\u0E48\u0E32\u0E01\u0E33\u0E25\u0E31\u0E07\u0E40\u0E02\u0E49\u0E32\u0E2A\u0E39\u0E48\u0E23\u0E30\u0E1A\u0E1A\u0E14\u0E49\u0E27\u0E22\u0E1A\u0E31\u0E0D\u0E0A\u0E35\u0E43\u0E14
|
|
29
|
+
|
|
30
|
+
pple init \u0E2A\u0E23\u0E49\u0E32\u0E07\u0E41\u0E2D\u0E1B\u0E41\u0E25\u0E30\u0E15\u0E31\u0E49\u0E07\u0E04\u0E48\u0E32\u0E42\u0E04\u0E49\u0E14\u0E1A\u0E19\u0E40\u0E04\u0E23\u0E37\u0E48\u0E2D\u0E07\u0E19\u0E35\u0E49
|
|
31
|
+
pple init --name "App" \u0E2A\u0E23\u0E49\u0E32\u0E07\u0E41\u0E2D\u0E1B\u0E42\u0E14\u0E22\u0E44\u0E21\u0E48\u0E15\u0E49\u0E2D\u0E07\u0E16\u0E32\u0E21 (\u0E2A\u0E33\u0E2B\u0E23\u0E31\u0E1A agent/\u0E2A\u0E04\u0E23\u0E34\u0E1B\u0E15\u0E4C)
|
|
32
|
+
pple init <app> \u0E15\u0E31\u0E49\u0E07\u0E04\u0E48\u0E32\u0E41\u0E2D\u0E1B\u0E17\u0E35\u0E48\u0E21\u0E35\u0E2D\u0E22\u0E39\u0E48\u0E41\u0E25\u0E49\u0E27\u0E1A\u0E19\u0E41\u0E1E\u0E25\u0E15\u0E1F\u0E2D\u0E23\u0E4C\u0E21
|
|
33
|
+
pple deploy [-m "note"] \u0E2A\u0E48\u0E07\u0E01\u0E32\u0E23\u0E40\u0E1B\u0E25\u0E35\u0E48\u0E22\u0E19\u0E41\u0E1B\u0E25\u0E07\u0E02\u0E2D\u0E07\u0E04\u0E38\u0E13\u0E02\u0E36\u0E49\u0E19\u0E43\u0E0A\u0E49\u0E07\u0E32\u0E19\u0E08\u0E23\u0E34\u0E07
|
|
34
|
+
pple info [<slug>] \u0E14\u0E39\u0E2A\u0E16\u0E32\u0E19\u0E30 \u0E01\u0E32\u0E23\u0E43\u0E0A\u0E49\u0E07\u0E32\u0E19 \u0E01\u0E32\u0E23\u0E14\u0E35\u0E1E\u0E25\u0E2D\u0E22 \u0E41\u0E25\u0E30\u0E04\u0E35\u0E22\u0E4C env \u0E02\u0E2D\u0E07\u0E41\u0E2D\u0E1B\u0E19\u0E35\u0E49
|
|
35
|
+
|
|
36
|
+
pple env list \u0E14\u0E39\u0E15\u0E31\u0E27\u0E41\u0E1B\u0E23\u0E41\u0E25\u0E30 secret \u0E02\u0E2D\u0E07\u0E41\u0E2D\u0E1B\u0E19\u0E35\u0E49
|
|
37
|
+
pple env set <KEY> [VAL] \u0E15\u0E31\u0E49\u0E07\u0E04\u0E48\u0E32\u0E15\u0E31\u0E27\u0E41\u0E1B\u0E23 (\u0E2B\u0E23\u0E37\u0E2D --secret) \u0E23\u0E31\u0E1A\u0E04\u0E48\u0E32\u0E08\u0E32\u0E01 arg, --file \u0E2B\u0E23\u0E37\u0E2D stdin
|
|
38
|
+
pple env delete <KEY> \u0E25\u0E1A\u0E15\u0E31\u0E27\u0E41\u0E1B\u0E23\u0E2B\u0E23\u0E37\u0E2D secret
|
|
39
|
+
|
|
40
|
+
pple upgrade \u0E2D\u0E31\u0E1B\u0E40\u0E14\u0E15 pple \u0E40\u0E1B\u0E47\u0E19\u0E40\u0E27\u0E2D\u0E23\u0E4C\u0E0A\u0E31\u0E19\u0E25\u0E48\u0E32\u0E2A\u0E38\u0E14
|
|
41
|
+
|
|
42
|
+
\u0E15\u0E31\u0E27\u0E40\u0E25\u0E37\u0E2D\u0E01
|
|
43
|
+
-m, --message <note> \u0E2A\u0E34\u0E48\u0E07\u0E17\u0E35\u0E48\u0E40\u0E1B\u0E25\u0E35\u0E48\u0E22\u0E19\u0E41\u0E1B\u0E25\u0E07 \u0E41\u0E2A\u0E14\u0E07\u0E43\u0E19\u0E1B\u0E23\u0E30\u0E27\u0E31\u0E15\u0E34\u0E02\u0E2D\u0E07\u0E41\u0E2D\u0E1B
|
|
44
|
+
--name <App Name> \u0E2A\u0E23\u0E49\u0E32\u0E07\u0E41\u0E2D\u0E1B\u0E43\u0E2B\u0E21\u0E48\u0E14\u0E49\u0E27\u0E22\u0E0A\u0E37\u0E48\u0E2D\u0E19\u0E35\u0E49 (pple init)
|
|
45
|
+
--dir <folder> \u0E15\u0E33\u0E41\u0E2B\u0E19\u0E48\u0E07\u0E17\u0E35\u0E48\u0E08\u0E30\u0E27\u0E32\u0E07\u0E42\u0E04\u0E49\u0E14\u0E02\u0E2D\u0E07\u0E41\u0E2D\u0E1B (pple init)
|
|
46
|
+
--file <path> \u0E2D\u0E48\u0E32\u0E19\u0E04\u0E48\u0E32 env \u0E08\u0E32\u0E01\u0E44\u0E1F\u0E25\u0E4C (pple env set)
|
|
47
|
+
--secret \u0E40\u0E01\u0E47\u0E1A\u0E04\u0E48\u0E32\u0E40\u0E1B\u0E47\u0E19 secret \u0E41\u0E1A\u0E1A\u0E40\u0E02\u0E35\u0E22\u0E19\u0E2D\u0E22\u0E48\u0E32\u0E07\u0E40\u0E14\u0E35\u0E22\u0E27 (pple env set)
|
|
48
|
+
-h, --help \u0E41\u0E2A\u0E14\u0E07\u0E27\u0E34\u0E18\u0E35\u0E43\u0E0A\u0E49\u0E19\u0E35\u0E49
|
|
49
|
+
`;async function Zt(t,e){try{if(Jt(t)){let r=await Yt(e,t);if(r!==null)return r}return await Dr(t,e),0}catch(r){if(r instanceof s)return e.out.fail(r),1;throw r}}async function Dr(t,e){let r=[...t];if(r.length===0||r[0]==="--help"||r[0]==="-h"){e.out.say(zt);return}let n=r.shift();switch(n){case"auth":{let i=r.shift();if(i==="login")return ft(e);if(i==="logout")return mt(e);if(i==="whoami")return G(e);throw tt(`auth ${i??""}`.trim())}case"whoami":return G(e);case"init":{let i=M(r,"--dir"),o=M(r,"--name"),u=r.shift();if(o!==void 0&&u)throw new s("`pple init` \u0E23\u0E31\u0E1A\u0E44\u0E14\u0E49\u0E40\u0E09\u0E1E\u0E32\u0E30\u0E0A\u0E37\u0E48\u0E2D\u0E41\u0E2D\u0E1B\u0E43\u0E2B\u0E21\u0E48 \u0E2B\u0E23\u0E37\u0E2D\u0E41\u0E2D\u0E1B\u0E17\u0E35\u0E48\u0E21\u0E35\u0E2D\u0E22\u0E39\u0E48\u0E41\u0E25\u0E49\u0E27 \u0E2D\u0E22\u0E48\u0E32\u0E07\u0E43\u0E14\u0E2D\u0E22\u0E48\u0E32\u0E07\u0E2B\u0E19\u0E36\u0E48\u0E07\u0E40\u0E17\u0E48\u0E32\u0E19\u0E31\u0E49\u0E19",'\u0E43\u0E0A\u0E49 `pple init --name "\u0E0A\u0E37\u0E48\u0E2D\u0E41\u0E2D\u0E1B\u0E02\u0E2D\u0E07\u0E04\u0E38\u0E13"` \u0E40\u0E1E\u0E37\u0E48\u0E2D\u0E2A\u0E23\u0E49\u0E32\u0E07\u0E43\u0E2B\u0E21\u0E48 \u0E2B\u0E23\u0E37\u0E2D `pple init <app>` \u0E2A\u0E33\u0E2B\u0E23\u0E31\u0E1A\u0E41\u0E2D\u0E1B\u0E17\u0E35\u0E48\u0E21\u0E35\u0E2D\u0E22\u0E39\u0E48\u0E41\u0E25\u0E49\u0E27');return Ht(e,{slug:u,name:o,dir:i})}case"deploy":{let i=M(r,"--message","-m");return Rt(e,{message:i})}case"info":{let i=r.shift();return Bt(e,i)}case"env":{let i=r.shift();if(i==="list")return It(e);if(i==="set"){let o=kr(r,"--secret"),u=M(r,"--file"),a=r.shift(),c=r.shift();if(!a)throw new s("`pple env set` \u0E15\u0E49\u0E2D\u0E07\u0E23\u0E30\u0E1A\u0E38 KEY","\u0E15\u0E31\u0E27\u0E2D\u0E22\u0E48\u0E32\u0E07: `pple env set API_URL https://example.com`");return Lt(e,{key:a,value:c,secret:o,file:u})}if(i==="delete"){let o=r.shift();if(!o)throw new s("`pple env delete` \u0E15\u0E49\u0E2D\u0E07\u0E23\u0E30\u0E1A\u0E38 KEY","\u0E15\u0E31\u0E27\u0E2D\u0E22\u0E48\u0E32\u0E07: `pple env delete API_URL`");return Nt(e,o)}throw tt(`env ${i??""}`.trim())}case"upgrade":return Xt(e);case"help":e.out.say(zt);return;default:throw tt(n??"")}}function tt(t){return new s(`\u0E44\u0E21\u0E48\u0E21\u0E35\u0E04\u0E33\u0E2A\u0E31\u0E48\u0E07 \`pple ${t}\``,"\u0E23\u0E31\u0E19 `pple --help` \u0E40\u0E1E\u0E37\u0E48\u0E2D\u0E14\u0E39\u0E04\u0E33\u0E2A\u0E31\u0E48\u0E07\u0E17\u0E31\u0E49\u0E07\u0E2B\u0E21\u0E14")}function M(t,e,r){let n=t.findIndex(o=>o===e||r&&o===r);if(n===-1)return;let[,i]=t.splice(n,2);if(i===void 0||i.startsWith("-"))throw new s(`\`${e}\` \u0E15\u0E49\u0E2D\u0E07\u0E23\u0E30\u0E1A\u0E38\u0E04\u0E48\u0E32\u0E15\u0E32\u0E21\u0E2B\u0E25\u0E31\u0E07`);return i}function kr(t,e){let r=t.indexOf(e);return r===-1?!1:(t.splice(r,1),!0)}import{spawn as ae}from"node:child_process";import ue from"node:readline/promises";import{existsSync as Qt,readFileSync as Ar}from"node:fs";import f from"node:path";import{fileURLToPath as _r}from"node:url";var C={apiBase:"https://api.ppleth.ai",ssoBase:"https://id.peoplesparty.or.th",clientId:"382216793067947795",repoBase:"https://github.com",registryBase:"https://registry.npmjs.org"};function te(t){return{apiBase:t.PPLE_API_BASE??C.apiBase,ssoBase:t.PPLE_SSO_BASE??C.ssoBase,clientId:t.PPLE_CLIENT_ID??C.clientId,repoBase:t.PPLE_REPO_BASE??C.repoBase,registryBase:t.PPLE_REGISTRY_BASE??C.registryBase}}function ee(t,e){let r=t.XDG_CONFIG_HOME?.trim();return f.join(r&&r!==""?r:f.join(e,".config"),"pple")}function re(t){let e=t.PPLE_NO_UPDATE_CHECK?.trim().toLowerCase();return!e||e==="0"||e==="false"}function h(){return f.dirname(f.dirname(_r(import.meta.url)))}function ne(){try{let t=Ar(f.join(h(),"package.json"),"utf8");return String(JSON.parse(t).version??"0.0.0")}catch{return"0.0.0"}}function ie(t){let e=t.PPLE_TEMPLATE_DIR?.trim();if(e)return e;let r=f.join(h(),"templates","golden-path");return Qt(r)?r:f.join(f.dirname(h()),"template")}function oe(t){let e=t.PPLE_SKILLS_DIR?.trim();if(e)return e;let r=f.join(h(),"skills","pple-platform");return Qt(r)?r:f.join(f.dirname(h()),"skills","pple-platform")}function se(){return f.join(h(),"askpass","pple-askpass.mjs")}function le(t,e,r){return new Promise((n,i)=>{let o=ae(t,e,{cwd:r.cwd,env:{...process.env,...r.env},stdio:["ignore","pipe","pipe"]}),u="",a="";o.stdout.on("data",c=>u+=String(c)),o.stderr.on("data",c=>a+=String(c)),o.on("error",i),o.on("close",c=>n({code:c??0,stdout:u,stderr:a}))})}async function br(t){let e=process.platform==="darwin"?"open":process.platform==="win32"?"start":"xdg-open";await le(e,[t],{cwd:process.cwd()}).catch(()=>{})}async function Cr(t){let e=ue.createInterface({input:process.stdin,output:process.stdout});try{let r=await e.question(`${t} [y/N] `);return/^y(es)?$/i.test(r.trim())}finally{e.close()}}async function xr(t){let e=ue.createInterface({input:process.stdin,output:process.stdout});try{return await e.question(`${t} `)}finally{e.close()}}async function Tr(){let t=[];for await(let e of process.stdin)t.push(typeof e=="string"?Buffer.from(e):e);return Buffer.concat(t).toString("utf8")}function Sr(t){return new Promise((e,r)=>{let n=ae(process.execPath,[process.argv[1],...t],{stdio:"inherit"});n.on("error",r),n.on("close",i=>e(i??0))})}function ce(t,e){return{fetch:globalThis.fetch.bind(globalThis),now:()=>Date.now(),sleep:r=>new Promise(n=>setTimeout(n,r)),cwd:process.cwd(),configDir:ee(process.env,e),out:t,openBrowser:br,run:le,templateDir:ie(process.env),skillsDir:oe(process.env),packageDir:h(),version:ne(),interactive:process.stdin.isTTY===!0&&process.stdout.isTTY===!0,confirm:Cr,ask:xr,readStdin:Tr,reexec:Sr,updateChecks:re(process.env),gitAskpass:se(),config:te(process.env)}}function pe(t,e){return{say(r=""){t(`${r}
|
|
50
|
+
`)},fail(r){e(`${r.message}
|
|
51
|
+
`),r.hint&&e(`${r.hint}
|
|
52
|
+
`)}}}var Ir=pe(t=>process.stdout.write(t),t=>process.stderr.write(t));try{process.exitCode=await Zt(process.argv.slice(2),ce(Ir,Rr.homedir()))}catch(t){process.stderr.write(`\u0E40\u0E01\u0E34\u0E14\u0E02\u0E49\u0E2D\u0E1C\u0E34\u0E14\u0E1E\u0E25\u0E32\u0E14\u0E20\u0E32\u0E22\u0E43\u0E19 pple CLI \u0E01\u0E23\u0E38\u0E13\u0E32\u0E2A\u0E48\u0E07\u0E02\u0E49\u0E2D\u0E04\u0E27\u0E32\u0E21\u0E19\u0E35\u0E49\u0E43\u0E2B\u0E49\u0E17\u0E35\u0E21\u0E41\u0E1E\u0E25\u0E15\u0E1F\u0E2D\u0E23\u0E4C\u0E21:
|
|
53
|
+
`),process.stderr.write(`${t instanceof Error?t.stack??t.message:String(t)}
|
|
54
|
+
`),process.exitCode=1}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pplethai/cli",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.2",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
"templates"
|
|
18
18
|
],
|
|
19
19
|
"scripts": {
|
|
20
|
-
"build": "npm run build:template && npm run build:skills &&
|
|
20
|
+
"build": "npm run build:template && npm run build:skills && node scripts/bundle.mjs",
|
|
21
21
|
"build:template": "node scripts/bundle-template.mjs",
|
|
22
22
|
"build:skills": "node scripts/bundle-skills.mjs",
|
|
23
23
|
"typecheck": "tsc --noEmit",
|
|
@@ -26,6 +26,7 @@
|
|
|
26
26
|
},
|
|
27
27
|
"devDependencies": {
|
|
28
28
|
"@types/node": "^22.10.0",
|
|
29
|
+
"esbuild": "^0.28.1",
|
|
29
30
|
"typescript": "^5.8.0",
|
|
30
31
|
"vitest": "^4.1.10"
|
|
31
32
|
},
|
|
@@ -14,14 +14,14 @@ reinventing a design-system setup from `pple-erp` or other older apps.
|
|
|
14
14
|
import "@pplethai/components/styles.css";
|
|
15
15
|
import "./app.css";
|
|
16
16
|
|
|
17
|
-
import { Button, Card, CardContent,
|
|
17
|
+
import { Button, Card, CardContent, Navbar } from "@pplethai/components";
|
|
18
18
|
```
|
|
19
19
|
|
|
20
20
|
Package entry points:
|
|
21
21
|
|
|
22
22
|
| Import | Contents |
|
|
23
23
|
| ------ | -------- |
|
|
24
|
-
| `@pplethai/components` | UI primitives, layout, brand (`Logo`, …), `cn()`, toasts |
|
|
24
|
+
| `@pplethai/components` | UI primitives, layout, brand (`Navbar`, `Logo`, …), `cn()`, toasts |
|
|
25
25
|
| `@pplethai/components/form` | react-hook-form helpers when you need forms |
|
|
26
26
|
| `@pplethai/components/styles.css` | Brand tokens — import once |
|
|
27
27
|
|
|
@@ -34,6 +34,11 @@ the bare `@pplethai/components` import to `dist/index.js`.
|
|
|
34
34
|
- Put **page layout** in `web/app.css` (mobile-first, safe-area padding for
|
|
35
35
|
the WebView). Do not fight the design-system stylesheet with a second
|
|
36
36
|
full Tailwind stack unless you need it.
|
|
37
|
+
- Top-level chrome uses Shared `<Navbar>` (see `web/App.tsx`). Do not hand-roll
|
|
38
|
+
a header/app bar with `Logo`. With a client router, pass `renderHomeLink` /
|
|
39
|
+
`renderLink` (as in pple-erp); otherwise default `<a href>` links are fine.
|
|
40
|
+
Navbar is `position: fixed` below the `md` breakpoint — pad the page content
|
|
41
|
+
accordingly (the template's `.screen` already does).
|
|
37
42
|
- Compose screens from design-system components (`Card`, `Button`, `Input`,
|
|
38
43
|
`Textarea`, `Badge`, `Alert`, …) like the demo cards in `web/App.tsx`.
|
|
39
44
|
- **Colors and type** come from CSS variables in `styles.css`
|
|
@@ -1,20 +1,27 @@
|
|
|
1
1
|
import {
|
|
2
|
-
Badge,
|
|
3
2
|
Button,
|
|
4
3
|
Card,
|
|
5
4
|
CardContent,
|
|
6
5
|
CardDescription,
|
|
7
6
|
CardHeader,
|
|
8
7
|
CardTitle,
|
|
8
|
+
DropdownMenu,
|
|
9
|
+
DropdownMenuContent,
|
|
10
|
+
DropdownMenuItem,
|
|
11
|
+
DropdownMenuLabel,
|
|
12
|
+
DropdownMenuSeparator,
|
|
13
|
+
DropdownMenuTrigger,
|
|
14
|
+
Icon,
|
|
9
15
|
Input,
|
|
10
|
-
|
|
16
|
+
Navbar,
|
|
11
17
|
Spinner,
|
|
12
18
|
Textarea,
|
|
13
19
|
showToast,
|
|
14
20
|
} from "@pplethai/components";
|
|
21
|
+
import { ChevronDown, LogOut, Plus, Send, Upload, User } from "lucide-react";
|
|
15
22
|
import { useEffect, useRef, useState } from "react";
|
|
16
23
|
import type { Me, Note, UploadedFile } from "../shared/api";
|
|
17
|
-
import { api, apiJson } from "./pple";
|
|
24
|
+
import { api, apiJson, logout } from "./pple";
|
|
18
25
|
|
|
19
26
|
function bytes(n: number): string {
|
|
20
27
|
if (n < 1024) return `${n} B`;
|
|
@@ -26,35 +33,89 @@ function message(e: unknown): string {
|
|
|
26
33
|
return e instanceof Error ? e.message : String(e);
|
|
27
34
|
}
|
|
28
35
|
|
|
36
|
+
// Starter nav — replace with your routes. With a client router, pass
|
|
37
|
+
// renderHomeLink / renderLink (see pple-erp's Navbar wrapper).
|
|
38
|
+
const NAV_ITEMS = [{ href: "/", label: "หน้าหลัก", end: true }];
|
|
39
|
+
|
|
29
40
|
export function App() {
|
|
30
41
|
const [me, setMe] = useState<Me | null>(null);
|
|
31
42
|
|
|
32
43
|
useEffect(() => {
|
|
33
44
|
apiJson<Me>("/api/me").then(setMe).catch((e) => showToast({
|
|
34
|
-
title: "
|
|
45
|
+
title: "โหลดโปรไฟล์ไม่สำเร็จ",
|
|
35
46
|
description: message(e),
|
|
36
47
|
variant: "error",
|
|
37
48
|
}));
|
|
38
49
|
}, []);
|
|
39
50
|
|
|
51
|
+
const displayName = me?.actor.name ?? me?.actor.sub ?? "";
|
|
52
|
+
const roleLabels = me
|
|
53
|
+
? [me.effective.activeRole, ...me.effective.extraRoles]
|
|
54
|
+
: [];
|
|
55
|
+
|
|
40
56
|
return (
|
|
41
|
-
|
|
42
|
-
<
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
{
|
|
46
|
-
|
|
57
|
+
<>
|
|
58
|
+
<Navbar
|
|
59
|
+
title="PPLE App"
|
|
60
|
+
pathname={window.location.pathname}
|
|
61
|
+
items={NAV_ITEMS}
|
|
62
|
+
mobileMenuAriaLabel={{ open: "เปิดเมนู", close: "ปิดเมนู" }}
|
|
63
|
+
navAriaLabel="เมนูหลัก"
|
|
64
|
+
>
|
|
65
|
+
{me && (
|
|
66
|
+
<DropdownMenu>
|
|
67
|
+
<DropdownMenuTrigger asChild>
|
|
68
|
+
<Button variant="outline" size="default" className="gap-2">
|
|
69
|
+
<Icon icon={User} />
|
|
70
|
+
<span>{displayName}</span>
|
|
71
|
+
<Icon icon={ChevronDown} size="sm" />
|
|
72
|
+
</Button>
|
|
73
|
+
</DropdownMenuTrigger>
|
|
74
|
+
<DropdownMenuContent align="end" className="w-64">
|
|
75
|
+
<DropdownMenuLabel>
|
|
76
|
+
<div className="font-medium">{displayName}</div>
|
|
77
|
+
{me.actor.mobile && (
|
|
78
|
+
<div className="text-xs text-muted-foreground font-normal">
|
|
79
|
+
{me.actor.mobile}
|
|
80
|
+
</div>
|
|
81
|
+
)}
|
|
82
|
+
{me.effective.isDelegated && (
|
|
83
|
+
<div className="text-xs text-muted-foreground font-normal">
|
|
84
|
+
(ปฏิบัติงานแทน — สิทธิ์เป็นของหัวหน้า)
|
|
85
|
+
</div>
|
|
86
|
+
)}
|
|
87
|
+
</DropdownMenuLabel>
|
|
88
|
+
<DropdownMenuSeparator />
|
|
89
|
+
<DropdownMenuLabel className="text-xs text-muted-foreground font-normal">
|
|
90
|
+
บทบาทของคุณ
|
|
91
|
+
</DropdownMenuLabel>
|
|
92
|
+
{roleLabels.map((label) => (
|
|
93
|
+
<DropdownMenuItem key={label} disabled className="opacity-70">
|
|
94
|
+
{label}
|
|
95
|
+
</DropdownMenuItem>
|
|
96
|
+
))}
|
|
97
|
+
<DropdownMenuSeparator />
|
|
98
|
+
<DropdownMenuItem onClick={() => void logout()}>
|
|
99
|
+
<Icon icon={LogOut} />
|
|
100
|
+
ออกจากระบบ
|
|
101
|
+
</DropdownMenuItem>
|
|
102
|
+
</DropdownMenuContent>
|
|
103
|
+
</DropdownMenu>
|
|
104
|
+
)}
|
|
105
|
+
</Navbar>
|
|
47
106
|
|
|
48
|
-
<
|
|
49
|
-
<
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
107
|
+
<main className="screen">
|
|
108
|
+
<div className="stack">
|
|
109
|
+
<p className="muted">
|
|
110
|
+
นี่คือเทมเพลตเริ่มต้น แต่ละการ์ดด้านล่างแสดงความสามารถหนึ่งอย่างของ
|
|
111
|
+
แพลตฟอร์ม แทนที่ด้วยแอปของคุณเองได้เลย
|
|
112
|
+
</p>
|
|
113
|
+
<NotesCard />
|
|
114
|
+
<FilesCard />
|
|
115
|
+
<NotifyCard />
|
|
116
|
+
</div>
|
|
117
|
+
</main>
|
|
118
|
+
</>
|
|
58
119
|
);
|
|
59
120
|
}
|
|
60
121
|
|
|
@@ -68,7 +129,7 @@ function NotesCard() {
|
|
|
68
129
|
apiJson<{ notes: Note[] }>("/api/notes")
|
|
69
130
|
.then((r) => setNotes(r.notes))
|
|
70
131
|
.catch((e) => {
|
|
71
|
-
showToast({ title: "
|
|
132
|
+
showToast({ title: "โหลดบันทึกไม่สำเร็จ", description: message(e), variant: "error" });
|
|
72
133
|
// Land on the empty state. Leaving this null would spin forever.
|
|
73
134
|
setNotes([]);
|
|
74
135
|
});
|
|
@@ -89,7 +150,7 @@ function NotesCard() {
|
|
|
89
150
|
setBody("");
|
|
90
151
|
await load();
|
|
91
152
|
} catch (e) {
|
|
92
|
-
showToast({ title: "
|
|
153
|
+
showToast({ title: "บันทึกไม่สำเร็จ", description: message(e), variant: "error" });
|
|
93
154
|
} finally {
|
|
94
155
|
setSaving(false);
|
|
95
156
|
}
|
|
@@ -98,32 +159,35 @@ function NotesCard() {
|
|
|
98
159
|
return (
|
|
99
160
|
<Card className="card">
|
|
100
161
|
<CardHeader>
|
|
101
|
-
<CardTitle
|
|
102
|
-
<CardDescription
|
|
162
|
+
<CardTitle>บันทึก</CardTitle>
|
|
163
|
+
<CardDescription>อ่านและเขียนฐานข้อมูล D1 ของแอป</CardDescription>
|
|
103
164
|
</CardHeader>
|
|
104
165
|
<CardContent>
|
|
105
166
|
<div className="stack">
|
|
106
167
|
<div className="row">
|
|
107
168
|
<Input
|
|
108
169
|
value={body}
|
|
109
|
-
placeholder="
|
|
170
|
+
placeholder="เขียนบันทึก…"
|
|
110
171
|
onChange={(e) => setBody(e.target.value)}
|
|
111
172
|
onKeyDown={(e) => e.key === "Enter" && add()}
|
|
112
173
|
/>
|
|
113
174
|
<Button onClick={add} disabled={saving || !body.trim()}>
|
|
114
|
-
{saving ? <Spinner /> :
|
|
175
|
+
{saving ? <Spinner /> : <Icon icon={Plus} />}
|
|
176
|
+
เพิ่ม
|
|
115
177
|
</Button>
|
|
116
178
|
</div>
|
|
117
179
|
{notes === null ? (
|
|
118
180
|
<Spinner />
|
|
119
181
|
) : notes.length === 0 ? (
|
|
120
|
-
<p className="muted"
|
|
182
|
+
<p className="muted">ยังไม่มีบันทึก</p>
|
|
121
183
|
) : (
|
|
122
184
|
<ul className="list">
|
|
123
185
|
{notes.map((n) => (
|
|
124
186
|
<li key={n.id} className="list__item">
|
|
125
187
|
<span>{n.body}</span>
|
|
126
|
-
<span className="muted">
|
|
188
|
+
<span className="muted">
|
|
189
|
+
{new Date(n.createdAt).toLocaleString("th-TH")}
|
|
190
|
+
</span>
|
|
127
191
|
</li>
|
|
128
192
|
))}
|
|
129
193
|
</ul>
|
|
@@ -144,7 +208,7 @@ function FilesCard() {
|
|
|
144
208
|
apiJson<{ files: UploadedFile[] }>("/api/files")
|
|
145
209
|
.then((r) => setFiles(r.files))
|
|
146
210
|
.catch((e) => {
|
|
147
|
-
showToast({ title: "
|
|
211
|
+
showToast({ title: "โหลดไฟล์ไม่สำเร็จ", description: message(e), variant: "error" });
|
|
148
212
|
// Land on the empty state. Leaving this null would spin forever.
|
|
149
213
|
setFiles([]);
|
|
150
214
|
});
|
|
@@ -159,11 +223,11 @@ function FilesCard() {
|
|
|
159
223
|
const fd = new FormData();
|
|
160
224
|
fd.append("file", file);
|
|
161
225
|
const res = await api("/api/files", { method: "POST", body: fd });
|
|
162
|
-
if (!res.ok) throw new Error(
|
|
226
|
+
if (!res.ok) throw new Error(`อัปโหลดไม่สำเร็จ (${res.status})`);
|
|
163
227
|
if (inputRef.current) inputRef.current.value = "";
|
|
164
228
|
await load();
|
|
165
229
|
} catch (e) {
|
|
166
|
-
showToast({ title: "
|
|
230
|
+
showToast({ title: "อัปโหลดไฟล์ไม่สำเร็จ", description: message(e), variant: "error" });
|
|
167
231
|
} finally {
|
|
168
232
|
setUploading(false);
|
|
169
233
|
}
|
|
@@ -172,27 +236,34 @@ function FilesCard() {
|
|
|
172
236
|
return (
|
|
173
237
|
<Card className="card">
|
|
174
238
|
<CardHeader>
|
|
175
|
-
<CardTitle
|
|
176
|
-
<CardDescription
|
|
239
|
+
<CardTitle>ไฟล์</CardTitle>
|
|
240
|
+
<CardDescription>อัปโหลดไปยังบัคเก็ต R2 ของแอป</CardDescription>
|
|
177
241
|
</CardHeader>
|
|
178
242
|
<CardContent>
|
|
179
243
|
<div className="stack">
|
|
180
244
|
<div className="row">
|
|
181
|
-
{/*
|
|
182
|
-
a concurrent upload. */}
|
|
245
|
+
{/* Hidden native picker; the design-system Button opens it. Disabled
|
|
246
|
+
while uploading so a second pick can't start a concurrent upload. */}
|
|
183
247
|
<input
|
|
184
248
|
ref={inputRef}
|
|
185
249
|
type="file"
|
|
186
|
-
className="
|
|
250
|
+
className="hidden"
|
|
187
251
|
onChange={upload}
|
|
188
252
|
disabled={uploading}
|
|
189
253
|
/>
|
|
190
|
-
|
|
254
|
+
<Button
|
|
255
|
+
variant="outline"
|
|
256
|
+
disabled={uploading}
|
|
257
|
+
onClick={() => inputRef.current?.click()}
|
|
258
|
+
>
|
|
259
|
+
{uploading ? <Spinner /> : <Icon icon={Upload} />}
|
|
260
|
+
เลือกไฟล์
|
|
261
|
+
</Button>
|
|
191
262
|
</div>
|
|
192
263
|
{files === null ? (
|
|
193
264
|
<Spinner />
|
|
194
265
|
) : files.length === 0 ? (
|
|
195
|
-
<p className="muted"
|
|
266
|
+
<p className="muted">ยังไม่มีไฟล์</p>
|
|
196
267
|
) : (
|
|
197
268
|
<ul className="list">
|
|
198
269
|
{files.map((f) => (
|
|
@@ -226,20 +297,20 @@ function NotifyCard() {
|
|
|
226
297
|
});
|
|
227
298
|
const data = (await res.json().catch(() => ({}))) as { error?: string };
|
|
228
299
|
if (res.ok) {
|
|
229
|
-
showToast({ title: "
|
|
300
|
+
showToast({ title: "ส่งการแจ้งเตือนแล้ว", variant: "success" });
|
|
230
301
|
setTitle("");
|
|
231
302
|
setBody("");
|
|
232
303
|
} else if (data.error === "notifications_not_configured") {
|
|
233
304
|
showToast({
|
|
234
|
-
title: "
|
|
235
|
-
description: "
|
|
305
|
+
title: "ยังไม่ได้ตั้งค่าการแจ้งเตือน",
|
|
306
|
+
description: "ตั้งค่า NOTIFY_API_BASE และ NOTIFY_API_KEY เพื่อส่งจริง",
|
|
236
307
|
variant: "warning",
|
|
237
308
|
});
|
|
238
309
|
} else {
|
|
239
|
-
showToast({ title: "
|
|
310
|
+
showToast({ title: "ส่งไม่สำเร็จ", description: data.error, variant: "error" });
|
|
240
311
|
}
|
|
241
312
|
} catch (e) {
|
|
242
|
-
showToast({ title: "
|
|
313
|
+
showToast({ title: "ส่งไม่สำเร็จ", description: message(e), variant: "error" });
|
|
243
314
|
} finally {
|
|
244
315
|
setSending(false);
|
|
245
316
|
}
|
|
@@ -248,18 +319,27 @@ function NotifyCard() {
|
|
|
248
319
|
return (
|
|
249
320
|
<Card className="card">
|
|
250
321
|
<CardHeader>
|
|
251
|
-
<CardTitle
|
|
322
|
+
<CardTitle>แจ้งเตือนผู้ใช้</CardTitle>
|
|
252
323
|
<CardDescription>
|
|
253
|
-
|
|
254
|
-
|
|
324
|
+
ส่งการแจ้งเตือนแบบผูกกับกลุ่มผู้ใช้แอป — ส่งเฉพาะเนื้อหา
|
|
325
|
+
ไม่ส่งหมายเลขโทรศัพท์
|
|
255
326
|
</CardDescription>
|
|
256
327
|
</CardHeader>
|
|
257
328
|
<CardContent>
|
|
258
329
|
<div className="stack">
|
|
259
|
-
<Input
|
|
260
|
-
|
|
330
|
+
<Input
|
|
331
|
+
value={title}
|
|
332
|
+
placeholder="หัวข้อ"
|
|
333
|
+
onChange={(e) => setTitle(e.target.value)}
|
|
334
|
+
/>
|
|
335
|
+
<Textarea
|
|
336
|
+
value={body}
|
|
337
|
+
placeholder="ข้อความ"
|
|
338
|
+
onChange={(e) => setBody(e.target.value)}
|
|
339
|
+
/>
|
|
261
340
|
<Button onClick={send} disabled={sending || !title.trim() || !body.trim()}>
|
|
262
|
-
{sending ? <Spinner /> :
|
|
341
|
+
{sending ? <Spinner /> : <Icon icon={Send} />}
|
|
342
|
+
ส่งการแจ้งเตือน
|
|
263
343
|
</Button>
|
|
264
344
|
</div>
|
|
265
345
|
</CardContent>
|