@miracleplus/mplus 0.1.4 → 0.1.6

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/dist/oauth.js ADDED
@@ -0,0 +1 @@
1
+ 'use strict';const _0x4c0ed3=_0x186c;(function(_0x23a4dc,_0x163e06){const _0x2557e9=_0x186c,_0x1a50df=_0x23a4dc();while(!![]){try{const _0x32ca6d=-parseInt(_0x2557e9(0x180))/0x1*(parseInt(_0x2557e9(0x1e0))/0x2)+parseInt(_0x2557e9(0x1bf))/0x3+parseInt(_0x2557e9(0x1c9))/0x4*(parseInt(_0x2557e9(0x1cc))/0x5)+-parseInt(_0x2557e9(0x1ee))/0x6*(-parseInt(_0x2557e9(0x1df))/0x7)+-parseInt(_0x2557e9(0x194))/0x8*(parseInt(_0x2557e9(0x1c1))/0x9)+parseInt(_0x2557e9(0x18f))/0xa*(-parseInt(_0x2557e9(0x196))/0xb)+parseInt(_0x2557e9(0x1a4))/0xc;if(_0x32ca6d===_0x163e06)break;else _0x1a50df['push'](_0x1a50df['shift']());}catch(_0x4a8ee1){_0x1a50df['push'](_0x1a50df['shift']());}}}(_0x7c22,0x5d671));var __createBinding=this&&this[_0x4c0ed3(0x1ae)]||(Object[_0x4c0ed3(0x192)]?function(_0x117ded,_0xd167fc,_0x271b73,_0x23e05a){const _0x1e25e5=_0x4c0ed3;if(_0x23e05a===undefined)_0x23e05a=_0x271b73;var _0x1c21db=Object[_0x1e25e5(0x198)](_0xd167fc,_0x271b73);(!_0x1c21db||(_0x1e25e5(0x1d5)in _0x1c21db?!_0xd167fc['__esModule']:_0x1c21db['writable']||_0x1c21db[_0x1e25e5(0x1af)]))&&(_0x1c21db={'enumerable':!![],'get':function(){return _0xd167fc[_0x271b73];}}),Object[_0x1e25e5(0x1d0)](_0x117ded,_0x23e05a,_0x1c21db);}:function(_0x1c69ab,_0x1fcc52,_0x3d7b35,_0x308e4a){if(_0x308e4a===undefined)_0x308e4a=_0x3d7b35;_0x1c69ab[_0x308e4a]=_0x1fcc52[_0x3d7b35];}),__setModuleDefault=this&&this[_0x4c0ed3(0x197)]||(Object['create']?function(_0x35d7ef,_0x3fa8a7){const _0x1f5c94=_0x4c0ed3;Object[_0x1f5c94(0x1d0)](_0x35d7ef,'default',{'enumerable':!![],'value':_0x3fa8a7});}:function(_0x59a358,_0x3375e5){_0x59a358['default']=_0x3375e5;}),__importStar=this&&this[_0x4c0ed3(0x1a0)]||(function(){var _0x131c07=function(_0x374a4e){const _0x54f913=_0x186c;return _0x131c07=Object[_0x54f913(0x1a3)]||function(_0x9474ee){const _0x194875=_0x54f913;var _0x50f558=[];for(var _0x345597 in _0x9474ee)if(Object[_0x194875(0x1cb)][_0x194875(0x18c)][_0x194875(0x1a8)](_0x9474ee,_0x345597))_0x50f558[_0x50f558['length']]=_0x345597;return _0x50f558;},_0x131c07(_0x374a4e);};return function(_0x22121c){const _0xd9e52b=_0x186c;if(_0x22121c&&_0x22121c[_0xd9e52b(0x1c3)])return _0x22121c;var _0x4a4c6b={};if(_0x22121c!=null){for(var _0x40b33e=_0x131c07(_0x22121c),_0xbe4f63=0x0;_0xbe4f63<_0x40b33e['length'];_0xbe4f63++)if(_0x40b33e[_0xbe4f63]!==_0xd9e52b(0x1bc))__createBinding(_0x4a4c6b,_0x22121c,_0x40b33e[_0xbe4f63]);}return __setModuleDefault(_0x4a4c6b,_0x22121c),_0x4a4c6b;};}()),__importDefault=this&&this[_0x4c0ed3(0x19c)]||function(_0x2bd9c6){const _0x9b3172=_0x4c0ed3;return _0x2bd9c6&&_0x2bd9c6[_0x9b3172(0x1c3)]?_0x2bd9c6:{'default':_0x2bd9c6};};Object[_0x4c0ed3(0x1d0)](exports,'__esModule',{'value':!![]}),exports[_0x4c0ed3(0x1a7)]=loginWithOAuth,exports['isOAuthAccessTokenFresh']=isOAuthAccessTokenFresh,exports['refreshOAuthSession']=refreshOAuthSession,exports[_0x4c0ed3(0x1d4)]=getValidOAuthAccessToken;const axios_1=__importDefault(require(_0x4c0ed3(0x19a))),crypto=__importStar(require(_0x4c0ed3(0x1d6))),http=__importStar(require(_0x4c0ed3(0x1e5))),url_1=require('url'),child_process_1=require(_0x4c0ed3(0x1b3)),config_1=require(_0x4c0ed3(0x199));function base64Url(_0x30eb75){const _0x2a8bb6=_0x4c0ed3;return _0x30eb75[_0x2a8bb6(0x1c8)](_0x2a8bb6(0x1ed))['replace'](/\+/g,'-')[_0x2a8bb6(0x191)](/\//g,'_')['replace'](/=+$/g,'');}function randomBase64Url(_0x506493=0x20){const _0x58baf1=_0x4c0ed3;return base64Url(crypto[_0x58baf1(0x18b)](_0x506493));}function createCodeChallenge(_0x59510e){const _0x4af8e2=_0x4c0ed3;return base64Url(crypto[_0x4af8e2(0x184)]('sha256')[_0x4af8e2(0x1e3)](_0x59510e)['digest']());}function normalizeEndpoint(_0x111704){return _0x111704['replace'](/\/$/,'');}function openUrl(_0x7beef6){const _0x4fe6db=_0x4c0ed3,_0x297ceb=process[_0x4fe6db(0x1d3)],_0x883e7a=_0x297ceb===_0x4fe6db(0x1cf)?_0x4fe6db(0x1e1):_0x297ceb==='win32'?_0x4fe6db(0x17e):_0x4fe6db(0x1de),_0x1ed015=_0x297ceb===_0x4fe6db(0x1c0)?['/c',_0x4fe6db(0x1b1),'',_0x7beef6]:[_0x7beef6],_0x3aba6d=(0x0,child_process_1[_0x4fe6db(0x1b6)])(_0x883e7a,_0x1ed015,{'stdio':'ignore','detached':!![]});_0x3aba6d[_0x4fe6db(0x1a9)]();}function listenForCallback(_0x3e0b3d,_0x45c259){const _0xf5a3fb=_0x4c0ed3,_0x3603d9=new url_1[(_0xf5a3fb(0x1ac))](_0x3e0b3d),_0x5e0ab6=Number(_0x3603d9[_0xf5a3fb(0x1ef)]||(_0x3603d9[_0xf5a3fb(0x1ce)]==='https:'?0x1bb:0x50)),_0x12c05b=_0x3603d9[_0xf5a3fb(0x1e7)];if(![_0xf5a3fb(0x1a1),'localhost'][_0xf5a3fb(0x18d)](_0x3603d9[_0xf5a3fb(0x18a)]))throw new Error(_0xf5a3fb(0x1f1));return new Promise((_0x428551,_0x1d3a4c)=>{const _0x2621aa=_0xf5a3fb,_0x503ae0=setTimeout(()=>{_0x19c282['close'](),_0x1d3a4c(new Error('等待浏览器授权超时,请重新运行\x20mplus\x20login'));},0x5*0x3c*0x3e8),_0x19c282=http[_0x2621aa(0x17f)]((_0x2b0030,_0x56a1f6)=>{const _0x2531cd=_0x2621aa;try{const _0x21f324=new url_1[(_0x2531cd(0x1ac))](_0x2b0030[_0x2531cd(0x1b2)]??'/',_0x3e0b3d);if(_0x21f324[_0x2531cd(0x1e7)]!==_0x12c05b){_0x56a1f6[_0x2531cd(0x177)](0x194,{'Content-Type':'text/plain;\x20charset=utf-8'}),_0x56a1f6['end'](_0x2531cd(0x176));return;}const _0x340f6d=_0x21f324['searchParams'][_0x2531cd(0x1d5)]('error');if(_0x340f6d){const _0x3b8235=_0x21f324[_0x2531cd(0x1ca)][_0x2531cd(0x1d5)](_0x2531cd(0x1be))??_0x340f6d;_0x56a1f6[_0x2531cd(0x177)](0x190,{'Content-Type':_0x2531cd(0x195)}),_0x56a1f6[_0x2531cd(0x186)](_0x2531cd(0x1b9)+_0x3b8235+'</p>'),clearTimeout(_0x503ae0),_0x19c282[_0x2531cd(0x1d7)](),_0x1d3a4c(new Error('OAuth\x20授权失败:'+_0x3b8235));return;}const _0x576643=_0x21f324[_0x2531cd(0x1ca)][_0x2531cd(0x1d5)]('state');if(_0x576643!==_0x45c259){_0x56a1f6['writeHead'](0x190,{'Content-Type':_0x2531cd(0x195)}),_0x56a1f6[_0x2531cd(0x186)]('<h1>授权失败</h1><p>state\x20校验失败,请回到终端重新登录。</p>'),clearTimeout(_0x503ae0),_0x19c282[_0x2531cd(0x1d7)](),_0x1d3a4c(new Error(_0x2531cd(0x1eb)));return;}const _0x5e7b7a=_0x21f324[_0x2531cd(0x1ca)][_0x2531cd(0x1d5)]('code');if(!_0x5e7b7a){_0x56a1f6[_0x2531cd(0x177)](0x190,{'Content-Type':_0x2531cd(0x195)}),_0x56a1f6['end'](_0x2531cd(0x1dc)),clearTimeout(_0x503ae0),_0x19c282[_0x2531cd(0x1d7)](),_0x1d3a4c(new Error(_0x2531cd(0x1f0)));return;}_0x56a1f6[_0x2531cd(0x177)](0xc8,{'Content-Type':_0x2531cd(0x195)}),_0x56a1f6[_0x2531cd(0x186)](_0x2531cd(0x193)),clearTimeout(_0x503ae0),_0x19c282[_0x2531cd(0x1d7)](),_0x428551(_0x5e7b7a);}catch(_0x3cb6b3){clearTimeout(_0x503ae0),_0x19c282['close'](),_0x1d3a4c(_0x3cb6b3);}});_0x19c282['on'](_0x2621aa(0x1c7),_0x55fadb=>{clearTimeout(_0x503ae0),_0x1d3a4c(_0x55fadb);}),_0x19c282[_0x2621aa(0x17a)](_0x5e0ab6,_0x3603d9['hostname']);});}async function exchangeCodeForToken(_0x264b57,_0x5e5232,_0x22da23,_0x4aa6de,_0x9c264){const _0x2c98f3=_0x4c0ed3,_0x3eb702=normalizeEndpoint(_0x264b57)+_0x2c98f3(0x1bb),_0xd195c6=new url_1[(_0x2c98f3(0x1c4))]({'grant_type':_0x2c98f3(0x17c),'client_id':_0x5e5232,'redirect_uri':_0x22da23,'code':_0x4aa6de,'code_verifier':_0x9c264}),_0x52b19d=await axios_1[_0x2c98f3(0x1bc)][_0x2c98f3(0x1a2)](_0x3eb702,_0xd195c6[_0x2c98f3(0x1c8)](),{'headers':{'Content-Type':'application/x-www-form-urlencoded','Accept':_0x2c98f3(0x1d9)},'timeout':0x3a98});return _0x52b19d['data'];}function _0x186c(_0x1e15be,_0x195d45){_0x1e15be=_0x1e15be-0x176;const _0x7c220a=_0x7c22();let _0x186ca0=_0x7c220a[_0x1e15be];if(_0x186c['fYRQqO']===undefined){var _0x1274bc=function(_0x4bb89a){const _0x3b2f6a='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let _0x117ded='',_0xd167fc='';for(let _0x271b73=0x0,_0x23e05a,_0x1c21db,_0x1c69ab=0x0;_0x1c21db=_0x4bb89a['charAt'](_0x1c69ab++);~_0x1c21db&&(_0x23e05a=_0x271b73%0x4?_0x23e05a*0x40+_0x1c21db:_0x1c21db,_0x271b73++%0x4)?_0x117ded+=String['fromCharCode'](0xff&_0x23e05a>>(-0x2*_0x271b73&0x6)):0x0){_0x1c21db=_0x3b2f6a['indexOf'](_0x1c21db);}for(let _0x1fcc52=0x0,_0x3d7b35=_0x117ded['length'];_0x1fcc52<_0x3d7b35;_0x1fcc52++){_0xd167fc+='%'+('00'+_0x117ded['charCodeAt'](_0x1fcc52)['toString'](0x10))['slice'](-0x2);}return decodeURIComponent(_0xd167fc);};_0x186c['qQnOVk']=_0x1274bc,_0x186c['guEeOc']={},_0x186c['fYRQqO']=!![];}const _0x2f5928=_0x7c220a[0x0],_0x82dc3e=_0x1e15be+_0x2f5928,_0x1a789b=_0x186c['guEeOc'][_0x82dc3e];return!_0x1a789b?(_0x186ca0=_0x186c['qQnOVk'](_0x186ca0),_0x186c['guEeOc'][_0x82dc3e]=_0x186ca0):_0x186ca0=_0x1a789b,_0x186ca0;}async function exchangeRefreshToken(_0x54949d){const _0x1e269d=_0x4c0ed3;if(!_0x54949d[_0x1e269d(0x1da)])throw new Error(_0x1e269d(0x185));const _0x5635a0=new url_1[(_0x1e269d(0x1c4))]({'grant_type':'refresh_token','client_id':_0x54949d[_0x1e269d(0x1cd)],'refresh_token':_0x54949d['refresh_token']}),_0x563bf0=await axios_1[_0x1e269d(0x1bc)][_0x1e269d(0x1a2)](normalizeEndpoint(_0x54949d[_0x1e269d(0x19e)])+_0x1e269d(0x1bb),_0x5635a0['toString'](),{'headers':{'Content-Type':'application/x-www-form-urlencoded','Accept':_0x1e269d(0x1d9)},'timeout':0x3a98});return _0x563bf0['data'];}async function fetchUserInfo(_0x43b88e,_0x338a97){const _0x36e782=_0x4c0ed3,_0x169402=await axios_1[_0x36e782(0x1bc)][_0x36e782(0x1d5)](normalizeEndpoint(_0x43b88e)+_0x36e782(0x1c5),{'headers':{'Authorization':_0x36e782(0x1ea)+_0x338a97,'Accept':_0x36e782(0x1d9)},'timeout':0x3a98});return _0x169402[_0x36e782(0x187)];}function buildSessionFromToken(_0x485ac6,_0x33e19e,_0x3f1aeb){const _0x2c8cb8=_0x4c0ed3,_0x341489=_0x33e19e[_0x2c8cb8(0x19f)]?new Date(Date[_0x2c8cb8(0x1b0)]()+_0x33e19e[_0x2c8cb8(0x19f)]*0x3e8)[_0x2c8cb8(0x1e4)]():undefined;return{..._0x485ac6,'scope':_0x33e19e['scope']??_0x485ac6[_0x2c8cb8(0x1aa)],'access_token':_0x33e19e[_0x2c8cb8(0x1e6)],..._0x33e19e[_0x2c8cb8(0x1da)]?{'refresh_token':_0x33e19e['refresh_token']}:{},'token_type':_0x33e19e['token_type']??'Bearer',..._0x341489?{'token_expires_at':_0x341489}:{},..._0x3f1aeb?{'user':{'id':_0x3f1aeb['sub'],..._0x3f1aeb[_0x2c8cb8(0x1e8)]?{'name':_0x3f1aeb[_0x2c8cb8(0x1e8)]}:{},..._0x3f1aeb[_0x2c8cb8(0x189)]?{'email':_0x3f1aeb['email']}:{},'roles':_0x3f1aeb[_0x2c8cb8(0x1bd)]??[]}}:{},'logged_in_at':new Date()['toISOString']()};}async function loginWithOAuth(_0x6705c5){const _0x1541aa=_0x4c0ed3,_0x4256f4=normalizeEndpoint(_0x6705c5[_0x1541aa(0x19e)]),_0x44b21f=randomBase64Url(0x18),_0x254444=randomBase64Url(0x30),_0xc401a9=createCodeChallenge(_0x254444),_0x2154cb=new url_1[(_0x1541aa(0x1ac))](_0x4256f4+_0x1541aa(0x1dd));_0x2154cb[_0x1541aa(0x1ca)]['set'](_0x1541aa(0x1cd),_0x6705c5[_0x1541aa(0x1c6)]),_0x2154cb['searchParams'][_0x1541aa(0x1ab)](_0x1541aa(0x1ad),_0x6705c5[_0x1541aa(0x19b)]),_0x2154cb[_0x1541aa(0x1ca)][_0x1541aa(0x1ab)](_0x1541aa(0x1a6),_0x1541aa(0x183)),_0x2154cb[_0x1541aa(0x1ca)]['set']('scope',_0x6705c5['scope']),_0x2154cb['searchParams'][_0x1541aa(0x1ab)](_0x1541aa(0x179),_0x44b21f),_0x2154cb[_0x1541aa(0x1ca)][_0x1541aa(0x1ab)](_0x1541aa(0x1d8),_0xc401a9),_0x2154cb[_0x1541aa(0x1ca)][_0x1541aa(0x1ab)](_0x1541aa(0x1ba),'S256');const _0x2ce062=listenForCallback(_0x6705c5[_0x1541aa(0x19b)],_0x44b21f);console[_0x1541aa(0x1c2)](_0x1541aa(0x1e2)+_0x2154cb['toString']()+'\x0a');_0x6705c5[_0x1541aa(0x17b)]?openUrl(_0x2154cb[_0x1541aa(0x1c8)]()):console[_0x1541aa(0x1c2)](_0x1541aa(0x182));const _0x143e7f=await _0x2ce062;process[_0x1541aa(0x1b5)][_0x1541aa(0x181)]('已收到授权码,正在换取\x20access\x20token...\x0a');const _0x31f61a=await exchangeCodeForToken(_0x4256f4,_0x6705c5[_0x1541aa(0x1c6)],_0x6705c5[_0x1541aa(0x19b)],_0x143e7f,_0x254444);process['stdout'][_0x1541aa(0x181)](_0x1541aa(0x1ec));let _0x383b51;try{_0x383b51=await fetchUserInfo(_0x4256f4,_0x31f61a[_0x1541aa(0x1e6)]);}catch(_0x1c30d2){const _0x30bc75=axios_1[_0x1541aa(0x1bc)]['isAxiosError'](_0x1c30d2)?_0x1541aa(0x178)+(_0x1c30d2[_0x1541aa(0x1d1)]?.[_0x1541aa(0x1db)]??_0x1c30d2[_0x1541aa(0x183)]??_0x1541aa(0x1a5)):_0x1c30d2 instanceof Error?_0x1c30d2['message']:String(_0x1c30d2);process[_0x1541aa(0x1b8)]['write'](_0x1541aa(0x190)+_0x30bc75+_0x1541aa(0x1d2));}const _0x21ef7f=buildSessionFromToken({'endpoint':_0x4256f4,'client_id':_0x6705c5[_0x1541aa(0x1c6)],'redirect_uri':_0x6705c5[_0x1541aa(0x19b)],'scope':_0x6705c5['scope']},_0x31f61a,_0x383b51);return(0x0,config_1['saveOAuthSession'])(_0x6705c5[_0x1541aa(0x19d)],_0x21ef7f),_0x21ef7f;}function isOAuthAccessTokenFresh(_0x13af44,_0x49ca8b=0x3c){const _0x340784=_0x4c0ed3;if(!_0x13af44[_0x340784(0x1e9)])return!![];return new Date(_0x13af44[_0x340784(0x1e9)])['getTime']()-Date['now']()>_0x49ca8b*0x3e8;}function _0x7c22(){const _0xfb0fa=['6k+35zYO5Rwp6kEi5zMO5lIT5A6m5OIqie1qioEzU+w9LEAoIoADG++8MGO','DxbKyxrL','Dg9ju09tDhjPBMC','Ahr0Ca','ywnJzxnZx3rVA2vU','Cgf0Ag5HBwu','BMfTzq','Dg9Rzw5FzxHWAxjLC19HDa','qMvHCMvYia','t0f1DgGGC3rHDguG5QcH6AQm5AsX6lsL','qwnJzxnZihrVA2vUiow3SUIoT+wpLU+8JoATO+wCQowWNEIVLEIoT+wpLUEuQoAiT+s/OEAbRY4UlGO','yMfZzty0','mtH6txLStMK','Cg9YDa','t0f1DgGG5zUE6lcd5lIT57Y65BcrignVzgu','CMvKAxjLy3rFDxjPiow/HEMHU+AyRYbSB2nHBgHVC3qG5OIwideYnY4WlJaUmq','tM90iezVDw5K','D3jPDgvizwfK','sfruuca','C3rHDgu','BgLZDgvU','B3bLBKjYB3DZzxi','yxv0Ag9YAxPHDgLVBL9JB2rL','5PYQ5OM+5yIWie9bDxrOihnLC3nPB27VViZOR7FLHyJOV5dOOyWGBxbSDxmGBg9NAw4','y21K','y3jLyxrLu2vYDMvY','ode4ugLpBuHw','D3jPDgu','5BEY56Ab55sO6iEQ5yQO5OMt5BYa5Rwp6kEi5zMO77Ym6k+35OMl5yQO5Asn5yI25lIk6z2I55Qe5zYW5z2a6k6/6zEU44cc','y29Kzq','y3jLyxrLsgfZAa','5B2t5yMnie9bDxrOihnLC3nPB24G5RkH5PYjihjLzNjLC2HFDg9Rzw7VViZOR7FPH43MLRdOV5dOOyWGBxbSDxmGBg9NAw4','zw5K','zgf0yq','C2vZC2LVBG','zw1HAwW','Ag9ZDg5HBwu','CMfUzg9TqNL0zxm','AgfZt3DUuhjVCgvYDhK','Aw5JBhvKzxm','z2v0t0f1DgHtzxnZAw9U','mZCXntK1mgXkDwvIra','4PQGioACQUIdVEIoT+wpLUEuQoAiT+s/OEAbR++8Ia','CMvWBgfJzq','y3jLyxrL','pgGXpUEzU+w9LEAiKowkNZWVAde+pha+5l2G5y+V5lUL5ywZ6zET6l+z5lIQ6Ag16z2I77Ym5zUE5yIW57Ui56UV57UN57UT5l2/55sOig1WBhvZ44ccpc9WpG','mJK2wgzkCNP4','Dgv4Dc9ODg1SoYbJAgfYC2v0pxv0zI04','mtfkvhbWu08','x19ZzxrnB2r1BgvezwzHDwX0','z2v0t3DUuhjVCgvYDhLezxnJCMLWDg9Y','lI9JB25MAwC','yxHPB3m','CMvKAxjLy3rvCMK','x19PBxbVCNrezwzHDwX0','C2vZC2LVBK5HBwu','zw5KCg9PBNq','zxHWAxjLC19PBG','x19PBxbVCNrtDgfY','mti3lJaUmc4X','Cg9ZDa','z2v0t3DUuhjVCgvYDhLoyw1LCW','mteXntCXndrzswvlEw4','Dw5RBM93BG','CMvZCg9UC2vFDhLWzq','Bg9NAw5xAxrOt0f1DgG','y2fSBa','Dw5Yzwy','C2nVCgu','C2v0','vvjm','CMvKAxjLy3rFDxjP','x19JCMvHDgvcAw5KAw5N','y29UzMLNDxjHyMXL','BM93','C3rHCNq','DxjS','y2HPBgrFChjVy2vZCW','DxnLCG','C3rKB3v0','C3bHD24','C2f2zu9bDxrOu2vZC2LVBG','C3rKzxjY','pgGXpUAoIoADG+wKSEI0PtWVAde+pha+','y29Kzv9JAgfSBgvUz2vFBwv0Ag9K','l29HDxrOl3rVA2vU','zgvMyxvSDa','CM9Szxm','zxjYB3jFzgvZy3jPChrPB24','mZK1mtaWtvfPt1LM','D2LUmZi','mtu1mZeZt3HethHv','Bg9N','x19LC01VzhvSzq','vvjmu2vHCMnOugfYyw1Z','l29HDxrOl3vZzxjPBMzV','y2XPzw50swq','zxjYB3i','Dg9tDhjPBMC','mJHQCK1yA3y','C2vHCMnOugfYyw1Z','ChjVDg90ExbL','mZG5odq1Bhn4vMn6','y2XPzw50x2LK','ChjVDg9JB2W','zgfYD2LU','zgvMAw5LuhjVCgvYDhK','CMvZCg9UC2u','77Yj77Ym5l2gigfJy2vZCYb0B2TLBIdLT7lKV53LRzJVViZLJ6/NLkJKUO7LKi7NU60GqvbjioIVT+AXGUoaGGO','CgXHDgzVCM0','z2v0vMfSAwrpqxv0AefJy2vZC1rVA2vU','z2v0','y3j5ChrV','y2XVC2u','y29Kzv9JAgfSBgvUz2u','yxbWBgLJyxrPB24VANnVBG','CMvMCMvZAf90B2TLBG','C3rHDhvZ','pgGXpUAoIoADG+wKSEI0PtWVAde+pha+5zUE6lcd5lIT57Y65BcrignVzgxJGii8l3a+','l29HDxrOl2f1DgHVCML6zq','EgrNlw9Wzw4','nZu3mtyYDuLftK1Z','mtmXoefKz3DZta','B3bLBG'];_0x7c22=function(){return _0xfb0fa;};return _0x7c22();}async function refreshOAuthSession(_0x482f2e){const _0x57788b=_0x4c0ed3,_0x584eff=(0x0,config_1['getOAuthSession'])(_0x482f2e);if(!_0x584eff)throw new Error(_0x57788b(0x17d));const _0x53e0bc=await exchangeRefreshToken(_0x584eff['session']),_0x2f1d6f={..._0x584eff[_0x57788b(0x188)],...buildSessionFromToken({'endpoint':_0x584eff['session'][_0x57788b(0x19e)],'client_id':_0x584eff[_0x57788b(0x188)][_0x57788b(0x1cd)],'redirect_uri':_0x584eff[_0x57788b(0x188)]['redirect_uri'],'scope':_0x584eff['session'][_0x57788b(0x1aa)]},_0x53e0bc,_0x584eff[_0x57788b(0x188)]['user']?{'sub':_0x584eff[_0x57788b(0x188)][_0x57788b(0x1b4)]['id'],'name':_0x584eff['session'][_0x57788b(0x1b4)]['name'],'email':_0x584eff[_0x57788b(0x188)][_0x57788b(0x1b4)][_0x57788b(0x189)],'roles':_0x584eff[_0x57788b(0x188)][_0x57788b(0x1b4)][_0x57788b(0x1bd)]}:undefined),'refresh_token':_0x53e0bc[_0x57788b(0x1da)]??_0x584eff[_0x57788b(0x188)][_0x57788b(0x1da)]};return(0x0,config_1[_0x57788b(0x1b7)])(_0x584eff[_0x57788b(0x1e8)],_0x2f1d6f),_0x2f1d6f;}async function getValidOAuthAccessToken(_0x3002e6){const _0x775c7e=_0x4c0ed3,_0x53b9e8=(0x0,config_1[_0x775c7e(0x18e)])(_0x3002e6);if(!_0x53b9e8)throw new Error(_0x775c7e(0x17d));if(isOAuthAccessTokenFresh(_0x53b9e8[_0x775c7e(0x188)]))return _0x53b9e8[_0x775c7e(0x188)][_0x775c7e(0x1e6)];const _0x580b49=await refreshOAuthSession(_0x53b9e8['name']);return _0x580b49[_0x775c7e(0x1e6)];}
@@ -0,0 +1 @@
1
+ 'use strict';function _0x2efc(_0x36f0cb,_0x34e9db){_0x36f0cb=_0x36f0cb-0x115;const _0x8b4c39=_0x8b4c();let _0x2efc8f=_0x8b4c39[_0x36f0cb];if(_0x2efc['NlGIsW']===undefined){var _0x3375d7=function(_0x372d3f){const _0x531bbc='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let _0x590411='',_0x23ec8a='';for(let _0x333897=0x0,_0x30683f,_0x208f8f,_0x445a24=0x0;_0x208f8f=_0x372d3f['charAt'](_0x445a24++);~_0x208f8f&&(_0x30683f=_0x333897%0x4?_0x30683f*0x40+_0x208f8f:_0x208f8f,_0x333897++%0x4)?_0x590411+=String['fromCharCode'](0xff&_0x30683f>>(-0x2*_0x333897&0x6)):0x0){_0x208f8f=_0x531bbc['indexOf'](_0x208f8f);}for(let _0x218f5d=0x0,_0x385e35=_0x590411['length'];_0x218f5d<_0x385e35;_0x218f5d++){_0x23ec8a+='%'+('00'+_0x590411['charCodeAt'](_0x218f5d)['toString'](0x10))['slice'](-0x2);}return decodeURIComponent(_0x23ec8a);};_0x2efc['NUVagW']=_0x3375d7,_0x2efc['lyiGZz']={},_0x2efc['NlGIsW']=!![];}const _0x3656f2=_0x8b4c39[0x0],_0x13700a=_0x36f0cb+_0x3656f2,_0x30c9f5=_0x2efc['lyiGZz'][_0x13700a];return!_0x30c9f5?(_0x2efc8f=_0x2efc['NUVagW'](_0x2efc8f),_0x2efc['lyiGZz'][_0x13700a]=_0x2efc8f):_0x2efc8f=_0x30c9f5,_0x2efc8f;}const _0x199ff3=_0x2efc;(function(_0x3bb5d4,_0x3af209){const _0x3c02aa=_0x2efc,_0x56a8c7=_0x3bb5d4();while(!![]){try{const _0x2cd1c4=parseInt(_0x3c02aa(0x12e))/0x1*(-parseInt(_0x3c02aa(0x11b))/0x2)+parseInt(_0x3c02aa(0x12f))/0x3+parseInt(_0x3c02aa(0x11e))/0x4*(-parseInt(_0x3c02aa(0x11a))/0x5)+parseInt(_0x3c02aa(0x12c))/0x6+-parseInt(_0x3c02aa(0x136))/0x7+-parseInt(_0x3c02aa(0x120))/0x8*(-parseInt(_0x3c02aa(0x133))/0x9)+-parseInt(_0x3c02aa(0x123))/0xa*(parseInt(_0x3c02aa(0x11f))/0xb);if(_0x2cd1c4===_0x3af209)break;else _0x56a8c7['push'](_0x56a8c7['shift']());}catch(_0x3a4841){_0x56a8c7['push'](_0x56a8c7['shift']());}}}(_0x8b4c,0x5e5dd));var __importDefault=this&&this[_0x199ff3(0x11d)]||function(_0x590411){return _0x590411&&_0x590411['__esModule']?_0x590411:{'default':_0x590411};};function _0x8b4c(){const _0x87c601=['tvbmvvnFqvbjx0DbvevxqvLFru5eue9jtLq','mJG4mtC4mLvsBNLSwG','y3jLyxrL','CMvZCg9UC2u','mJmZmdCYqvPVBgXk','yxbWBgLJyxrPB24VANnVBG','lI9Vyxv0Aa','zgvMyxvSDa','B2jQzwn0','qxbPrxjYB3i','revgqvvmvf9bueLFr0furvDbwv9ftKrqt0Lova','lI9JBgLLBNq','nuHpt1DNtq','mtq4vwv6yxDM','BwvZC2fNzq','x19PBxbVCNrezwzHDwX0','mteZmdK0men3rfv1AG','mta2n1rVzvDVuq','mtzvBwDlCLi','Aw50zxjJzxb0B3jZ','5l2G5RkH5PYj6k6/6zEU6k+L6lwe5RQq55Qe5P2d6zMq','mtq5otbWrgjgue0','6lwe5RQq5lIn5A2y5zYO','qMvHCMvYia','C3rHDhvZ','x19LC01VzhvSzq','CMvXDwvZDa','zgf0yq','lI9LBNy','B2f1DgHbCgLdBgLLBNq','ntqWodrAtePrtNm','z2v0vMfSAwrpqxv0AefJy2vZC1rVA2vU','nta1z3zTu2D5','nZa3nZu3vvrJv0jz','zw52','zgvMAw5LuhjVCgvYDhK'];_0x8b4c=function(){return _0x87c601;};return _0x8b4c();}Object[_0x199ff3(0x131)](exports,_0x199ff3(0x127),{'value':!![]}),exports[_0x199ff3(0x12b)]=oauthApiClient;const axios_1=__importDefault(require('axios')),env_1=require(_0x199ff3(0x12a)),oauth_1=require(_0x199ff3(0x138)),client_1=require(_0x199ff3(0x119));function httpErrorMessage(_0x23ec8a,_0x333897){const _0x3102db=_0x199ff3;if(_0x333897&&typeof _0x333897===_0x3102db(0x116)&&_0x3102db(0x11c)in _0x333897)return String(_0x333897['message']);switch(_0x23ec8a){case 0x191:return'OAuth\x20鉴权失败,请运行\x20mplus\x20login\x20重新登录';case 0x193:return _0x3102db(0x122);case 0x194:return _0x3102db(0x124);default:if(_0x23ec8a>=0x1f4)return'服务器错误,请稍后重试';return'请求失败(HTTP\x20'+_0x23ec8a+')';}}async function oauthApiClient(_0x30683f){const _0x389189=_0x199ff3,_0x208f8f=await(0x0,oauth_1[_0x389189(0x12d)])(_0x30683f),_0x445a24=(process[_0x389189(0x130)][_0x389189(0x132)]??env_1[_0x389189(0x118)])['replace'](/\/$/,''),_0x218f5d=axios_1[_0x389189(0x115)][_0x389189(0x134)]({'baseURL':_0x445a24,'headers':{'Authorization':_0x389189(0x125)+_0x208f8f,'Content-Type':_0x389189(0x137),'Accept':_0x389189(0x137)},'timeout':0x7530});return _0x218f5d[_0x389189(0x121)][_0x389189(0x135)]['use'](_0x385e35=>_0x385e35,_0x59cae7=>{const _0x23e8ff=_0x389189;if(_0x59cae7['response'])throw new client_1[(_0x23e8ff(0x117))](httpErrorMessage(_0x59cae7[_0x23e8ff(0x135)][_0x23e8ff(0x126)],_0x59cae7[_0x23e8ff(0x135)][_0x23e8ff(0x129)]),_0x59cae7[_0x23e8ff(0x135)][_0x23e8ff(0x126)]);if(_0x59cae7[_0x23e8ff(0x128)])throw new client_1[(_0x23e8ff(0x117))]('网络错误,无法连接\x20API\x20Gateway:'+_0x59cae7[_0x23e8ff(0x11c)]);throw new client_1[(_0x23e8ff(0x117))](_0x59cae7['message']);}),_0x218f5d;}
package/dist/registry.js CHANGED
@@ -1 +1 @@
1
- 'use strict';var _0xedec71=_0x45f1;function _0xff91(){var _0x211497=['ndK4nJu1ogfmA2jruG','mJiYmJyXmNHbu3rAta','mZG5nde2sNHYDhHr','mtKXmdC3mfbrwwXlva','mJKXmJK0zNbPD0LV','mZGWotLftKHQyuK','zgvMAw5LuhjVCgvYDhK','mZzqvvb6tey','mJuZz1flr2je','mtG0zwn4zK9V','nde4nJGWmfb2teDAwq','mtvMz1rqBu8'];_0xff91=function(){return _0x211497;};return _0xff91();}(function(_0x9c7323,_0x5c1cbd){var _0x30039a=_0x45f1,_0xcd231d=_0x9c7323();while(!![]){try{var _0x4d489a=-parseInt(_0x30039a(0x1c6))/0x1*(parseInt(_0x30039a(0x1c8))/0x2)+parseInt(_0x30039a(0x1cc))/0x3*(-parseInt(_0x30039a(0x1c3))/0x4)+-parseInt(_0x30039a(0x1cb))/0x5+-parseInt(_0x30039a(0x1cd))/0x6+-parseInt(_0x30039a(0x1ce))/0x7+-parseInt(_0x30039a(0x1ca))/0x8*(parseInt(_0x30039a(0x1c5))/0x9)+-parseInt(_0x30039a(0x1c4))/0xa*(-parseInt(_0x30039a(0x1c9))/0xb);if(_0x4d489a===_0x5c1cbd)break;else _0xcd231d['push'](_0xcd231d['shift']());}catch(_0x272a77){_0xcd231d['push'](_0xcd231d['shift']());}}}(_0xff91,0x78138));function _0x45f1(_0x42669f,_0x1b6c07){_0x42669f=_0x42669f-0x1c3;var _0xff91d8=_0xff91();var _0x45f18c=_0xff91d8[_0x42669f];if(_0x45f1['BZfhal']===undefined){var _0x1b7a8f=function(_0x3e8887){var _0x14a668='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';var _0x298681='',_0xe72b97='';for(var _0x18182a=0x0,_0x719dc6,_0x7679f8,_0x204c5a=0x0;_0x7679f8=_0x3e8887['charAt'](_0x204c5a++);~_0x7679f8&&(_0x719dc6=_0x18182a%0x4?_0x719dc6*0x40+_0x7679f8:_0x7679f8,_0x18182a++%0x4)?_0x298681+=String['fromCharCode'](0xff&_0x719dc6>>(-0x2*_0x18182a&0x6)):0x0){_0x7679f8=_0x14a668['indexOf'](_0x7679f8);}for(var _0xb9b229=0x0,_0x37c395=_0x298681['length'];_0xb9b229<_0x37c395;_0xb9b229++){_0xe72b97+='%'+('00'+_0x298681['charCodeAt'](_0xb9b229)['toString'](0x10))['slice'](-0x2);}return decodeURIComponent(_0xe72b97);};_0x45f1['IXUDBC']=_0x1b7a8f,_0x45f1['RFknKM']={},_0x45f1['BZfhal']=!![];}var _0x22c9c2=_0xff91d8[0x0],_0x3fdcef=_0x42669f+_0x22c9c2,_0x1cefd9=_0x45f1['RFknKM'][_0x3fdcef];return!_0x1cefd9?(_0x45f18c=_0x45f1['IXUDBC'](_0x45f18c),_0x45f1['RFknKM'][_0x3fdcef]=_0x45f18c):_0x45f18c=_0x1cefd9,_0x45f18c;}Object[_0xedec71(0x1c7)](exports,'__esModule',{'value':!![]}),exports['commandRoles']=void 0x0,exports['commandRoles']=new Map();
1
+ 'use strict';function _0x2988(_0x220d5e,_0x454725){_0x220d5e=_0x220d5e-0xec;var _0x256985=_0x2569();var _0x29884e=_0x256985[_0x220d5e];if(_0x2988['VprRov']===undefined){var _0x22f25a=function(_0x403c3c){var _0x456d8f='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';var _0x475351='',_0x8c10c4='';for(var _0x3d161d=0x0,_0x44c45e,_0x4b7af6,_0x4ec919=0x0;_0x4b7af6=_0x403c3c['charAt'](_0x4ec919++);~_0x4b7af6&&(_0x44c45e=_0x3d161d%0x4?_0x44c45e*0x40+_0x4b7af6:_0x4b7af6,_0x3d161d++%0x4)?_0x475351+=String['fromCharCode'](0xff&_0x44c45e>>(-0x2*_0x3d161d&0x6)):0x0){_0x4b7af6=_0x456d8f['indexOf'](_0x4b7af6);}for(var _0x271f3a=0x0,_0x5549df=_0x475351['length'];_0x271f3a<_0x5549df;_0x271f3a++){_0x8c10c4+='%'+('00'+_0x475351['charCodeAt'](_0x271f3a)['toString'](0x10))['slice'](-0x2);}return decodeURIComponent(_0x8c10c4);};_0x2988['JxezeB']=_0x22f25a,_0x2988['HGwZvV']={},_0x2988['VprRov']=!![];}var _0xfe8abc=_0x256985[0x0],_0xa035c2=_0x220d5e+_0xfe8abc,_0x4a46d0=_0x2988['HGwZvV'][_0xa035c2];return!_0x4a46d0?(_0x29884e=_0x2988['JxezeB'](_0x29884e),_0x2988['HGwZvV'][_0xa035c2]=_0x29884e):_0x29884e=_0x4a46d0,_0x29884e;}var _0x59d817=_0x2988;(function(_0x4981df,_0x16820a){var _0x2a2e29=_0x2988,_0x3e0c4e=_0x4981df();while(!![]){try{var _0x45388b=parseInt(_0x2a2e29(0xf0))/0x1*(-parseInt(_0x2a2e29(0xf5))/0x2)+parseInt(_0x2a2e29(0xf4))/0x3+parseInt(_0x2a2e29(0xef))/0x4+parseInt(_0x2a2e29(0xee))/0x5+parseInt(_0x2a2e29(0xf2))/0x6+parseInt(_0x2a2e29(0xf7))/0x7*(-parseInt(_0x2a2e29(0xf1))/0x8)+-parseInt(_0x2a2e29(0xf6))/0x9*(parseInt(_0x2a2e29(0xec))/0xa);if(_0x45388b===_0x16820a)break;else _0x3e0c4e['push'](_0x3e0c4e['shift']());}catch(_0x2e3ac3){_0x3e0c4e['push'](_0x3e0c4e['shift']());}}}(_0x2569,0xbcbe1));function _0x2569(){var _0x1bca87=['mtbjvvbfzNq','zgvMAw5LuhjVCgvYDhK','nduWnJmWnwrzyufZBa','mJCZndiYoeXeDgjjsW','ntCZotfNrwDZrem','mteXmtiWogrdBLfWsW','nJa1mdy3mfbeDMveDq','y29TBwfUzfjVBgvZ','mtmWmZq0mgPArxzxvW','ndrYBurtuLq','nJqYodi1mhHIBwTzBq','mtryuKvQs0m'];_0x2569=function(){return _0x1bca87;};return _0x2569();}Object[_0x59d817(0xed)](exports,'__esModule',{'value':!![]}),exports[_0x59d817(0xf3)]=void 0x0,exports[_0x59d817(0xf3)]=new Map();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@miracleplus/mplus",
3
- "version": "0.1.4",
3
+ "version": "0.1.6",
4
4
  "description": "奇绩创坛命令行工具(mplus CLI)",
5
5
  "keywords": [
6
6
  "miracleplus",
@@ -12,15 +12,20 @@
12
12
  "mplus": "./bin/mplus.js"
13
13
  },
14
14
  "main": "./dist/index.js",
15
+ "readme": "README.npm.md",
15
16
  "files": [
16
17
  "dist",
17
- "bin"
18
+ "bin",
19
+ "skills",
20
+ "scripts/postinstall-skills.js",
21
+ "README.npm.md"
18
22
  ],
19
23
  "scripts": {
20
24
  "build": "tsc -p tsconfig.build.json && node scripts/postbuild.js",
21
25
  "build:dev": "tsc && node scripts/postbuild.js",
22
26
  "obfuscate": "node scripts/obfuscate.js",
23
27
  "prepublishOnly": "npm run clean && npm run build && npm run obfuscate",
28
+ "postinstall": "node scripts/postinstall-skills.js",
24
29
  "dev": "tsc --watch",
25
30
  "start": "node dist/index.js",
26
31
  "clean": "rm -rf dist"
@@ -0,0 +1,49 @@
1
+ /**
2
+ * postinstall hook — 自动将 skills 安装到 ~/.agents/skills/
3
+ * npm install -g @miracleplus/mplus 时自动执行
4
+ */
5
+
6
+ const fs = require('fs');
7
+ const path = require('path');
8
+ const os = require('os');
9
+
10
+ const skillsSource = path.resolve(__dirname, '..', 'skills');
11
+ const skillsTarget = path.join(os.homedir(), '.agents', 'skills');
12
+
13
+ function copyDirSync(src, dest) {
14
+ fs.mkdirSync(dest, { recursive: true });
15
+ const entries = fs.readdirSync(src, { withFileTypes: true });
16
+ for (const entry of entries) {
17
+ const srcPath = path.join(src, entry.name);
18
+ const destPath = path.join(dest, entry.name);
19
+ if (entry.isDirectory()) {
20
+ copyDirSync(srcPath, destPath);
21
+ } else {
22
+ fs.copyFileSync(srcPath, destPath);
23
+ }
24
+ }
25
+ }
26
+
27
+ // 静默执行:失败不阻塞安装
28
+ try {
29
+ if (!fs.existsSync(skillsSource)) {
30
+ // 开发环境或 skills 目录未打包,跳过
31
+ process.exit(0);
32
+ }
33
+
34
+ const skillDirs = fs.readdirSync(skillsSource, { withFileTypes: true })
35
+ .filter((d) => d.isDirectory());
36
+
37
+ if (skillDirs.length === 0) {
38
+ process.exit(0);
39
+ }
40
+
41
+ for (const dir of skillDirs) {
42
+ copyDirSync(path.join(skillsSource, dir.name), path.join(skillsTarget, dir.name));
43
+ }
44
+
45
+ console.log(`mplus: ✓ ${skillDirs.length} AI skills installed to ${skillsTarget}`);
46
+ } catch (err) {
47
+ // 静默失败,不阻塞 npm install
48
+ // 用户可以后续手动执行 mplus install-skills
49
+ }
@@ -0,0 +1,49 @@
1
+ ---
2
+ name: mplus-admission
3
+ version: 0.1.0
4
+ description: "奇绩创坛 Admission 数据查询:查询创业项目(startup_projects)的申请材料和面试材料,支持按批次、补充材料等条件过滤。当用户需要查看、搜索、分析创业项目申请数据时使用。"
5
+ metadata:
6
+ requires:
7
+ bins: ["mplus"]
8
+ ---
9
+
10
+ # admission
11
+
12
+ **CRITICAL — 开始前 MUST 先用 Read 工具读取 [`../mplus-shared/SKILL.md`](../mplus-shared/SKILL.md),其中包含认证、错误处理等共享知识**
13
+
14
+ ## 核心概念
15
+
16
+ - **startup_project**: 创业项目记录,包含申请材料(application_content)和面试材料(interview_content)
17
+ - **batch**: 加速营批次,每期一个批次名(格式 `<YY><季节>`,小写。季节:`s`=春季批、`a`=秋季批。例如 "25s"=2025 春、"25a"=2025 秋、"26s"=2026 春)
18
+ - **addition**: 补充材料标记,表示该记录是否为补充提交的材料
19
+
20
+ ## 资源关系
21
+
22
+ ```
23
+ Batch (batch_name)
24
+ └── StartupProject (project_id)
25
+ ├── application_content (申请材料,可能为 null)
26
+ ├── interview_content (面试材料,可能为 null)
27
+ └── addition (是否补充材料)
28
+ ```
29
+
30
+ ## 认证要求
31
+
32
+ admission 命令使用 OAuth 认证(非 API Key),需要先执行 `mplus login` 完成授权。
33
+
34
+ 支持 `--session` 参数切换不同的 OAuth session。
35
+
36
+ ## 命令速查
37
+
38
+ | 命令 | 说明 | 参考文档 |
39
+ |------|------|---------|
40
+ | `mplus admission startup-projects list` | 查询项目列表,支持过滤和分页 | [references/admission-startup-projects-list.md](references/admission-startup-projects-list.md) |
41
+ | `mplus admission startup-projects get <id>` | 查询单个项目详情 | [references/admission-startup-projects-get.md](references/admission-startup-projects-get.md) |
42
+
43
+ ## AI 使用建议
44
+
45
+ 1. **先查列表再取详情**:不确定 project_id 时,先用 `list` 命令查找,再用 `get` 获取完整内容
46
+ 2. **始终加 `--json`**:需要解析数据时必须使用 JSON 格式,默认文本格式会截断材料内容(只显示长度)
47
+ 3. **分页策略**:先不带过滤条件查看 `total`,了解数据规模后再决定是否需要翻页或加过滤条件
48
+ 4. **批次过滤**:如果用户提到具体批次(如 "26s 的项目"),使用 `--batch-name` 过滤
49
+ 5. **补充材料**:`--addition true` 只返回补充提交的记录,`--addition false` 只返回初始提交
@@ -0,0 +1,91 @@
1
+ # admission startup-projects get
2
+
3
+ > **前置条件:** 先用 Read 工具读取 [`../mplus-shared/SKILL.md`](../../mplus-shared/SKILL.md) 了解认证和全局参数。
4
+
5
+ 查询单个 startup_project 的详细信息。
6
+
7
+ 对应命令:`mplus admission startup-projects get <project_id>`(内部调用 `GET /admission/api/v1/startup-projects/:project_id`,通过 API Gateway)。
8
+
9
+ ## 命令示例
10
+
11
+ ```bash
12
+ # 查询单个项目(默认只看初始提交)
13
+ mplus admission startup-projects get 87575
14
+
15
+ # JSON 格式输出(AI Agent 推荐)
16
+ mplus admission startup-projects get 87575 --json
17
+
18
+ # 查看补充材料版本
19
+ mplus admission startup-projects get 87575 --addition true --json
20
+
21
+ # 使用指定 OAuth session
22
+ mplus admission startup-projects get 87575 --session work --json
23
+ ```
24
+
25
+ ## 参数
26
+
27
+ | 参数 | 必填 | 类型 | 默认值 | 说明 |
28
+ |------|------|------|--------|------|
29
+ | `<project_id>` | **是** | string (位置参数) | — | 项目唯一标识 |
30
+ | `--addition <bool>` | 否 | string | `"false"` | 是否查看补充材料版本:`true` 返回补充提交,`false` 返回初始提交 |
31
+ | `--session <name>` | 否 | string | `"default"` | OAuth session 名称 |
32
+ | `--json` | 否 | boolean | `false` | 以 JSON 格式输出完整响应 |
33
+
34
+ > **`--addition` 取值规则**:接受 `true`/`1`/`yes`/`y` 或 `false`/`0`/`no`/`n`(不区分大小写)。其他值会报错。
35
+
36
+ ## 返回字段
37
+
38
+ ### JSON 格式(`--json`)
39
+
40
+ ```json
41
+ {
42
+ "project_id": "87575",
43
+ "batch_name": "26s",
44
+ "application_content": "完整的申请材料文本...",
45
+ "interview_content": "完整的面试材料文本...",
46
+ "addition": false
47
+ }
48
+ ```
49
+
50
+ | 字段 | 类型 | 说明 |
51
+ |------|------|------|
52
+ | `project_id` | string | 项目唯一标识 |
53
+ | `batch_name` | string | 所属批次名 |
54
+ | `application_content` | string \| null | 申请材料全文(可能为 null,表示未提交) |
55
+ | `interview_content` | string \| null | 面试材料全文(可能为 null,表示未提交) |
56
+ | `addition` | boolean | 是否为补充材料 |
57
+
58
+ ### 默认文本格式
59
+
60
+ ```
61
+ 项目 ID:87575
62
+ 批次:26s
63
+ 补充材料:否
64
+ 申请材料长度:3456
65
+ 面试材料长度:2100
66
+ ```
67
+
68
+ > 文本格式只显示材料长度,不显示实际内容。需要完整内容必须加 `--json`。
69
+
70
+ ## 常见错误
71
+
72
+ | 现象 | 原因 | 解决方案 |
73
+ |------|------|---------|
74
+ | `OAuth 鉴权失败,请运行 mplus login 重新登录` | token 过期且刷新失败 | 执行 `mplus login` |
75
+ | `未找到 OAuth session,请先运行 mplus login` | 从未登录 | 执行 `mplus login` |
76
+ | `--addition 只能是 true 或 false` | `--addition` 传了非法值 | 使用 `true`/`false`/`1`/`0`/`yes`/`no` |
77
+ | `资源不存在` | project_id 不存在,或该 addition 状态下无记录 | 确认 project_id 正确;尝试切换 `--addition` 值 |
78
+ | `你没有访问该资源的权限` | 当前用户无 admission 数据权限 | 确认账户权限 |
79
+
80
+ ## AI 使用建议
81
+
82
+ 1. **获取完整材料**:必须加 `--json`,否则只能看到材料长度
83
+ 2. **初始 vs 补充材料**:同一个 project_id 可能有两个版本——初始提交(`--addition false`,默认)和补充提交(`--addition true`)。如果用户要看"最新材料"或"补充材料",记得切换 `--addition`
84
+ 3. **project_id 来源**:通常从 `admission startup-projects list` 的结果中获取
85
+ 4. **材料为 null**:表示该阶段材料尚未提交,不是错误
86
+
87
+ ## 参考
88
+
89
+ - [mplus-admission](../SKILL.md) — admission 领域概览
90
+ - [mplus-shared](../../mplus-shared/SKILL.md) — 认证和全局参数
91
+ - [admission-startup-projects-list](admission-startup-projects-list.md) — 查询项目列表
@@ -0,0 +1,150 @@
1
+ # admission startup-projects list
2
+
3
+ > **前置条件:** 先用 Read 工具读取 [`../mplus-shared/SKILL.md`](../../mplus-shared/SKILL.md) 了解认证和全局参数。
4
+
5
+ 查询 startup_projects 列表,支持按批次、补充材料、项目 ID 过滤,支持分页。
6
+
7
+ 对应命令:`mplus admission startup-projects list`(内部调用 `GET /admission/api/v1/startup-projects`,通过 API Gateway)。
8
+
9
+ ## 命令示例
10
+
11
+ ```bash
12
+ # 查询所有项目(默认第 1 页,每页 20 条)
13
+ mplus admission startup-projects list
14
+
15
+ # JSON 格式输出(AI Agent 推荐)
16
+ mplus admission startup-projects list --json
17
+
18
+ # 按批次过滤
19
+ mplus admission startup-projects list --batch-name "26s"
20
+
21
+ # 只看补充材料
22
+ mplus admission startup-projects list --addition true
23
+
24
+ # 只看初始提交
25
+ mplus admission startup-projects list --addition false
26
+
27
+ # 按项目 ID 精确查询
28
+ mplus admission startup-projects list --project-id "87575"
29
+
30
+ # 分页:第 2 页,每页 50 条
31
+ mplus admission startup-projects list --page 2 --page-size 50
32
+
33
+ # 组合过滤 + 分页 + JSON
34
+ mplus admission startup-projects list --batch-name "25a" --addition false --page 1 --page-size 10 --json
35
+
36
+ # 使用指定 OAuth session
37
+ mplus admission startup-projects list --session work --json
38
+ ```
39
+
40
+ ## 参数
41
+
42
+ | 参数 | 必填 | 类型 | 默认值 | 说明 |
43
+ |------|------|------|--------|------|
44
+ | `--batch-name <name>` | 否 | string | — | 按批次名过滤(精确匹配,格式 `<YY><季节>` 小写,季节:`s`=春、`a`=秋,如 `"25a"`、`"26s"`) |
45
+ | `--addition <bool>` | 否 | string | — | 按补充材料过滤:`true` 只返回补充提交,`false` 只返回初始提交 |
46
+ | `--project-id <id>` | 否 | string | — | 按 project_id 精确过滤 |
47
+ | `--page <number>` | 否 | string | `"1"` | 页码,从 1 开始 |
48
+ | `--page-size <number>` | 否 | string | `"20"` | 每页数量 |
49
+ | `--session <name>` | 否 | string | `"default"` | OAuth session 名称 |
50
+ | `--json` | 否 | boolean | `false` | 以 JSON 格式输出完整响应 |
51
+
52
+ > **`--addition` 取值规则**:接受 `true`/`1`/`yes`/`y` 或 `false`/`0`/`no`/`n`(不区分大小写)。其他值会报错。
53
+
54
+ ## 返回字段
55
+
56
+ ### JSON 格式(`--json`)
57
+
58
+ ```json
59
+ {
60
+ "total": 156,
61
+ "page": 1,
62
+ "page_size": 20,
63
+ "items": [
64
+ {
65
+ "project_id": "87575",
66
+ "batch_name": "26s",
67
+ "application_content": "完整的申请材料文本...",
68
+ "interview_content": "完整的面试材料文本...",
69
+ "addition": false
70
+ }
71
+ ]
72
+ }
73
+ ```
74
+
75
+ | 字段 | 类型 | 说明 |
76
+ |------|------|------|
77
+ | `total` | number | 符合条件的总记录数 |
78
+ | `page` | number | 当前页码 |
79
+ | `page_size` | number | 每页数量 |
80
+ | `items` | array | 项目列表 |
81
+ | `items[].project_id` | string | 项目唯一标识 |
82
+ | `items[].batch_name` | string | 所属批次名 |
83
+ | `items[].application_content` | string \| null | 申请材料全文(可能为 null) |
84
+ | `items[].interview_content` | string \| null | 面试材料全文(可能为 null) |
85
+ | `items[].addition` | boolean | 是否为补充材料 |
86
+
87
+ ### 默认文本格式
88
+
89
+ 文本格式只显示摘要信息(材料长度而非全文):
90
+
91
+ ```
92
+ 共 156 条,当前第 1 页,每页 20 条
93
+
94
+ 项目 ID:87575
95
+ 批次:26s
96
+ 补充材料:否
97
+ 申请材料长度:3456
98
+ 面试材料长度:2100
99
+
100
+ 项目 ID:87611
101
+ 批次:26s
102
+ 补充材料:是
103
+ 申请材料长度:0
104
+ 面试材料长度:1800
105
+ ```
106
+
107
+ ## 分页
108
+
109
+ 服务端分页,通过 `--page` 和 `--page-size` 控制:
110
+
111
+ - `total` 表示符合过滤条件的总记录数
112
+ - 总页数 = `Math.ceil(total / page_size)`
113
+ - 翻页:递增 `--page` 值
114
+
115
+ ```bash
116
+ # 第 1 页
117
+ mplus admission startup-projects list --json --page 1 --page-size 20
118
+
119
+ # 第 2 页
120
+ mplus admission startup-projects list --json --page 2 --page-size 20
121
+
122
+ # 第 3 页
123
+ mplus admission startup-projects list --json --page 3 --page-size 20
124
+ ```
125
+
126
+ **判断是否还有下一页**:当 `page * page_size < total` 时,还有更多数据。
127
+
128
+ ## 常见错误
129
+
130
+ | 现象 | 原因 | 解决方案 |
131
+ |------|------|---------|
132
+ | `OAuth 鉴权失败,请运行 mplus login 重新登录` | token 过期且刷新失败 | 执行 `mplus login` |
133
+ | `未找到 OAuth session,请先运行 mplus login` | 从未登录 | 执行 `mplus login` |
134
+ | `--addition 只能是 true 或 false` | `--addition` 传了非法值 | 使用 `true`/`false`/`1`/`0`/`yes`/`no` |
135
+ | `你没有访问该资源的权限` | 当前用户无 admission 数据权限 | 确认账户权限 |
136
+ | `资源不存在` | API 路径错误或服务未部署 | 检查 API Gateway 状态 |
137
+
138
+ ## AI 使用建议
139
+
140
+ 1. **获取完整材料内容**:必须加 `--json`。默认文本格式只显示材料长度(字符数),不显示实际内容
141
+ 2. **大批量数据**:先查一次不带过滤条件看 `total`,再决定分页策略。如果 total 很大,优先加过滤条件缩小范围
142
+ 3. **查找特定项目**:如果知道 project_id,直接用 `--project-id` 过滤(或用 `get` 子命令)
143
+ 4. **批次名格式**:`<YY><季节>` 小写,年份在前。季节字母:`s`=春季批、`a`=秋季批。例如 `26s`=2026 春季批、`25a`=2025 秋季批。已观察到 `20a`、`22s`/`22a`、`23s`/`23a`、`24s`/`24a`、`25s`/`25a`、`26s`。`--batch-name` 精确匹配,注意大小写
144
+ 5. **材料为 null 的情况**:`application_content` 或 `interview_content` 为 null 表示该阶段材料尚未提交
145
+
146
+ ## 参考
147
+
148
+ - [mplus-admission](../SKILL.md) — admission 领域概览
149
+ - [mplus-shared](../../mplus-shared/SKILL.md) — 认证和全局参数
150
+ - [admission-startup-projects-get](admission-startup-projects-get.md) — 查询单个项目
@@ -0,0 +1,96 @@
1
+ ---
2
+ name: mplus-shared
3
+ version: 0.1.0
4
+ description: "奇绩创坛 CLI 共享基础:OAuth 登录、session 管理、全局参数、错误处理。当用户首次使用 mplus CLI、需要登录授权、遇到鉴权错误、或切换 session 时触发。"
5
+ metadata:
6
+ requires:
7
+ bins: ["mplus"]
8
+ ---
9
+
10
+ # mplus CLI 共享规则
11
+
12
+ 本技能指导你如何通过 mplus CLI 操作奇绩创坛平台资源。
13
+
14
+ ## 认证方式
15
+
16
+ mplus CLI 的 admission 相关命令使用 **OAuth Authorization Code + PKCE** 认证,通过 API Gateway (`https://api-gateway.miracleplus.com`) 访问后端服务。
17
+
18
+ ### 登录
19
+
20
+ ```bash
21
+ # 默认登录(自动打开浏览器)
22
+ mplus login
23
+
24
+ # 指定 session 名称(支持多账户)
25
+ mplus login --session work
26
+
27
+ # 不自动打开浏览器(手动复制链接)
28
+ mplus login --no-open
29
+ ```
30
+
31
+ 登录流程:
32
+ 1. CLI 启动本地 HTTP 服务器(端口 8765)
33
+ 2. 打开浏览器跳转到 MP OAuth 授权页面
34
+ 3. 用户在浏览器中完成授权
35
+ 4. CLI 自动接收回调,换取 access token
36
+ 5. Token 保存到本地 session
37
+
38
+ ### Session 管理
39
+
40
+ 支持多个 OAuth session 并存,通过 `--session` 切换:
41
+
42
+ ```bash
43
+ # 使用默认 session
44
+ mplus admission startup-projects list
45
+
46
+ # 使用指定 session
47
+ mplus admission startup-projects list --session work
48
+ ```
49
+
50
+ ### Token 自动刷新
51
+
52
+ - access token 过期前 60 秒自动使用 refresh_token 刷新
53
+ - 如果 refresh_token 也失效,需要重新 `mplus login`
54
+
55
+ ## 全局输出格式
56
+
57
+ 所有数据命令支持 `--json` 标志:
58
+
59
+ | 模式 | 说明 |
60
+ |------|------|
61
+ | 默认 | 人类友好的格式化文本输出 |
62
+ | `--json` | 完整 JSON 响应(2 空格缩进) |
63
+
64
+ **AI Agent 建议**:需要解析数据时始终使用 `--json`,默认文本格式仅供人类阅读。
65
+
66
+ ## 错误处理
67
+
68
+ 所有错误输出到 stderr,格式为 `错误:<message>`,进程退出码为 1。
69
+
70
+ | 错误消息 | 原因 | 解决方案 |
71
+ |---------|------|---------|
72
+ | `OAuth 鉴权失败,请运行 mplus login 重新登录` | access token 无效或过期且刷新失败 | 执行 `mplus login` 重新授权 |
73
+ | `未找到 OAuth session,请先运行 mplus login` | 从未登录或 session 不存在 | 执行 `mplus login --session <name>` |
74
+ | `你没有访问该资源的权限` | 当前用户无权限 | 确认账户权限 |
75
+ | `网络错误,无法连接 API Gateway` | 网络不通 | 检查网络连接 |
76
+ | `服务器错误,请稍后重试` | 后端 5xx | 等待后重试 |
77
+
78
+ ## Agent 代理发起登录
79
+
80
+ 当你作为 AI Agent 帮用户登录时:
81
+
82
+ 1. 使用 background 方式执行 `mplus login`(该命令会阻塞等待浏览器回调)
83
+ 2. 从输出中提取授权 URL 发给用户
84
+ 3. 等待用户在浏览器中完成授权
85
+ 4. 命令自动完成,session 已保存
86
+
87
+ ```bash
88
+ # background 执行,提取 URL 给用户
89
+ mplus login --session default
90
+ ```
91
+
92
+ ## 安全规则
93
+
94
+ - **禁止**将 access_token / refresh_token 输出到终端明文
95
+ - 写入/删除操作前确认用户意图
96
+ - 使用 `--json` 获取结构化数据,避免解析文本格式出错