@giteeteam/apps-cli 0.8.18 → 1.0.0-alpha.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 CHANGED
@@ -24,3 +24,13 @@ $ giteeteam-apps login
24
24
  ```bash
25
25
  $ giteeteam-apps tunnel
26
26
  ```
27
+
28
+ ## 升级旧版 webpack 项目到 rspack
29
+ ```bash
30
+ $ giteeteam-apps upgrade-v1
31
+ ```
32
+
33
+ ## 同步最新 skill 到项目(同名覆盖)
34
+ ```bash
35
+ $ giteeteam-apps sync-skill
36
+ ```
package/dist/index.js CHANGED
@@ -1,7 +1,9 @@
1
1
  #!/usr/bin/env node
2
- "use strict";var no=Object.create;var W=Object.defineProperty;var io=Object.getOwnPropertyDescriptor;var so=Object.getOwnPropertyNames;var ao=Object.getPrototypeOf,po=Object.prototype.hasOwnProperty;var co=(e,t)=>()=>(e&&(t=e(e=0)),t);var mo=(e,t)=>{for(var o in t)W(e,o,{get:t[o],enumerable:!0})},lo=(e,t,o,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let n of so(t))!po.call(e,n)&&n!==o&&W(e,n,{get:()=>t[n],enumerable:!(r=io(t,n))||r.enumerable});return e};var s=(e,t,o)=>(o=e!=null?no(ao(e)):{},lo(t||!e||!e.__esModule?W(o,"default",{value:e,enumerable:!0}):o,e));var Ge={};mo(Ge,{default:()=>ko});function ko({environment:e,appKey:t,distOutputPath:o="dist"}){let r=e==="production",n=e==="development",i=f=>f?{filename:"js/[name].[chunkhash].min.js",path:M.default.resolve(o),publicPath:"./",library:t,libraryTarget:"umd"}:{filename:"main.js",path:M.default.resolve(o),publicPath:"/",library:t,libraryTarget:"umd"},p=({resourcePath:f},fe,y)=>y===t||/\.global\.(css|less)$/.test(f)||/node_modules/.test(f)?y:`${y}__${(0,Ue.default)(f+y,{algorithm:"md5"}).slice(0,8)}`,a={loader:"@ecomfe/class-names-loader",options:{classNamesModule:require.resolve("classnames")}},c=r?Y.default.loader:"style-loader",m={loader:"postcss-loader",options:{postcssOptions:{plugins:[Me.default]}}},l={loader:"css-loader",options:{modules:{getLocalIdent:p},importLoaders:1}},u={loader:"less-loader",options:{lessOptions:{javascriptEnabled:!0,modifyVars:{...Fe,...bo,"ant-prefix":t}}}};return{mode:e,entry:"./src/index.tsx",output:i(r),devtool:r?!1:"source-map",resolve:{extensions:[".js",".ts",".jsx",".tsx",".css",".less"]},optimization:{minimize:r,minimizer:[new Ne.default,"..."]},plugins:[Oo&&new wo,new X.default.DefinePlugin({"process.env":JSON.stringify(process.env),"process.env.appKey":JSON.stringify(t)}),new je.default({template:M.default.resolve("public/index.html"),filename:"index.html",inject:!0,appKey:t}),r&&new Y.default({filename:"[name].[contenthash].css",chunkFilename:"[name].[contenthash].chunk.css"}),n&&new X.default.HotModuleReplacementPlugin,n&&new Le.default({overlay:!1}),r&&new Ie.CleanWebpackPlugin].filter(Boolean),module:{rules:[{oneOf:[{test:/\.(js|mjs|jsx|ts|tsx)$/,exclude:/node_modules/,loader:"swc-loader",options:{sourceMaps:Eo,jsc:{parser:{syntax:"typescript",tsx:!0},transform:{react:{runtime:"automatic",development:!r,refresh:!r}}},env:{targets:"chrome >= 72",mode:"usage",coreJs:"3.38"}}},{test:/\.css$/,use:[a,c,"css-loader",m]},{test:/\.less$/,use:[a,c,l,m,u]},{test:/\.(png|jpg|gif)$/i,use:[{loader:"url-loader",options:{name:"[name]_[hash].[ext]",limit:100*24}}]},{test:/\.svg$/i,use:["@svgr/webpack"]}]}]},externals:[{...Po()}]}}var M,Ae,_e,Le,$e,Me,Ie,Ne,Ue,je,Y,X,wo,yo,vo,Fe,bo,xo,Po,Eo,Oo,Be=co(()=>{"use strict";M=s(require("path")),Ae=require("@ant-design/compatible"),_e=require("@giteeteam/apps-team-theme"),Le=s(require("@pmmmwh/react-refresh-webpack-plugin")),$e=require("antd"),Me=s(require("autoprefixer")),Ie=require("clean-webpack-plugin"),Ne=s(require("css-minimizer-webpack-plugin")),Ue=s(require("hasha")),je=s(require("html-webpack-plugin")),Y=s(require("mini-css-extract-plugin")),X=s(require("webpack")),wo=require("webpack-bundle-analyzer").BundleAnalyzerPlugin,{defaultAlgorithm:yo,defaultSeed:vo}=$e.theme,Fe=yo({...vo,..._e.themeConfig.token}),bo=(0,Ae.convertLegacyToken)({...Fe}),xo=()=>e=>["window modules",e],Po=()=>{let e=xo();return{"react-dom/client":e("reactDOMClient"),"react-dom":e("reactDOM"),react:e("react")}},Eo=process.env.GENERATE_SOURCEMAP==="true",Oo=process.env.ANALYZER_PACKAGE==="true"});var Ln=require("dotenv/config"),ue=s(require("chalk")),Zt=require("commander");var k="0.8.18";var te=s(require("path"));var L=["manifest.yml","locales"],ve=Buffer.from(process.env.ONE_AUTH_IV||"ABCDEFGHIJKLM_iv","utf-8"),be=Buffer.from(process.env.ONE_AUTH_SECRET_KEY||"ABCDEFGHIJKL_key","utf-8"),xe=process.env.ONE_AUTH_ALGORITHM||"aes-128-cbc";var j=s(require("chalk")),et=s(require("fs-extra"));var Oe=s(require("fs")),J=s(require("path")),ke=s(require("@rollup/plugin-commonjs")),Te=require("rollup");var T=require("fs"),h=require("path"),Pe=require("esbuild"),fo={treeShaking:!0,format:"esm",loader:"tsx"};var go=({source:e,dirPath:t,mode:o})=>{let r="";if(o==="development")try{return r=require.resolve(e+"/src/index.ts",{paths:[t]}),r}catch{}try{return r=require.resolve(e,{paths:[t]}),r}catch{}return r};function Q({mode:e,...t}){return t={...fo,...t},{name:"esbuild",resolveId(o,r,n){if(!r)return o;let i=(0,h.dirname)(r),p;if((0,T.existsSync)(p=(0,h.resolve)(i,o,"index.ts")))return p;if((0,T.existsSync)(p=(0,h.resolve)(i,o,"index.tsx")))return p;if((0,T.existsSync)(p=(0,h.resolve)(i,o+".ts")))return p;if((0,T.existsSync)(p=(0,h.resolve)(i,o+".tsx")))return p;{let a=go({source:o,dirPath:i,mode:e});if((0,T.existsSync)(a))return a;throw console.error({source:o,importer:r,options:n}),p=(0,h.relative)(".",(0,h.resolve)(r,o)),new Error(`ENOENT: ${p.replace(/\\/g,"/")}`)}},async transform(o,r){t.sourcefile=r,t.loader=r.endsWith(".json")?"json":t.loader;let{code:n,map:i}=await(0,Pe.transform)(o,t);return i?{code:n,map:i}:n}}}function ho(e,t,o="development"){let r=[(0,ke.default)()];r.push(Q({mode:o,sourcemap:o==="development",minify:o!=="development",target:"es2018",jsx:"transform",jsxFactory:"AppsUI.createElement",jsxFragment:"AppsUI.Fragment"}));let n={input:e,plugins:r},i={file:t,format:"es",sourcemap:o==="development"};return{inputOptions:n,outputOptions:i}}async function $(e){let{fileName:t,inputDir:o,outputDir:r,mode:n="development"}=e,i=J.default.join(o,`${t}.ts`);try{await Oe.default.promises.access(i)}catch{console.error(`${i} is not exist`);return}let p=J.default.join(r,`${t}.js`),{inputOptions:a,outputOptions:c}=ho(i,p,n);await(await(0,Te.rollup)(a)).write(c)}var Se=s(require("ora")),d=async(e,t)=>{var r,n;let o=(0,Se.default)(e.start).start();try{let i=await t();return o.succeed(e.succeed),i}catch(i){throw o.fail(`${e.error}: ${((n=(r=i==null?void 0:i.response)==null?void 0:r.data)==null?void 0:n.message)||i.message}`),i}};var Ce=s(require("path")),De=require("@giteeteam/apps-manifest"),Re=s(require("fs-extra")),b=async()=>{let e=Ce.default.resolve("manifest.yml"),t=await Re.default.readFile(e);return new De.Manifest(t.toString())};var Ve=s(require("path")),He=s(require("webpack")),qe=s(require("webpack-merge"));var I=async()=>(await Promise.resolve().then(()=>(Be(),Ge))).default;var ze=async({appKey:e,webpackConfig:t})=>{let o=await I();return new Promise((r,n)=>{let i=o({environment:"production",appKey:e});if(t){let a=require(Ve.default.resolve(t));i=(0,qe.default)(i,a)}(0,He.default)(i).run((a,c)=>{if(a)return console.error(a),n(a);if(console.info(c==null?void 0:c.toString()),c!=null&&c.hasErrors())return n(new Error("build-ui-error"));r()})})};var Ke=s(require("path")),We=s(require("archiver")),Z=s(require("fs-extra")),Qe=async(e,t)=>{let o=Ke.default.resolve(t);return await Z.default.remove(o),new Promise((r,n)=>{let i=Z.default.createWriteStream(o),p=(0,We.default)("zip",{zlib:{level:9}});i.on("close",function(){r()}),p.on("warning",function(a){console.info(a),a.code==="ENOENT"||n(a)}),p.on("error",function(a){console.info(a),n(a)}),p.pipe(i),p.directory(e,!1),p.finalize()})};var Je=async e=>{let{manifest:t,mode:o,outputDir:r,inputDir:n}=e,p=t.getFunctionFiles().map(async a=>{await $({inputDir:n,fileName:a,outputDir:r,mode:o})});await Promise.all(p)};var U=s(require("path")),Xe=s(require("fs-extra"));var ee=s(require("path")),Ye=s(require("fs-extra")),N=async(e,t)=>{for(let o of t)try{let r=ee.default.resolve(o),n=ee.default.join(e,o);await Ye.default.copy(r,n)}catch(r){if(r.code==="ENOENT"&&o==="locales")continue;throw r}};var Ze=async({outputDir:e,manifest:t,filesToCopy:o})=>{let{resources:r}=t;if(r)for(let{key:n,path:i}of r){let p=U.default.resolve(U.default.join("./",i)),a=U.default.join(e,n);await Xe.default.copy(p,a)}await N(e,o)};var tt=async({outputDir:e,inputDir:t,prod:o,filesToCopy:r,zip:n,ui:i,webpackConfig:p})=>{let a=await b(),{version:c,key:m}=a.app;if(!m){console.error("manifest app key is required");return}if(!c){console.error("manifest app version is required");return}console.info(`App key: ${j.default.bold.green(m)}`),console.info(`App version: ${j.default.bold.green(c)}
3
- `);let{pass:l,errors:u}=a.validate();if(!l){if(u!=null&&u.length){let{message:g,path:f}=u[0];console.error(`Manifest valid error: Path '${f}', ${g}`)}else console.error("Manifest valid error");return}if(await et.default.emptyDir(e),i&&await d({start:"start build ui",error:"build ui failed",succeed:"build ui success"},()=>ze({appKey:m,webpackConfig:p})),await d({start:"start bundle",error:"bundle failed",succeed:"bundle success"},()=>Je({outputDir:e,inputDir:t,manifest:a,mode:o?"production":"development"})),await d({start:"start package",error:"package failed",succeed:"package success"},()=>Ze({outputDir:e,manifest:a,filesToCopy:r})),n){let g=`${m}_${c}.zip`;await d({start:"start archive",error:"archive failed",succeed:"archive success"},()=>Qe(e,g)),console.info(`
4
- The output file of the build is ${j.default.bold.green(g)}`)}};var ot=async e=>{let{input:t="functions",output:o="package",prod:r,dev:n,copy:i=[],zip:p,ui:a,webpack:c}=e;await tt({outputDir:te.default.resolve(o),inputDir:te.default.resolve(t),prod:r??!n,filesToCopy:[...L,...i],zip:p,ui:!!a,webpackConfig:c}).catch(()=>{})};var ft=s(require("fs")),dt=s(require("chalk"));var rt=s(require("path")),nt=s(require("lowdb")),it=s(require("lowdb/adapters/FileSync"));var oe,re=()=>{if(!oe){let e=rt.default.join(__dirname,"user.json"),t=new it.default(e);oe=(0,nt.default)(t)}return oe},st=()=>{let e=re(),t=e.get("version").value();(!t||t!==k)&&e.defaults({version:k,user:{}}).write()},ne=e=>{st(),re().set("user",e).write()},S=()=>(st(),re().get("user").value());var pt=s(require("fs")),ct=s(require("path")),mt=s(require("form-data"));var at=s(require("axios"));var v={GET:"GET",POST:"POST",PUT:"PUT",DELETE:"DELETE"},E=async({url:e,method:t,data:o,headers:r})=>{let{domain:n,cookie:i}=S();return(await(0,at.default)({method:t,baseURL:n,url:e,data:o,headers:{...r,cookie:i}})).data};var lt=async(e,t)=>{let o=new mt.default;o.append("environmentKey",t),o.append("package",pt.default.createReadStream(ct.default.resolve(e))),await E({method:v.POST,url:"/apps/api/v1/apps/deploy",data:o,headers:{...o.getHeaders()}})};var ut=s(require("chalk")),To=ut.default.bold.red,w={error:e=>{console.info(To(e))}};var gt=(r=>(r.DEVELOPMENT="development",r.STAGING="staging",r.PRODUCTION="production",r))(gt||{}),ht=async(e,t)=>{let{domain:o}=S(),{environment:r="development"}=t;if(!Object.values(gt).includes(r)){w.error("Only support development, staging, production environment.");return}if(!o){w.error("Please login in first!");return}if(!ft.default.existsSync(e)){w.error(`File:${e} is not exist`);return}console.info(`Deploying to ${dt.default.bold.green(o)}`),await d({start:"start deploy",error:"deploy failed",succeed:"deploy success"},()=>lt(e,r)).catch(()=>{})};var C=s(require("path")),D=s(require("fs-extra")),pe=s(require("inquirer"));var wt=s(require("readline")),yt=require("chalk"),vt=s(require("execa")),So=e=>{if(!yt.supportsColor){e.write("\r");return}wt.default.cursorTo(e,0)},Co=(e,t)=>{let o=Math.min(Math.max(e/t,0),1),r=` ${e}/${t}`,n=Math.max(0,process.stderr.columns-r.length-3),i=Math.min(t,n),p=Math.round(i*o),a="#".repeat(p),c="-".repeat(i-p);So(process.stderr),process.stderr.write(`[${a}${c}]${r}`)},Do=(e,t,o,r)=>new Promise((n,i)=>{var a;let p=(0,vt.default)(e,t,{cwd:o,stdio:["inherit","inherit","pipe"],env:r});(a=p.stderr)==null||a.on("data",c=>{let m=c.toString();if(/warning/.test(m))return;let l=m.match(/\[.*] (\d+)\/(\d+)/);if(l){Co(parseFloat(l[1]),parseFloat(l[2]));return}process.stderr.write(c)}),p.on("close",c=>{if(c!==0){i(new Error(`command failed: ${e} ${t.join(" ")}`));return}n()})}),bt={executeCommand:Do};var ie=s(require("fs-extra")),se=s(require("simple-git")),xt=async e=>{await(0,se.default)(e).init()},Pt=async(e,t)=>{await ie.default.pathExists(t)||await ie.default.mkdir(t),await(0,se.default)(t).clone(e,t)};var F=s(require("fs-extra")),Et="https://github.com/moriahq/apps-template.git",ae=(o=>(o.micro="micro",o.uikit="uikit",o))(ae||{}),Ot=async(e,t)=>{if(!await F.default.pathExists(e))return;let o=await F.default.readFile(e,{encoding:"utf-8"});await F.default.writeFile(e,o.replace(/{{(\w+)}}/g,(r,n)=>typeof t[n]=="string"?t[n]:r))};var Ao=async()=>(await pe.default.createPromptModule()({type:"input",name:"App Name",message:"Please enter an app name",validate:o=>!!o}))["App Name"],_o=async()=>(await pe.default.createPromptModule()({type:"input",name:"App key",message:"Please enter a valid app key",validate:o=>/^[a-z][a-z0-9_]*$/.test(o)?!0:(console.info(""),console.info("only supports letters, numbers, underscores and starts with letters"),!1)}))["App key"],Lo=async(e,t)=>{await d({start:"Start clone repository",error:"Clone repository failed!",succeed:"Clone repository success!"},()=>Pt(e,t))},$o=async e=>{await d({start:"Start install dependencies",error:"Install dependencies failed!",succeed:"Install dependencies success!"},()=>bt.executeCommand("yarn",["install"],e))},kt=async e=>{let{cwd:t}=e,o="micro",r=await Ao(),n=await _o(),i=C.default.join(t,n);if(await D.default.pathExists(i)){console.error(`Project path already exists: ${i}`);return}await Lo(Et,i),await D.default.copy(C.default.join(i,o),i),await Promise.all(Object.values(ae).map(a=>D.default.remove(C.default.join(i,a)))),await D.default.remove(C.default.join(i,"./.git"));let p=["./manifest.yml","./package.json","./webpack.config.js","./public/index.html","./src/App.tsx","./src/index.tsx","./static/App.tsx","./static/index.tsx"];await Promise.all(p.map(a=>Ot(C.default.join(i,a),{appName:r,appKey:n}))),await $o(i),await xt(i),console.info("Project init success!"),console.info("Project path:"+i)};var Tt=async()=>{let e=process.cwd();await kt({cwd:e})};var G=s(require("inquirer"));var ce=s(require("axios"));var St=async({baseUrl:e,username:t,password:o})=>{var r;try{return{cookie:(r=(await(0,ce.default)({method:v.POST,url:`${e}/api/gateway/login`,data:{username:t,password:o}})).headers)==null?void 0:r["set-cookie"]}}catch(n){return console.error("Login error:",n==null?void 0:n.message),{cookie:""}}},Ct=async e=>{try{return await(0,ce.default)({method:v.GET,url:`${e}/apps/api/v1/tenants`}),!1}catch{return!0}};var Dt=e=>{try{return new URL(e).origin}catch{return e}};var Rt=s(require("crypto"));var At=e=>{try{let t=Rt.default.createCipheriv(xe,be,ve),o=t.update(e,"utf8","base64");return o+=t.final("base64"),o.toString()}catch(t){return console.error(`Encryption error: ${t}`),null}};var Mo=async()=>(await G.default.createPromptModule()({type:"input",name:"Domain",message:"Please enter the domain address",validate:o=>{try{return new URL(o),!0}catch{return"Please enter a valid domain name"}}})).Domain,Io=async()=>(await G.default.createPromptModule()({type:"input",name:"Username",message:"Please enter username",validate:o=>!!o})).Username,No=async()=>(await G.default.createPromptModule()({type:"password",name:"Password",message:"Please enter password",validate:o=>!!o})).Password,_t=async({domain:e,username:t,password:o})=>{if(e||(e=await Mo()),e=Dt(e),await Ct(e)){t||(t=await Io()),o||(o=await No());let{cookie:n}=await St({baseUrl:e,username:t,password:At(o)||o});n?(ne({domain:e,username:t,cookie:n}),console.info("Login success!")):console.error("Login failed!")}else ne({domain:e}),console.info("Login success!")};var Lt=async e=>{await _t(e)};var q=s(require("path"));var Kt=s(require("path")),H=s(require("chalk")),Wt=s(require("debug")),le=s(require("fs-extra"));var $t=async()=>{var t;return((t=(await E({method:v.GET,url:"/apps/api/v1/config"}).catch(o=>{var r,n;console.info(`getRuntimeConfig error ${((n=(r=o==null?void 0:o.response)==null?void 0:r.data)==null?void 0:n.message)||(o==null?void 0:o.message)}`)})).data)==null?void 0:t.runtime)||{}};var B=require("child_process"),R=class{constructor(t,o){this.imageName=t,this.containerName=o}async downloadImage(){console.info(`Downloading image(${this.imageName}) ...`),await this.execPromise(`docker pull ${this.imageName}`),console.info(`Download image(${this.imageName}) success!`)}async runContainer({port:t,env:o,volume:r=[]}){await this.removeContainer();let n=Object.keys(o).filter(a=>o[a]!==void 0).map(a=>`-e ${a}=${o[a]}`).join(" "),i=r==null?void 0:r.map(a=>`-v ${a}`).join(" "),p=`docker run -d -p ${t}:${t} ${n} ${i} --name ${this.containerName} ${this.imageName}`;await this.execPromise(p)}async removeContainer(){await this.execPromise(`docker rm -f ${this.containerName}`).catch(()=>{})}logs(){let t=(0,B.spawn)("docker",["logs","-f",this.containerName]);t.stdout.on("data",o=>{console.info(`${o}`)}),t.stderr.on("data",o=>{console.info(`${o}`)})}execPromise(t){return new Promise((o,r)=>{(0,B.exec)(t,(n,i,p)=>{if(n)return r(n);o({stdout:i,stderr:p})})})}};var Mt=s(require("localtunnel"));var It=async({appKey:e,runtimeHost:t,resources:o,resourcePort:r})=>{o!=null&&o.length&&o.forEach(n=>{n.path=`http://127.0.0.1:${r}`}),await E({method:v.POST,url:`/apps/api/v1/apps/tunnel/${e}`,data:{resources:o,runtimeHost:t}}).catch(n=>{var i,p;console.info(`addTunnel error ${((p=(i=n==null?void 0:n.response)==null?void 0:i.data)==null?void 0:p.message)||(n==null?void 0:n.message)}`)})},Nt=async e=>{await E({method:"DELETE",url:`/apps/api/v1/apps/tunnel/${e}`}).catch(()=>{})},Ut=async e=>{var t,o;try{return(await(0,Mt.default)({port:e,host:((t=process.env)==null?void 0:t.TUNNEL_HOST)==="OFFICIAL"?void 0:((o=process.env)==null?void 0:o.TUNNEL_HOST)||"http://tunnel.gitee.work:1777"})).url}catch(r){return console.info("runTunnel error",r==null?void 0:r.message),""}};var me=s(require("path")),jt=s(require("cors")),Ft=s(require("express")),Gt=s(require("webpack")),Bt=s(require("webpack-dev-middleware")),Vt=require("webpack-merge");var V=async({appKey:e,webpackConfig:t})=>{let r=(await I())({environment:"development",appKey:e});if(t){let c=require(me.default.resolve(t));r=(0,Vt.merge)(r,c)}let n=(0,Gt.default)(r),i=(0,Ft.default)(),p=Number(process.env.UI_PORT)||8e3,a=(0,Bt.default)(n);i.use((0,jt.default)()),i.use(a),i.get("*",(c,m)=>{var l,u;(u=n.outputFileSystem)==null||u.readFile(me.default.join(((l=r.output)==null?void 0:l.path)||"","index.html"),(g,f)=>{if(g||!f){m.sendStatus(404);return}m.send(f.toString())})}),i.listen(p,"0.0.0.0",()=>{console.info(`The React app is listening on port ${p}!
5
- `)})};var qt=s(require("chokidar"));var Ht=(e,t,o)=>{for(let r of e)$({inputDir:t,outputDir:o,fileName:r,mode:"development"})},zt=async e=>{let{inputDir:t,outputDir:o,watchFilePaths:r}=e,i=(await b()).getFunctionFiles();Ht(i,t,o);let p,a=[t,...r],c=qt.default.watch(a);console.info(`watch: ${a.join(", ")}`),c.on("change",m=>{clearTimeout(p),p=setTimeout(()=>{console.info(`${m} has change`),Ht(i,t,o)},1e3)})};var Uo=(0,Wt.default)("cli:tunnel"),jo=async()=>{let e=await $t(),t=process.env.RUNTIME_IMAGE||e.image||"docker-hub.gitee.work/gitee-prod/proxima-apps-runtime-server:4.4.0-alpha-86",o=Number(process.env.CONTAINER_PORT)||8455,r=process.env.CONTAINER_NAME||"cli-dev-apps-runtime-server",n=process.env.PULL_IMAGE!=="false",i={PORT:o,APPS_DIR:"/usr/src/app/apps",LRU_TTL:1,FS_MODE:"local",DEBUG:process.env.DEBUG||"runtime*",LOG_LEVEL:process.env.LOG_LEVEL,APPS_DEFAULT_LOCALE:process.env.APPS_DEFAULT_LOCALE||"zh-CN",PARSE_PUBLIC_SERVER_URL:process.env.PARSE_PUBLIC_SERVER_URL||e.parsePublicServerUrl,PARSE_SERVER_MASTER_KEY:process.env.PARSE_SERVER_MASTER_KEY||e.parseServerMasterKey,PROXIMA_CORE_URL:process.env.PROXIMA_CORE_URL||e.proximaCoreUrl,APPS_SERVER_URL:process.env.APPS_SERVER_URL||e.appsServerUrl,APPS_PARSE_SERVER_URL:process.env.APPS_PARSE_SERVER_URL||e.appsParseServerUrl,PGSQL_CLIENT_HOST:process.env.PGSQL_CLIENT_HOST,PGSQL_CLIENT_PORT:process.env.PGSQL_CLIENT_PORT,PGSQL_CLIENT_USER:process.env.PGSQL_CLIENT_USER,PGSQL_CLIENT_PASSWORD:process.env.PGSQL_CLIENT_PASSWORD,APPS_RUNTIME_IOREDIS_OPTIONS:process.env.APPS_RUNTIME_IOREDIS_OPTIONS?`'${process.env.APPS_RUNTIME_IOREDIS_OPTIONS}'`:void 0};return{runtimeImage:t,containerPort:o,containerName:r,containerEnv:i,pullImage:n}},Qt=async e=>{var he,we,ye;let{inputDir:t,outputDir:o,server:r,filesToCopy:n,resourcePort:i,ui:p,webpackConfig:a,noProxy:c,watchFilePaths:m=[]}=e;await le.default.emptyDir(o);let l=await b(),u=l.app.key,g=l.app.version,f=l.getFunctionFiles(),fe=l.resources||[];if(!u){w.error("appKey is required!");return}if(!g){w.error("version is required!");return}console.info(`App key: ${H.default.bold.green(u)}`),console.info(`App version: ${H.default.bold.green(g)}
6
- `);let{domain:y}=S();if(!y){w.error("Please login in first!");return}console.info(`Tunneling to ${H.default.bold.green(y)}`);let A=[],z=async O=>{O instanceof Error&&console.error(O);try{await Promise.all(A.map(P=>P()))}catch(P){console.error("other error:",P)}process.exit()};process.on("SIGINT",z),process.on("uncaughtException",z),process.on("unhandledRejection",z),p&&V({appKey:u,webpackConfig:a});let eo=`${`/${u}/development/${g}`}/server-side`,de=Kt.default.join(o,eo);await N(de,n),await zt({inputDir:t,outputDir:de,watchFilePaths:m}),A.push(()=>le.default.remove(o));let K="",ge;if(r&&f.length>0){let{runtimeImage:O,containerPort:P,containerEnv:to,containerName:oo,pullImage:ro}=await jo();ge=P;let _=new R(O,oo);ro&&await _.downloadImage(),await _.runContainer({port:P,env:to,volume:[`${o}:/usr/src/app/apps`]}),A.push(()=>_.removeContainer()),c||(K=await d({start:"start tunnel",error:"tunnel failed",succeed:"tunnel success"},()=>Ut(P)),Uo("runtimeHost",K)),_.logs()}if(c){console.info(`\u4EE3\u7406\u5173\u95ED \u274C\uFF1A\u8BF7\u628A\u8BF7\u6C42\u6307\u5411localhost:${ge}`);return}if(await It({appKey:u,runtimeHost:K,resources:fe,resourcePort:i}),A.push(()=>Nt(u)),r&&((ye=(we=(he=l.getManifest())==null?void 0:he.modules)==null?void 0:we.webtrigger)!=null&&ye.length)){console.info("You can use this url for test:");let O=`${y}/apps/api/v1/:tenant/apps/${u}/environments/development/webtriggers/:webtriggerKey`;console.info(`POST ${O}`)}};var Jt=async e=>{let{copy:t=[],input:o="functions",output:r="cache",server:n=!0,resourcePort:i,ui:p,webpack:a,proxy:c,watch:m=[]}=e;await Qt({outputDir:q.default.resolve(r),inputDir:q.default.resolve(o),filesToCopy:[...L,...t],server:n,resourcePort:Number(i)||8e3,ui:!!p,webpackConfig:a,noProxy:!c,watchFilePaths:m.map(l=>q.default.resolve(l))})};var Fo=async({webpackConfig:e})=>{let t=await b(),{key:o}=t.app;if(!o){w.error("manifest app key is required");return}V({appKey:o,webpackConfig:e})},Yt=Fo;var Xt=async e=>{let{webpack:t}=e;await Yt({webpackConfig:t})};var Go=`v${k}`;console.info(`GiteeTeam Apps Cli ${ue.default.bold.green(Go)}`);console.info(`Node.js ${ue.default.bold.green(process.version)}
7
- `);var x=new Zt.Command;x.version(k,"-v -V --vers").description("Giteeteam Apps Cli");x.command("build").option("--prod","build in production").option("--dev","build in development").option("--no-zip","no archive").option("-c --copy [letters...]","copy files").option("-i --input [dir]","input dir").option("-o --output [dir]","output dir").option("--ui","build ui").option("-w --webpack [file]","build ui webpack config file").action(ot);x.command("init").action(Tt);x.command("login").option("--domain [domain]","login domain").option("-u --username [username]","login username").option("-p --password [password]","login user password").action(Lt);x.command("tunnel").option("-c --copy [letters...]","copy files").option("-i --input [dir]","input dir").option("-o --output [dir]","output dir,default cache").option("--no-server","no server").option("--resourcePort [number]","resource port").option("--ui","build ui").option("-w --webpack [file]","build ui webpack config file").option("--no-proxy","no proxy").option("-w --watch [paths...]","watch files change").action(Jt);x.command("deploy [filename]").option("-e --environment [environment]","app environment").action(ht);x.command("ui-dev").option("-w --webpack [file]","build ui webpack config file").action(Xt);x.parse(process.argv);
2
+ "use strict";var cr=Object.create;var ie=Object.defineProperty;var pr=Object.getOwnPropertyDescriptor;var lr=Object.getOwnPropertyNames;var mr=Object.getPrototypeOf,ur=Object.prototype.hasOwnProperty;var fr=(e,t)=>()=>(e&&(t=e(e=0)),t);var dr=(e,t)=>{for(var r in t)ie(e,r,{get:t[r],enumerable:!0})},gr=(e,t,r,o)=>{if(t&&typeof t=="object"||typeof t=="function")for(let n of lr(t))!ur.call(e,n)&&n!==r&&ie(e,n,{get:()=>t[n],enumerable:!(o=pr(t,n))||o.enumerable});return e};var c=(e,t,r)=>(r=e!=null?cr(mr(e)):{},gr(t||!e||!e.__esModule?ie(r,"default",{value:e,enumerable:!0}):r,e));var qe={};dr(qe,{default:()=>Pr});function Pr({environment:e,appKey:t,distOutputPath:r="dist"}){let o=e==="production",n=e==="development",s=kr(),a=Be.default.existsSync(C.default.resolve("locales")),i=T=>T?{filename:"js/[name].[chunkhash].min.js",path:C.default.resolve(r),publicPath:"./",library:{type:"umd",name:t},clean:!0}:{filename:"main.js",path:C.default.resolve(r),publicPath:"/",library:{type:"umd",name:t}},p=({resourcePath:T},U,y)=>y===t||/\.global\.(css|less)$/.test(T)||/node_modules/.test(T)?y:`${y}__${(0,Ve.default)(`${T}${y}`,{algorithm:"md5"}).slice(0,8)}`,m={loader:"@ecomfe/class-names-loader",options:{classNamesModule:require.resolve("classnames")}},l=o?A.rspack.CssExtractRspackPlugin.loader:"style-loader",u={loader:"postcss-loader",options:{postcssOptions:{plugins:[Ke.default]}}},f={loader:"css-loader",options:{modules:{getLocalIdent:p},importLoaders:1}},P={loader:"less-loader",options:{lessOptions:{javascriptEnabled:!0,modifyVars:{"ant-prefix":t}}}};return{mode:e,entry:"./src/index.tsx",output:i(o),devtool:o?!1:"source-map",resolve:{alias:{"@":C.default.join(process.cwd(),"src/")},extensions:[".js",".ts",".jsx",".tsx",".css",".less"]},optimization:{minimize:o},plugins:[new A.rspack.DefinePlugin({"process.env":JSON.stringify(process.env),"process.env.appKey":JSON.stringify(t)}),new A.rspack.HtmlRspackPlugin({template:C.default.resolve("public/index.html"),filename:"index.html",inject:!0,appKey:t}),o&&new A.rspack.CssExtractRspackPlugin({filename:"[name].[contenthash].css",chunkFilename:"[name].[contenthash].chunk.css"}),n&&new A.rspack.HotModuleReplacementPlugin,n&&new Ge.default({overlay:!1})].filter(Boolean),module:{rules:[{oneOf:[{test:/\.(js|mjs|jsx|ts|tsx)$/,exclude:/node_modules/,loader:"builtin:swc-loader",options:{sourceMaps:br,jsc:{parser:{syntax:"typescript",tsx:!0},transform:{react:{runtime:"automatic",development:!o,refresh:!o}}},env:{targets:"chrome >= 72",mode:"usage",coreJs:"3.38"}},type:"javascript/auto"},s&&a&&{test:/locales/,loader:s,include:[C.default.resolve("locales")]},{test:/\.css$/,use:[m,l,"css-loader",u]},{test:/\.less$/,use:[m,l,f,u,P]},{test:/\.(png|jpg|gif)$/i,type:"asset",parser:{dataUrlCondition:{maxSize:2400}},generator:{filename:"[name]_[hash][ext]"}},{test:/\.svg$/i,use:["@svgr/webpack"]}]}]}}}var Be,C,A,Ge,Ke,Ve,br,kr,He=fr(()=>{"use strict";Be=c(require("fs")),C=c(require("path")),A=require("@rspack/core"),Ge=c(require("@rspack/plugin-react-refresh")),Ke=c(require("autoprefixer")),Ve=c(require("hasha")),br=process.env.GENERATE_SOURCEMAP==="true",kr=()=>{try{return require.resolve("@alienfast/i18next-loader")}catch{return null}}});var es=require("dotenv/config"),xe=c(require("chalk")),or=require("commander");var x="1.0.0-alpha.2";var me=c(require("path"));var G=["manifest.yml","locales"],De=Buffer.from(process.env.ONE_AUTH_IV||"ABCDEFGHIJKLM_iv","utf-8"),Re=Buffer.from(process.env.ONE_AUTH_SECRET_KEY||"ABCDEFGHIJKL_key","utf-8"),je=process.env.ONE_AUTH_ALGORITHM||"aes-128-cbc";var z=c(require("chalk")),nt=c(require("fs-extra"));var Le=c(require("fs")),ce=c(require("path")),$e=c(require("@rollup/plugin-commonjs")),Ne=require("rollup");var _=require("fs"),w=require("path"),_e=require("esbuild"),yr={treeShaking:!0,format:"esm",loader:"tsx"};var wr=({source:e,dirPath:t,mode:r})=>{let o="";if(r==="development")try{return o=require.resolve(e+"/src/index.ts",{paths:[t]}),o}catch{}try{return o=require.resolve(e,{paths:[t]}),o}catch{}return o};function ae({mode:e,...t}){return t={...yr,...t},{name:"esbuild",resolveId(r,o,n){if(!o)return r;let s=(0,w.dirname)(o),a;if((0,_.existsSync)(a=(0,w.resolve)(s,r,"index.ts")))return a;if((0,_.existsSync)(a=(0,w.resolve)(s,r,"index.tsx")))return a;if((0,_.existsSync)(a=(0,w.resolve)(s,r+".ts")))return a;if((0,_.existsSync)(a=(0,w.resolve)(s,r+".tsx")))return a;{let i=wr({source:r,dirPath:s,mode:e});if((0,_.existsSync)(i))return i;throw console.error({source:r,importer:o,options:n}),a=(0,w.relative)(".",(0,w.resolve)(o,r)),new Error(`ENOENT: ${a.replace(/\\/g,"/")}`)}},async transform(r,o){t.sourcefile=o,t.loader=o.endsWith(".json")?"json":t.loader;let{code:n,map:s}=await(0,_e.transform)(r,t);return s?{code:n,map:s}:n}}}function vr(e,t,r="development"){let o=[(0,$e.default)()];o.push(ae({mode:r,sourcemap:r==="development",minify:r!=="development",target:"es2018",jsx:"transform",jsxFactory:"AppsUI.createElement",jsxFragment:"AppsUI.Fragment"}));let n={input:e,plugins:o},s={file:t,format:"es",sourcemap:r==="development"};return{inputOptions:n,outputOptions:s}}async function K(e){let{fileName:t,inputDir:r,outputDir:o,mode:n="development"}=e,s=ce.default.join(r,`${t}.ts`);try{await Le.default.promises.access(s)}catch{console.error(`${s} is not exist`);return}let a=ce.default.join(o,`${t}.js`),{inputOptions:i,outputOptions:p}=vr(s,a,n);await(await(0,Ne.rollup)(i)).write(p)}var Ie=c(require("ora")),d=async(e,t)=>{var o,n;let r=(0,Ie.default)(e.start).start();try{let s=await t();return r.succeed(e.succeed),s}catch(s){throw r.fail(`${e.error}: ${((n=(o=s==null?void 0:s.response)==null?void 0:o.data)==null?void 0:n.message)||s.message}`),s}};var Fe=c(require("path")),Me=require("@giteeteam/apps-manifest"),Ue=c(require("fs-extra")),E=async()=>{let e=Fe.default.resolve("manifest.yml"),t=await Ue.default.readFile(e);return new Me.Manifest(t.toString())};var Je=c(require("path")),We=require("@rspack/core");var V=async()=>(await Promise.resolve().then(()=>(He(),qe))).default;var ze=e=>Object.prototype.toString.call(e)==="[object Object]",I=(e,t)=>{if(t===void 0)return e;if(Array.isArray(e)&&Array.isArray(t))return[...e,...t];if(ze(e)&&ze(t)){let r={...e};for(let[o,n]of Object.entries(t))r[o]=o in r?I(r[o],n):n;return r}return t};var Qe=async({appKey:e,rspackConfig:t})=>{let r=await V();return new Promise((o,n)=>{let s=r({environment:"production",appKey:e});if(t){let i=require(Je.default.resolve(t));s=I(s,i)}(0,We.rspack)(s).run((i,p)=>{if(i)return console.error(i),n(i);if(console.info(p==null?void 0:p.toString()),p!=null&&p.hasErrors())return n(new Error("build-ui-error"));o()})})};var Ye=c(require("path")),Xe=c(require("archiver")),pe=c(require("fs-extra")),Ze=async(e,t)=>{let r=Ye.default.resolve(t);return await pe.default.remove(r),new Promise((o,n)=>{let s=pe.default.createWriteStream(r),a=(0,Xe.default)("zip",{zlib:{level:9}});s.on("close",function(){o()}),a.on("warning",function(i){console.info(i),i.code==="ENOENT"||n(i)}),a.on("error",function(i){console.info(i),n(i)}),a.pipe(s),a.directory(e,!1),a.finalize()})};var et=async e=>{let{manifest:t,mode:r,outputDir:o,inputDir:n}=e,a=t.getFunctionFiles().map(async i=>{await K({inputDir:n,fileName:i,outputDir:o,mode:r})});await Promise.all(a)};var H=c(require("path")),rt=c(require("fs-extra"));var le=c(require("path")),tt=c(require("fs-extra")),q=async(e,t)=>{for(let r of t)try{let o=le.default.resolve(r),n=le.default.join(e,r);await tt.default.copy(o,n)}catch(o){if(o.code==="ENOENT"&&r==="locales")continue;throw o}};var ot=async({outputDir:e,manifest:t,filesToCopy:r})=>{let{resources:o}=t;if(o)for(let{key:n,path:s}of o){let a=H.default.resolve(H.default.join("./",s)),i=H.default.join(e,n);await rt.default.copy(a,i)}await q(e,r)};var st=async({outputDir:e,inputDir:t,prod:r,filesToCopy:o,zip:n,ui:s,rspackConfig:a})=>{let i=await E(),{version:p,key:m}=i.app;if(!m){console.error("manifest app key is required");return}if(!p){console.error("manifest app version is required");return}console.info(`App key: ${z.default.bold.green(m)}`),console.info(`App version: ${z.default.bold.green(p)}
3
+ `);let{pass:l,errors:u}=i.validate();if(!l){if(u!=null&&u.length){let{message:f,path:P}=u[0];console.error(`Manifest valid error: Path '${P}', ${f}`)}else console.error("Manifest valid error");return}if(await nt.default.emptyDir(e),s&&await d({start:"start build ui",error:"build ui failed",succeed:"build ui success"},()=>Qe({appKey:m,rspackConfig:a})),await d({start:"start bundle",error:"bundle failed",succeed:"bundle success"},()=>et({outputDir:e,inputDir:t,manifest:i,mode:r?"production":"development"})),await d({start:"start package",error:"package failed",succeed:"package success"},()=>ot({outputDir:e,manifest:i,filesToCopy:o})),n){let f=`${m}_${p}.zip`;await d({start:"start archive",error:"archive failed",succeed:"archive success"},()=>Ze(e,f)),console.info(`
4
+ The output file of the build is ${z.default.bold.green(f)}`)}};var it=async e=>{let{input:t="functions",output:r="package",prod:o,dev:n,copy:s=[],zip:a,ui:i,rspack:p}=e;await st({outputDir:me.default.resolve(r),inputDir:me.default.resolve(t),prod:o??!n,filesToCopy:[...G,...s],zip:a,ui:!!i,rspackConfig:p}).catch(()=>{})};var yt=c(require("fs")),wt=c(require("chalk"));var at=c(require("path")),ct=c(require("lowdb")),pt=c(require("lowdb/adapters/FileSync"));var ue,fe=()=>{if(!ue){let e=at.default.join(__dirname,"user.json"),t=new pt.default(e);ue=(0,ct.default)(t)}return ue},lt=()=>{let e=fe(),t=e.get("version").value();(!t||t!==x)&&e.defaults({version:x,user:{}}).write()},de=e=>{lt(),fe().set("user",e).write()},L=()=>(lt(),fe().get("user").value());var ut=c(require("fs")),ft=c(require("path")),dt=c(require("form-data"));var mt=c(require("axios"));var b={GET:"GET",POST:"POST",PUT:"PUT",DELETE:"DELETE"},D=async({url:e,method:t,data:r,headers:o})=>{let{domain:n,cookie:s}=L();return(await(0,mt.default)({method:t,baseURL:n,url:e,data:r,headers:{...o,cookie:s}})).data};var gt=async(e,t)=>{let r=new dt.default;r.append("environmentKey",t),r.append("package",ut.default.createReadStream(ft.default.resolve(e))),await D({method:b.POST,url:"/apps/api/v1/apps/deploy",data:r,headers:{...r.getHeaders()}})};var ht=c(require("chalk")),xr=ht.default.bold.red,g={error:e=>{console.info(xr(e))}};var vt=(o=>(o.DEVELOPMENT="development",o.STAGING="staging",o.PRODUCTION="production",o))(vt||{}),bt=async(e,t)=>{let{domain:r}=L(),{environment:o="development"}=t;if(!Object.values(vt).includes(o)){g.error("Only support development, staging, production environment.");return}if(!r){g.error("Please login in first!");return}if(!yt.default.existsSync(e)){g.error(`File:${e} is not exist`);return}console.info(`Deploying to ${wt.default.bold.green(r)}`),await d({start:"start deploy",error:"deploy failed",succeed:"deploy success"},()=>gt(e,o)).catch(()=>{})};var N=c(require("path")),F=c(require("fs-extra")),we=c(require("inquirer"));var kt=c(require("readline")),Pt=require("chalk"),xt=c(require("execa")),Er=e=>{if(!Pt.supportsColor){e.write("\r");return}kt.default.cursorTo(e,0)},Or=(e,t)=>{let r=Math.min(Math.max(e/t,0),1),o=` ${e}/${t}`,n=Math.max(0,process.stderr.columns-o.length-3),s=Math.min(t,n),a=Math.round(s*r),i="#".repeat(a),p="-".repeat(s-a);Er(process.stderr),process.stderr.write(`[${i}${p}]${o}`)},Tr=(e,t,r,o)=>new Promise((n,s)=>{var i;let a=(0,xt.default)(e,t,{cwd:r,stdio:["inherit","inherit","pipe"],env:o});(i=a.stderr)==null||i.on("data",p=>{let m=p.toString();if(/warning/.test(m))return;let l=m.match(/\[.*] (\d+)\/(\d+)/);if(l){Or(parseFloat(l[1]),parseFloat(l[2]));return}process.stderr.write(p)}),a.on("close",p=>{if(p!==0){s(new Error(`command failed: ${e} ${t.join(" ")}`));return}n()})}),Et={executeCommand:Tr};var ge=c(require("fs-extra")),he=c(require("simple-git")),Ot=async e=>{await(0,he.default)(e).init()},J=async(e,t,r)=>{await ge.default.pathExists(t)||await ge.default.mkdir(t);let o=(0,he.default)(t),n=[];r!=null&&r.branch&&n.push("--branch",r.branch),r!=null&&r.singleBranch&&n.push("--single-branch"),await o.clone(e,t,n)};var k=c(require("path")),R=c(require("fs-extra"));var W=c(require("fs-extra")),Tt=process.env.APPS_TEMPLATE_REPO||"https://github.com/moriahq/apps-template.git",ye=(r=>(r.micro="micro",r.uikit="uikit",r))(ye||{}),Q=async(e,t)=>{if(!await W.default.pathExists(e))return;let r=await W.default.readFile(e,{encoding:"utf-8"});await W.default.writeFile(e,r.replace(/{{(\w+)}}/g,(o,n)=>typeof t[n]=="string"?t[n]:o))};var Cr=async()=>{let e=[k.default.resolve(__dirname,"templates/skill"),k.default.resolve(__dirname,"../templates/skill")];for(let t of e)if(await R.default.pathExists(t))return t;return""},St=async(e,t)=>{let r=await R.default.readdir(e,{withFileTypes:!0});return(await Promise.all(r.map(async n=>{let s=k.default.join(e,n.name);return n.isDirectory()?St(s,t):n.isFile()?[k.default.relative(t,s)]:[]}))).flat()},$=async(e,t)=>{let{appName:r,appKey:o,overwrite:n=!1}=t,s=await Cr();if(!s||!await R.default.pathExists(s))throw new Error(`skill templates not found: ${s}`);let a=await St(s,s);for(let i of a){let p=k.default.join(s,i),m=i==="SKILL.md"||i.startsWith("skill/")?i:k.default.join("skill",i),l=k.default.join(e,m);!n&&await R.default.pathExists(l)||(await R.default.ensureDir(k.default.dirname(l)),await R.default.copy(p,l),l.endsWith(".md")&&await Q(l,{appName:r,appKey:o}))}};var Dr=async()=>(await we.default.createPromptModule()({type:"input",name:"App Name",message:"Please enter an app name",validate:r=>!!r}))["App Name"],Rr=async()=>(await we.default.createPromptModule()({type:"input",name:"App key",message:"Please enter a valid app key",validate:r=>/^[a-z][a-z0-9_]*$/.test(r)?!0:(console.info(""),console.info("only supports letters, numbers, underscores and starts with letters"),!1)}))["App key"],jr=()=>{if(Number(x.split(".")[0])>=1)return"v1"},_r=async(e,t)=>{let r=jr();if(!r){await d({start:"Start clone repository",error:"Clone repository failed!",succeed:"Clone repository success!"},()=>J(e,t));return}try{await d({start:`Start clone repository (branch: ${r})`,error:"Clone repository failed!",succeed:"Clone repository success!"},()=>J(e,t,{branch:r,singleBranch:!0}))}catch{console.info(`Template branch '${r}' not found, fallback to default branch.`),await d({start:"Start clone repository (default branch)",error:"Clone repository failed!",succeed:"Clone repository success!"},()=>J(e,t))}},Ar=async e=>{await d({start:"Start install dependencies",error:"Install dependencies failed!",succeed:"Install dependencies success!"},()=>Et.executeCommand("pnpm",["install"],e))},Ct=async e=>{let{cwd:t}=e,r="micro",o=await Dr(),n=await Rr(),s=N.default.join(t,n);if(await F.default.pathExists(s)){console.error(`Project path already exists: ${s}`);return}await _r(Tt,s),await F.default.copy(N.default.join(s,r),s),await Promise.all(Object.values(ye).map(i=>F.default.remove(N.default.join(s,i)))),await F.default.remove(N.default.join(s,"./.git"));let a=["./manifest.yml","./package.json","./rspack.config.js","./public/index.html","./src/App.tsx","./src/index.tsx","./static/App.tsx","./static/index.tsx","./SKILL.md"];await Promise.all(a.map(i=>Q(N.default.join(s,i),{appName:o,appKey:n}))),await $(s,{appName:o,appKey:n}),await Ar(s),await Ot(s),console.info("Project init success!"),console.info("Project path:"+s)};var Dt=async()=>{let e=process.cwd();await Ct({cwd:e})};var Y=c(require("inquirer"));var ve=c(require("axios"));var Rt=async({baseUrl:e,username:t,password:r})=>{var o;try{return{cookie:(o=(await(0,ve.default)({method:b.POST,url:`${e}/api/gateway/login`,data:{username:t,password:r}})).headers)==null?void 0:o["set-cookie"]}}catch(n){return console.error("Login error:",n==null?void 0:n.message),{cookie:""}}},jt=async e=>{try{return await(0,ve.default)({method:b.GET,url:`${e}/apps/api/v1/tenants`}),!1}catch{return!0}};var _t=e=>{try{return new URL(e).origin}catch{return e}};var At=c(require("crypto"));var Lt=e=>{try{let t=At.default.createCipheriv(je,Re,De),r=t.update(e,"utf8","base64");return r+=t.final("base64"),r.toString()}catch(t){return console.error(`Encryption error: ${t}`),null}};var Lr=async()=>(await Y.default.createPromptModule()({type:"input",name:"Domain",message:"Please enter the domain address",validate:r=>{try{return new URL(r),!0}catch{return"Please enter a valid domain name"}}})).Domain,$r=async()=>(await Y.default.createPromptModule()({type:"input",name:"Username",message:"Please enter username",validate:r=>!!r})).Username,Nr=async()=>(await Y.default.createPromptModule()({type:"password",name:"Password",message:"Please enter password",validate:r=>!!r})).Password,$t=async({domain:e,username:t,password:r})=>{if(e||(e=await Lr()),e=_t(e),await jt(e)){t||(t=await $r()),r||(r=await Nr());let{cookie:n}=await Rt({baseUrl:e,username:t,password:Lt(r)||r});n?(de({domain:e,username:t,cookie:n}),console.info("Login success!")):console.error("Login failed!")}else de({domain:e}),console.info("Login success!")};var Nt=async e=>{await $t(e)};var X=c(require("path")),Z=c(require("fs-extra"));var Ir=async e=>{var i,p,m,l;let t=X.default.join(e,"manifest.yml"),r=X.default.basename(e),o=r;if(!await Z.default.pathExists(t))return{appName:r,appKey:o};let n=await Z.default.readFile(t,"utf8"),s=((p=(i=n.match(/^\s*name:\s*(.+)\s*$/m))==null?void 0:i[1])==null?void 0:p.trim())||r,a=((l=(m=n.match(/^\s*key:\s*(.+)\s*$/m))==null?void 0:m[1])==null?void 0:l.trim())||o;return{appName:s,appKey:a}},It=async e=>{let t=X.default.resolve(e||process.cwd());if(!await Z.default.pathExists(t)){g.error(`project path not found: ${t}`);return}let{appName:r,appKey:o}=await Ir(t);await $(t,{appName:r,appKey:o,overwrite:!0}),console.info("sync-skill finished."),console.info(`Project path: ${t}`)};var oe=c(require("path"));var Qt=c(require("path")),re=c(require("chalk")),Yt=c(require("debug")),ke=c(require("fs-extra"));var Ft=async()=>{var t;return((t=(await D({method:b.GET,url:"/apps/api/v1/config"}).catch(r=>{var o,n;console.info(`getRuntimeConfig error ${((n=(o=r==null?void 0:r.response)==null?void 0:o.data)==null?void 0:n.message)||(r==null?void 0:r.message)}`)})).data)==null?void 0:t.runtime)||{}};var ee=require("child_process"),M=class{constructor(t,r){this.imageName=t,this.containerName=r}async downloadImage(){console.info(`Downloading image(${this.imageName}) ...`),await this.execPromise(`docker pull ${this.imageName}`),console.info(`Download image(${this.imageName}) success!`)}async runContainer({port:t,env:r,volume:o=[]}){await this.removeContainer();let n=Object.keys(r).filter(i=>r[i]!==void 0).map(i=>`-e ${i}=${r[i]}`).join(" "),s=o==null?void 0:o.map(i=>`-v ${i}`).join(" "),a=`docker run -d -p ${t}:${t} ${n} ${s} --name ${this.containerName} ${this.imageName}`;await this.execPromise(a)}async removeContainer(){await this.execPromise(`docker rm -f ${this.containerName}`).catch(()=>{})}logs(){let t=(0,ee.spawn)("docker",["logs","-f",this.containerName]);t.stdout.on("data",r=>{console.info(`${r}`)}),t.stderr.on("data",r=>{console.info(`${r}`)})}execPromise(t){return new Promise((r,o)=>{(0,ee.exec)(t,(n,s,a)=>{if(n)return o(n);r({stdout:s,stderr:a})})})}};var Mt=c(require("localtunnel"));var Ut=async({appKey:e,runtimeHost:t,resources:r,resourcePort:o})=>{r!=null&&r.length&&r.forEach(n=>{n.path=`http://127.0.0.1:${o}`}),await D({method:b.POST,url:`/apps/api/v1/apps/tunnel/${e}`,data:{resources:r,runtimeHost:t}}).catch(n=>{var s,a;console.info(`addTunnel error ${((a=(s=n==null?void 0:n.response)==null?void 0:s.data)==null?void 0:a.message)||(n==null?void 0:n.message)}`)})},Bt=async e=>{await D({method:"DELETE",url:`/apps/api/v1/apps/tunnel/${e}`}).catch(()=>{})},Gt=async e=>{var t,r;try{return(await(0,Mt.default)({port:e,host:((t=process.env)==null?void 0:t.TUNNEL_HOST)==="OFFICIAL"?void 0:((r=process.env)==null?void 0:r.TUNNEL_HOST)||"http://tunnel.gitee.work:1777"})).url}catch(o){return console.info("runTunnel error",o==null?void 0:o.message),""}};var be=c(require("path")),Kt=require("@rspack/core"),Vt=require("@rspack/dev-middleware"),qt=c(require("cors")),Ht=c(require("express"));var te=async({appKey:e,rspackConfig:t})=>{let o=(await V())({environment:"development",appKey:e});if(t){let p=require(be.default.resolve(t));o=I(o,p)}let n=(0,Kt.rspack)(o),s=(0,Ht.default)(),a=Number(process.env.UI_PORT)||8e3,i=(0,Vt.devMiddleware)(n);s.use((0,qt.default)()),s.use(i),s.get("*",(p,m)=>{var l,u;(u=n.outputFileSystem)==null||u.readFile(be.default.join(((l=o.output)==null?void 0:l.path)||"","index.html"),(f,P)=>{if(f||!P){m.sendStatus(404);return}m.send(P.toString())})}),s.listen(a,"0.0.0.0",()=>{console.info(`The React app is listening on port ${a}!
5
+ `)})};var Jt=c(require("chokidar"));var zt=(e,t,r)=>{for(let o of e)K({inputDir:t,outputDir:r,fileName:o,mode:"development"})},Wt=async e=>{let{inputDir:t,outputDir:r,watchFilePaths:o}=e,s=(await E()).getFunctionFiles();zt(s,t,r);let a,i=[t,...o],p=Jt.default.watch(i);console.info(`watch: ${i.join(", ")}`),p.on("change",m=>{clearTimeout(a),a=setTimeout(()=>{console.info(`${m} has change`),zt(s,t,r)},1e3)})};var Fr=(0,Yt.default)("cli:tunnel"),Mr=async()=>{let e=await Ft(),t=process.env.RUNTIME_IMAGE||e.image||"docker-hub.gitee.work/gitee-prod/proxima-apps-runtime-server:4.4.0-alpha-86",r=Number(process.env.CONTAINER_PORT)||8455,o=process.env.CONTAINER_NAME||"cli-dev-apps-runtime-server",n=process.env.PULL_IMAGE!=="false",s={PORT:r,APPS_DIR:"/usr/src/app/apps",LRU_TTL:1,FS_MODE:"local",DEBUG:process.env.DEBUG||"runtime*",LOG_LEVEL:process.env.LOG_LEVEL,APPS_DEFAULT_LOCALE:process.env.APPS_DEFAULT_LOCALE||"zh-CN",PARSE_PUBLIC_SERVER_URL:process.env.PARSE_PUBLIC_SERVER_URL||e.parsePublicServerUrl,PARSE_SERVER_MASTER_KEY:process.env.PARSE_SERVER_MASTER_KEY||e.parseServerMasterKey,PROXIMA_CORE_URL:process.env.PROXIMA_CORE_URL||e.proximaCoreUrl,APPS_SERVER_URL:process.env.APPS_SERVER_URL||e.appsServerUrl,APPS_PARSE_SERVER_URL:process.env.APPS_PARSE_SERVER_URL||e.appsParseServerUrl,PGSQL_CLIENT_HOST:process.env.PGSQL_CLIENT_HOST,PGSQL_CLIENT_PORT:process.env.PGSQL_CLIENT_PORT,PGSQL_CLIENT_USER:process.env.PGSQL_CLIENT_USER,PGSQL_CLIENT_PASSWORD:process.env.PGSQL_CLIENT_PASSWORD,APPS_RUNTIME_IOREDIS_OPTIONS:process.env.APPS_RUNTIME_IOREDIS_OPTIONS?`'${process.env.APPS_RUNTIME_IOREDIS_OPTIONS}'`:void 0};return{runtimeImage:t,containerPort:r,containerName:o,containerEnv:s,pullImage:n}},Xt=async e=>{var Te,Se,Ce;let{inputDir:t,outputDir:r,server:o,filesToCopy:n,resourcePort:s,ui:a,rspackConfig:i,noProxy:p,watchFilePaths:m=[]}=e;await ke.default.emptyDir(r);let l=await E(),u=l.app.key,f=l.app.version,P=l.getFunctionFiles(),T=l.resources||[];if(!u){g.error("appKey is required!");return}if(!f){g.error("version is required!");return}console.info(`App key: ${re.default.bold.green(u)}`),console.info(`App version: ${re.default.bold.green(f)}
6
+ `);let{domain:U}=L();if(!U){g.error("Please login in first!");return}console.info(`Tunneling to ${re.default.bold.green(U)}`);let y=[],ne=async j=>{j instanceof Error&&console.error(j);try{await Promise.all(y.map(S=>S()))}catch(S){console.error("other error:",S)}process.exit()};process.on("SIGINT",ne),process.on("uncaughtException",ne),process.on("unhandledRejection",ne),a&&te({appKey:u,rspackConfig:i});let nr=`${`/${u}/development/${f}`}/server-side`,Ee=Qt.default.join(r,nr);await q(Ee,n),await Wt({inputDir:t,outputDir:Ee,watchFilePaths:m}),y.push(()=>ke.default.remove(r));let se="",Oe;if(o&&P.length>0){let{runtimeImage:j,containerPort:S,containerEnv:sr,containerName:ir,pullImage:ar}=await Mr();Oe=S;let B=new M(j,ir);ar&&await B.downloadImage(),await B.runContainer({port:S,env:sr,volume:[`${r}:/usr/src/app/apps`]}),y.push(()=>B.removeContainer()),p||(se=await d({start:"start tunnel",error:"tunnel failed",succeed:"tunnel success"},()=>Gt(S)),Fr("runtimeHost",se)),B.logs()}if(p){console.info(`\u4EE3\u7406\u5173\u95ED \u274C\uFF1A\u8BF7\u628A\u8BF7\u6C42\u6307\u5411localhost:${Oe}`);return}if(await Ut({appKey:u,runtimeHost:se,resources:T,resourcePort:s}),y.push(()=>Bt(u)),o&&((Ce=(Se=(Te=l.getManifest())==null?void 0:Te.modules)==null?void 0:Se.webtrigger)!=null&&Ce.length)){console.info("You can use this url for test:");let j=`${U}/apps/api/v1/:tenant/apps/${u}/environments/development/webtriggers/:webtriggerKey`;console.info(`POST ${j}`)}};var Zt=async e=>{let{copy:t=[],input:r="functions",output:o="cache",server:n=!0,resourcePort:s,ui:a,rspack:i,proxy:p,watch:m=[]}=e;await Xt({outputDir:oe.default.resolve(o),inputDir:oe.default.resolve(r),filesToCopy:[...G,...t],server:n,resourcePort:Number(s)||8e3,ui:!!a,rspackConfig:i,noProxy:!p,watchFilePaths:m.map(l=>oe.default.resolve(l))})};var Ur=async({rspackConfig:e})=>{let t=await E(),{key:r}=t.app;if(!r){g.error("manifest app key is required");return}te({appKey:r,rspackConfig:e})},er=Ur;var tr=async e=>{let{rspack:t}=e;await er({rspackConfig:t})};var O=c(require("path")),h=c(require("fs-extra"));var Br=["@ant-design/compatible","@giteeteam/apps-team-theme","webpack","webpack-cli","webpack-dev-server","webpack-merge","webpack-bundle-analyzer"],Gr={"@rspack/core":"^2.0.0","@rspack/plugin-react-refresh":"^1.4.2",deepmerge:"^4.3.1"},Kr=["webpack.config.js","webpack.config.cjs","webpack.config.mjs","webpack.config.ts"],Pe=e=>Object.fromEntries(Object.entries(e).sort(([t],[r])=>t.localeCompare(r))),Vr=e=>{let t=e.peerDependencies;if(!t||typeof t!="object")return!1;let r=!1;for(let o of["@ant-design/compatible","@giteeteam/apps-team-theme"])o in t&&(delete t[o],r=!0);return r&&(e.peerDependencies=Pe(t)),r},qr=e=>{let t=["dependencies","devDependencies"],r=!1;for(let o of t){let n=e[o];if(!(!n||typeof n!="object"))for(let s of Br)s in n&&(delete n[s],r=!0)}(!e.dependencies||typeof e.dependencies!="object")&&(e.dependencies={},r=!0);for(let[o,n]of Object.entries(Gr))e.dependencies[o]||(e.dependencies[o]=n,r=!0);return e.dependencies&&typeof e.dependencies=="object"&&(e.dependencies=Pe(e.dependencies)),e.devDependencies&&typeof e.devDependencies=="object"&&(e.devDependencies=Pe(e.devDependencies)),r},Hr=e=>{if(!e.scripts||typeof e.scripts!="object")return!1;let t=!1;for(let[r,o]of Object.entries(e.scripts)){let n=o;n=n.replace(/\bwebpack-dev-server\b/g,"rspack serve"),n=n.replace(/\bwebpack serve\b/g,"rspack serve"),n=n.replace(/\bwebpack\b/g,"rspack"),n=n.replace(/--webpack\b/g,"--rspack"),n=n.replace(/(^|\s)-w(\s+)/g,"$1-r$2"),n=n.replace(/webpack\.config\.(js|cjs|mjs|ts)\b/g,"rspack.config.$1"),n!==o&&(e.scripts[r]=n,t=!0)}return t},zr=async e=>{let t=!1;for(let r of Kr){let o=O.default.join(e,r);if(!await h.default.pathExists(o))continue;let n=r.replace(/^webpack\.config/,"rspack.config"),s=O.default.join(e,n);await h.default.pathExists(s)||(await h.default.move(o,s),t=!0);let a=await h.default.readFile(s,"utf8"),i=a.replace(/webpack配置/g,"rspack\u914D\u7F6E").replace(/import\s+\{\s*themeConfig\s*\}\s+from\s+['"]@giteeteam\/apps-team-theme['"];?\n?/g,"").replace(/import\s+\{\s*convertLegacyToken\s*\}\s+from\s+['"]@ant-design\/compatible['"];?\n?/g,"").replace(/const\s+mapToken\s*=\s*defaultAlgorithm\(\{\s*\.\.\.defaultSeed\s*,\s*\.\.\.themeConfig\.token\s*\}\);?/g,"const mapToken = defaultAlgorithm({ ...defaultSeed });").replace(/const\s+v4Token\s*=\s*convertLegacyToken\(\{\s*\.\.\.mapToken\s*\}\);?\n?/g,"").replace(/\n([ \t]*)\.\.\.v4Token,\n/g,`
7
+ `).replace(/import\s+\{\s*merge\s*\}\s+from\s+['"]webpack-merge['"];?/g,"import merge from 'deepmerge';").replace(/const\s+\{\s*merge\s*\}\s*=\s*require\((['"])webpack-merge\1\);?/g,"const merge = require('deepmerge');").replace(/(['"])webpack-merge\1/g,"$1deepmerge$1").replace(/^.*(rspack-bundle-analyzer|webpack-bundle-analyzer).*\n?/gm,"").replace(/^.*ANALYZER_PACKAGE.*\n?/gm,"").replace(/(['"])webpack\1/g,"$1@rspack/core$1");i!==a&&(await h.default.writeFile(s,i),t=!0)}return t},Jr=async e=>{var i,p,m,l;let t=O.default.join(e,"manifest.yml"),r=O.default.basename(e),o=r;if(!await h.default.pathExists(t))return{appName:r,appKey:o};let n=await h.default.readFile(t,"utf8"),s=((p=(i=n.match(/^\s*name:\s*(.+)\s*$/m))==null?void 0:i[1])==null?void 0:p.trim())||r,a=((l=(m=n.match(/^\s*key:\s*(.+)\s*$/m))==null?void 0:m[1])==null?void 0:l.trim())||o;return{appName:s,appKey:a}},rr=async e=>{let t=O.default.resolve(e||process.cwd()),r=O.default.join(t,"package.json");if(!await h.default.pathExists(r)){g.error(`package.json not found in ${t}`);return}let o=await h.default.readFile(r,"utf8"),n=JSON.parse(o),s=qr(n),a=Vr(n),i=Hr(n),p=await zr(t),{appName:m,appKey:l}=await Jr(t),u=await h.default.pathExists(O.default.join(t,"SKILL.md"));await $(t,{appName:m,appKey:l});let f=!u;if((s||a||i)&&await h.default.writeFile(r,`${JSON.stringify(n,null,2)}
8
+ `),!s&&!a&&!i&&!p&&!f){console.info("Nothing to upgrade. Project already uses rspack settings.");return}console.info("upgrade-v1 finished."),console.info(`Project path: ${t}`),console.info("Please run: pnpm install")};var Wr=`v${x}`;console.info(`GiteeTeam Apps Cli ${xe.default.bold.green(Wr)}`);console.info(`Node.js ${xe.default.bold.green(process.version)}
9
+ `);var v=new or.Command;v.version(x,"-v -V --vers").description("Giteeteam Apps Cli");v.command("build").option("--prod","build in production").option("--dev","build in development").option("--no-zip","no archive").option("-c --copy [letters...]","copy files").option("-i --input [dir]","input dir").option("-o --output [dir]","output dir").option("--ui","build ui").option("-r --rspack [file]","build ui rspack config file").action(it);v.command("init").action(Dt);v.command("sync-skill [projectPath]").description("sync builtin skill files to project").action(It);v.command("upgrade-v1 [projectPath]").description("upgrade webpack project to rspack").action(rr);v.command("login").option("--domain [domain]","login domain").option("-u --username [username]","login username").option("-p --password [password]","login user password").action(Nt);v.command("tunnel").option("-c --copy [letters...]","copy files").option("-i --input [dir]","input dir").option("-o --output [dir]","output dir,default cache").option("--no-server","no server").option("--resourcePort [number]","resource port").option("--ui","build ui").option("-r --rspack [file]","build ui rspack config file").option("--no-proxy","no proxy").option("-w --watch [paths...]","watch files change").action(Zt);v.command("deploy [filename]").option("-e --environment [environment]","app environment").action(bt);v.command("ui-dev").option("-r --rspack [file]","build ui rspack config file").action(tr);v.parse(process.argv);
File without changes
@@ -0,0 +1,28 @@
1
+ # {{appName}} 插件开发 Skill
2
+
3
+ 这个 Skill 面向插件研发与 AI 代理协作,目标是让 Agent 在当前插件仓库内稳定地完成:
4
+
5
+ - 功能实现(前端模块、trigger、webtrigger)
6
+ - API 适配(`/forge/` 到运行时路径的转换)
7
+ - 打包与发布(上传应用包、订阅到租户)
8
+
9
+ ## 目录
10
+
11
+ - `skill/guides/01-overview.md`:插件开发总览与实现约束
12
+ - `skill/guides/02-extension-points.md`:常见扩展点和模块声明方式
13
+ - `skill/guides/03-api-routing-rules.md`:`/forge/` 接口转换规则
14
+ - `skill/guides/04-deploy-and-subscribe.md`:上传与订阅流程(含 curl 模板)
15
+ - `skill/guides/05-agent-prompt-template.md`:给 Agent 的标准提问模板
16
+ - `skill/references/README.md`:平台文档全集参考
17
+
18
+ ## 使用方式
19
+
20
+ 1. 先阅读 `01-overview` 和 `02-extension-points`,明确本次插件能力边界。
21
+ 2. 涉及接口调用时,严格执行 `03-api-routing-rules`。
22
+ 3. 需要发布验证时,按 `04-deploy-and-subscribe` 执行。
23
+ 4. 需要让 Agent 批量生成代码时,使用 `05-agent-prompt-template`。
24
+
25
+ ## 项目标识
26
+
27
+ - 插件名称:`{{appName}}`
28
+ - 插件 Key:`{{appKey}}`
@@ -0,0 +1,23 @@
1
+ # 插件开发总览
2
+
3
+ ## 目标
4
+
5
+ 在保持可运行最小骨架的前提下,快速迭代插件能力,并保证以下交付完整:
6
+
7
+ - `manifest.yml` 能力声明完整
8
+ - 前端入口与路由可运行
9
+ - 后端 trigger/webtrigger 代码可调用
10
+ - 打包产物可上传并可被目标租户订阅
11
+
12
+ ## 默认技术约束
13
+
14
+ - 前端:`React + React Router + Ant Design`
15
+ - 后端:`trigger/*.ts` 与 `functions/*.ts` 按 manifest 声明
16
+ - 构建:`giteeteam-apps` + `rspack`(通过 `rspack.config.js` 扩展)
17
+
18
+ ## 目录建议
19
+
20
+ - `manifest.yml`:插件能力声明
21
+ - `src/`:前端代码
22
+ - `functions/` 或 `trigger/`:后端逻辑
23
+ - `skill/`:AI 协作规范、平台参考、发布流程
@@ -0,0 +1,20 @@
1
+ # 插件扩展点速查
2
+
3
+ 以下扩展点与字段定义建议以平台文档为准;实现前先对照文档确认字段合法性。
4
+
5
+ ## 常见模块
6
+
7
+ - `adminPage`
8
+ - `workspacePage`
9
+ - `itemPanel`
10
+ - `webtrigger`
11
+ - `trigger`
12
+ - `function`
13
+ - `resources`
14
+
15
+ ## 实现要求
16
+
17
+ 1. 每新增一个可执行逻辑,都要在 `modules.function` 声明 handler。
18
+ 2. 每新增一个前端页面模块,都要在 `resources` 中声明静态资源路径。
19
+ 3. `webtrigger` 与 `trigger` 的 key/function 必须一一对应。
20
+ 4. 修改模块定义后,优先执行构建并检查 manifest 校验报错。
@@ -0,0 +1,25 @@
1
+ # /forge/ 接口转换规则
2
+
3
+ `llms-full.txt` 中大量接口以 `/forge/` 开头。插件实现时必须按调用场景转换:
4
+
5
+ ## 前端调用(浏览器)
6
+
7
+ 当文档给出:
8
+
9
+ - `/forge/xxx`
10
+
11
+ 前端实际请求必须改为:
12
+
13
+ - `/api/team/parse/forge/xxx`
14
+
15
+ ## Trigger 调用(服务端)
16
+
17
+ 当在 trigger/webtrigger 里调用同类接口时,省略 `/api/team` 前缀:
18
+
19
+ - `/parse/forge/xxx` 或直接走项目内 parse client 对应能力
20
+
21
+ ## 统一约束
22
+
23
+ 1. 不要在前端直接请求裸 `/forge/*`。
24
+ 2. 抽一层 API client(例如 `src/services/api.ts`)统一做路径转换。
25
+ 3. 在 PR 描述中明确标注本次新增接口是否遵循该规则。
@@ -0,0 +1,28 @@
1
+ # 插件上传与订阅
2
+
3
+ 以下流程用于将本地构建产物上传到某环境,并订阅到指定租户。
4
+
5
+ ## 1) 上传插件包到环境
6
+
7
+ ```bash
8
+ curl 'http://<host>/apps/api/v1/apps/deploy' \
9
+ -H 'Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryxxxx' \
10
+ -b 'auth_session=<session>; team_tenant=<tenant>; sessionToken=<token>' \
11
+ --data-raw $'------WebKitFormBoundaryxxxx\r\nContent-Disposition: form-data; name="package"; filename="<appKey>_<version>.zip"\r\nContent-Type: application/zip\r\n\r\n\r\n------WebKitFormBoundaryxxxx\r\nContent-Disposition: form-data; name="environmentKey"\r\n\r\nproduction\r\n------WebKitFormBoundaryxxxx\r\nContent-Disposition: form-data; name="category"\r\n\r\nUser installed\r\n------WebKitFormBoundaryxxxx\r\nContent-Disposition: form-data; name="subscriptionSource"\r\n\r\nmanual\r\n------WebKitFormBoundaryxxxx--\r\n' \
12
+ --insecure
13
+ ```
14
+
15
+ ## 2) 订阅到租户(例如 osc)
16
+
17
+ ```bash
18
+ curl 'http://<host>/apps/api/v1/apps/install/batch' \
19
+ -H 'Content-Type: application/json' \
20
+ -b 'auth_session=<session>; team_tenant=<tenant>; sessionToken=<token>' \
21
+ --data-raw '{"tenants":["osc"],"environmentKey":"production","appKey":"<appKey>","versionKey":"<version>","subscriptionSource":"manual"}' \
22
+ --insecure
23
+ ```
24
+
25
+ ## 安全说明
26
+
27
+ 1. 不要提交真实 cookie/token 到仓库。
28
+ 2. 通过环境变量注入认证信息,避免硬编码到脚本。
@@ -0,0 +1,18 @@
1
+ # 给 Agent 的任务模板
2
+
3
+ ```text
4
+ 请在当前仓库实现/修改插件能力。
5
+ 插件名称:{{appName}}
6
+ 插件 key:{{appKey}}
7
+ 目标模块:<itemPanel/workspacePage/adminPage/webtrigger/trigger>
8
+ 核心功能:
9
+ 1. <功能 1>
10
+ 2. <功能 2>
11
+ 3. <功能 3>
12
+
13
+ 约束:
14
+ - manifest.yml 定义完整且可校验
15
+ - 前端接口遵循 /forge/ 路径转换规则
16
+ - trigger 与 webtrigger 的 function 声明完整
17
+ - 保留最小可运行骨架并补充必要注释
18
+ ```
@@ -0,0 +1,5 @@
1
+ # 参考资料
2
+
3
+ - `llms-full.txt`:平台官方文档全集(单文件版)
4
+ - 来源:`https://team.gitee.cn/llms-full.txt`
5
+ - 更新策略:按需人工同步,更新时记录日期与来源
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@giteeteam/apps-cli",
3
- "version": "0.8.18",
3
+ "version": "1.0.0-alpha.2",
4
4
  "description": "Giteeteam Apps cli",
5
5
  "keywords": [
6
6
  "typescript",
@@ -13,18 +13,19 @@
13
13
  "license": "ISC",
14
14
  "main": "./dist/index.js",
15
15
  "files": [
16
- "dist"
16
+ "dist",
17
+ "templates/skill"
17
18
  ],
18
19
  "scripts": {
19
- "build": "rm -rf dist && etsc",
20
- "lint": "npx eslint .",
20
+ "build": "rm -rf dist && etsc && mkdir -p dist/templates && cp -R templates/skill dist/templates/skill",
21
+ "lint": "npx eslint . --quiet --fix",
21
22
  "type-check": "tsc --pretty --noEmit",
22
23
  "precommit": "pnpm i && lint-staged && pnpm type-check",
23
24
  "publish:alpha": "npm publish --tag alpha",
24
25
  "prepack": "pnpm build",
25
- "unlink": "yarn unlink",
26
- "link": "chmod +x ./dist/index.js && yarn link && yarn link '@giteeteam/apps-cli' -g",
27
- "build-link": "pnpm build && yarn run link"
26
+ "unlink": "npm unlink -g @giteeteam/apps-cli",
27
+ "link": "chmod +x ./dist/index.js && npm link",
28
+ "build-link": "pnpm build && pnpm run link"
28
29
  },
29
30
  "lint-staged": {
30
31
  "*.{ts,js,json}": [
@@ -38,20 +39,18 @@
38
39
  "registry": "https://registry.npmjs.org/"
39
40
  },
40
41
  "dependencies": {
41
- "@ant-design/compatible": "^5.1.2",
42
42
  "@giteeteam/apps-manifest": "0.8.7",
43
- "@giteeteam/apps-team-theme": "^0.2.0",
44
- "@pmmmwh/react-refresh-webpack-plugin": "^0.5.10",
45
- "@rollup/plugin-commonjs": "^22.0.0",
43
+ "@rspack/core": "^2.0.0",
44
+ "@rspack/dev-middleware": "^2.0.1",
45
+ "@rspack/plugin-react-refresh": "^1.4.2",
46
+ "@rollup/plugin-commonjs": "^29.0.2",
46
47
  "archiver": "^5.3.1",
47
48
  "autoprefixer": "^10.4.20",
48
49
  "axios": "^1.13.6",
49
50
  "chalk": "^4.1.2",
50
51
  "chokidar": "^3.5.3",
51
- "clean-webpack-plugin": "^4.0.0",
52
52
  "commander": "^11.1.0",
53
53
  "cors": "^2.8.5",
54
- "css-minimizer-webpack-plugin": "^4.2.2",
55
54
  "debug": "^4.3.4",
56
55
  "dotenv": "^16.3.1",
57
56
  "esbuild": "^0.18.11",
@@ -60,18 +59,12 @@
60
59
  "form-data": "^4.0.0",
61
60
  "fs-extra": "^11.2.0",
62
61
  "hasha": "^5.2.2",
63
- "html-webpack-plugin": "^5.5.3",
64
62
  "inquirer": "^8.2.6",
65
63
  "localtunnel": "2.0.2",
66
64
  "lowdb": "1.0.0",
67
- "mini-css-extract-plugin": "^2.4.5",
68
65
  "ora": "^5.4.1",
69
66
  "rollup": "^3.29.4",
70
- "simple-git": "^3.19.1",
71
- "webpack": "^5.88.1",
72
- "webpack-bundle-analyzer": "^5.2.0",
73
- "webpack-dev-middleware": "^6.1.1",
74
- "webpack-merge": "^6.0.1"
67
+ "simple-git": "^3.19.1"
75
68
  },
76
69
  "devDependencies": {
77
70
  "@types/archiver": "^5.3.1",
@@ -87,8 +80,6 @@
87
80
  "typescript": "^5.9.3"
88
81
  },
89
82
  "peerDependencies": {
90
- "@ant-design/compatible": "^5.1.1",
91
- "@giteeteam/apps-team-theme": "^0.2.0",
92
83
  "antd": "^5.7.3",
93
84
  "classnames": "^2.3.2"
94
85
  },
@@ -0,0 +1,28 @@
1
+ # {{appName}} 插件开发 Skill
2
+
3
+ 这个 Skill 面向插件研发与 AI 代理协作,目标是让 Agent 在当前插件仓库内稳定地完成:
4
+
5
+ - 功能实现(前端模块、trigger、webtrigger)
6
+ - API 适配(`/forge/` 到运行时路径的转换)
7
+ - 打包与发布(上传应用包、订阅到租户)
8
+
9
+ ## 目录
10
+
11
+ - `skill/guides/01-overview.md`:插件开发总览与实现约束
12
+ - `skill/guides/02-extension-points.md`:常见扩展点和模块声明方式
13
+ - `skill/guides/03-api-routing-rules.md`:`/forge/` 接口转换规则
14
+ - `skill/guides/04-deploy-and-subscribe.md`:上传与订阅流程(含 curl 模板)
15
+ - `skill/guides/05-agent-prompt-template.md`:给 Agent 的标准提问模板
16
+ - `skill/references/README.md`:平台文档全集参考
17
+
18
+ ## 使用方式
19
+
20
+ 1. 先阅读 `01-overview` 和 `02-extension-points`,明确本次插件能力边界。
21
+ 2. 涉及接口调用时,严格执行 `03-api-routing-rules`。
22
+ 3. 需要发布验证时,按 `04-deploy-and-subscribe` 执行。
23
+ 4. 需要让 Agent 批量生成代码时,使用 `05-agent-prompt-template`。
24
+
25
+ ## 项目标识
26
+
27
+ - 插件名称:`{{appName}}`
28
+ - 插件 Key:`{{appKey}}`
@@ -0,0 +1,23 @@
1
+ # 插件开发总览
2
+
3
+ ## 目标
4
+
5
+ 在保持可运行最小骨架的前提下,快速迭代插件能力,并保证以下交付完整:
6
+
7
+ - `manifest.yml` 能力声明完整
8
+ - 前端入口与路由可运行
9
+ - 后端 trigger/webtrigger 代码可调用
10
+ - 打包产物可上传并可被目标租户订阅
11
+
12
+ ## 默认技术约束
13
+
14
+ - 前端:`React + React Router + Ant Design`
15
+ - 后端:`trigger/*.ts` 与 `functions/*.ts` 按 manifest 声明
16
+ - 构建:`giteeteam-apps` + `rspack`(通过 `rspack.config.js` 扩展)
17
+
18
+ ## 目录建议
19
+
20
+ - `manifest.yml`:插件能力声明
21
+ - `src/`:前端代码
22
+ - `functions/` 或 `trigger/`:后端逻辑
23
+ - `skill/`:AI 协作规范、平台参考、发布流程
@@ -0,0 +1,20 @@
1
+ # 插件扩展点速查
2
+
3
+ 以下扩展点与字段定义建议以平台文档为准;实现前先对照文档确认字段合法性。
4
+
5
+ ## 常见模块
6
+
7
+ - `adminPage`
8
+ - `workspacePage`
9
+ - `itemPanel`
10
+ - `webtrigger`
11
+ - `trigger`
12
+ - `function`
13
+ - `resources`
14
+
15
+ ## 实现要求
16
+
17
+ 1. 每新增一个可执行逻辑,都要在 `modules.function` 声明 handler。
18
+ 2. 每新增一个前端页面模块,都要在 `resources` 中声明静态资源路径。
19
+ 3. `webtrigger` 与 `trigger` 的 key/function 必须一一对应。
20
+ 4. 修改模块定义后,优先执行构建并检查 manifest 校验报错。
@@ -0,0 +1,25 @@
1
+ # /forge/ 接口转换规则
2
+
3
+ `llms-full.txt` 中大量接口以 `/forge/` 开头。插件实现时必须按调用场景转换:
4
+
5
+ ## 前端调用(浏览器)
6
+
7
+ 当文档给出:
8
+
9
+ - `/forge/xxx`
10
+
11
+ 前端实际请求必须改为:
12
+
13
+ - `/api/team/parse/forge/xxx`
14
+
15
+ ## Trigger 调用(服务端)
16
+
17
+ 当在 trigger/webtrigger 里调用同类接口时,省略 `/api/team` 前缀:
18
+
19
+ - `/parse/forge/xxx` 或直接走项目内 parse client 对应能力
20
+
21
+ ## 统一约束
22
+
23
+ 1. 不要在前端直接请求裸 `/forge/*`。
24
+ 2. 抽一层 API client(例如 `src/services/api.ts`)统一做路径转换。
25
+ 3. 在 PR 描述中明确标注本次新增接口是否遵循该规则。
@@ -0,0 +1,28 @@
1
+ # 插件上传与订阅
2
+
3
+ 以下流程用于将本地构建产物上传到某环境,并订阅到指定租户。
4
+
5
+ ## 1) 上传插件包到环境
6
+
7
+ ```bash
8
+ curl 'http://<host>/apps/api/v1/apps/deploy' \
9
+ -H 'Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryxxxx' \
10
+ -b 'auth_session=<session>; team_tenant=<tenant>; sessionToken=<token>' \
11
+ --data-raw $'------WebKitFormBoundaryxxxx\r\nContent-Disposition: form-data; name="package"; filename="<appKey>_<version>.zip"\r\nContent-Type: application/zip\r\n\r\n\r\n------WebKitFormBoundaryxxxx\r\nContent-Disposition: form-data; name="environmentKey"\r\n\r\nproduction\r\n------WebKitFormBoundaryxxxx\r\nContent-Disposition: form-data; name="category"\r\n\r\nUser installed\r\n------WebKitFormBoundaryxxxx\r\nContent-Disposition: form-data; name="subscriptionSource"\r\n\r\nmanual\r\n------WebKitFormBoundaryxxxx--\r\n' \
12
+ --insecure
13
+ ```
14
+
15
+ ## 2) 订阅到租户(例如 osc)
16
+
17
+ ```bash
18
+ curl 'http://<host>/apps/api/v1/apps/install/batch' \
19
+ -H 'Content-Type: application/json' \
20
+ -b 'auth_session=<session>; team_tenant=<tenant>; sessionToken=<token>' \
21
+ --data-raw '{"tenants":["osc"],"environmentKey":"production","appKey":"<appKey>","versionKey":"<version>","subscriptionSource":"manual"}' \
22
+ --insecure
23
+ ```
24
+
25
+ ## 安全说明
26
+
27
+ 1. 不要提交真实 cookie/token 到仓库。
28
+ 2. 通过环境变量注入认证信息,避免硬编码到脚本。
@@ -0,0 +1,18 @@
1
+ # 给 Agent 的任务模板
2
+
3
+ ```text
4
+ 请在当前仓库实现/修改插件能力。
5
+ 插件名称:{{appName}}
6
+ 插件 key:{{appKey}}
7
+ 目标模块:<itemPanel/workspacePage/adminPage/webtrigger/trigger>
8
+ 核心功能:
9
+ 1. <功能 1>
10
+ 2. <功能 2>
11
+ 3. <功能 3>
12
+
13
+ 约束:
14
+ - manifest.yml 定义完整且可校验
15
+ - 前端接口遵循 /forge/ 路径转换规则
16
+ - trigger 与 webtrigger 的 function 声明完整
17
+ - 保留最小可运行骨架并补充必要注释
18
+ ```
@@ -0,0 +1,5 @@
1
+ # 参考资料
2
+
3
+ - `llms-full.txt`:平台官方文档全集(单文件版)
4
+ - 来源:`https://team.gitee.cn/llms-full.txt`
5
+ - 更新策略:按需人工同步,更新时记录日期与来源