feat(phase-4): WS2 + WS3 — Developer Portal (Next.js 14) and CLI tool (sentryagent)

WS2: Developer Portal (portal/)
- Standalone Next.js 14 + Tailwind CSS app — independent deployment
- Home page: hero, feature grid, CTA to /get-started
- /pricing: free tier limits table (10 agents, 1k calls/day) + paid tier CTA
- /sdks: all 4 SDKs (Node.js, Python, Go, Java) with install + code examples
- /api-explorer: Swagger UI from NEXT_PUBLIC_API_URL/openapi.json, persistAuthorization
- /get-started: 4-step wizard (setup → register agent → credentials → SDK snippet)
- Shared Nav component with active-link highlighting
- Build: 8/8 static pages, zero TypeScript errors

WS3: CLI Tool (cli/ — npm package: sentryagent)
- configure, register-agent, list-agents, issue-token, rotate-credentials, tail-audit-log
- Auto OAuth2 token fetch + 30s-buffer cache via client_credentials flow
- chalk-formatted table output, confirmation prompts, bounded audit log dedup
- bash + zsh shell completion scripts
- README with installation, all commands, and completion setup
- Build: tsc clean, node dist/index.js --help verified

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
SentryAgent.ai Developer
2026-04-02 04:29:50 +00:00
parent 1b682c22b2
commit d1e6af25aa
147 changed files with 8079 additions and 29 deletions

View File

@@ -0,0 +1 @@
(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[734],{52305:function(e,t,n){Promise.resolve().then(n.bind(n,49947))},49947:function(e,t,n){"use strict";n.d(t,{SwaggerExplorer:function(){return s}});var l=n(57437);n(2265);var r=n(50551),u=n.n(r);n(68146);let o=u()(()=>Promise.all([n.e(155),n.e(361)]).then(n.bind(n,3844)),{loadableGenerated:{webpack:()=>[null]},ssr:!1}),i=["get","post","put","patch","delete"];function s(e){let{apiUrl:t}=e;return(0,l.jsx)("div",{className:"swagger-wrapper min-h-screen",children:(0,l.jsx)(o,{url:"".concat(t,"/openapi.json"),persistAuthorization:!0,supportedSubmitMethods:i})})}},50551:function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"default",{enumerable:!0,get:function(){return u}});let l=n(99920);n(57437),n(2265);let r=l._(n(40148));function u(e,t){var n;let l={loading:e=>{let{error:t,isLoading:n,pastDelay:l}=e;return null}};"function"==typeof e&&(l.loader=e);let u={...l,...t};return(0,r.default)({...u,modules:null==(n=u.loadableGenerated)?void 0:n.modules})}("function"==typeof t.default||"object"==typeof t.default&&null!==t.default)&&void 0===t.default.__esModule&&(Object.defineProperty(t.default,"__esModule",{value:!0}),Object.assign(t.default,t),e.exports=t.default)},10912:function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"BailoutToCSR",{enumerable:!0,get:function(){return r}});let l=n(55592);function r(e){let{reason:t,children:n}=e;if("undefined"==typeof window)throw new l.BailoutToCSRError(t);return n}},40148:function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"default",{enumerable:!0,get:function(){return a}});let l=n(57437),r=n(2265),u=n(10912),o=n(61481);function i(e){return{default:e&&"default"in e?e.default:e}}let s={loader:()=>Promise.resolve(i(()=>null)),loading:null,ssr:!0},a=function(e){let t={...s,...e},n=(0,r.lazy)(()=>t.loader().then(i)),a=t.loading;function d(e){let i=a?(0,l.jsx)(a,{isLoading:!0,pastDelay:!0,error:null}):null,s=t.ssr?(0,l.jsxs)(l.Fragment,{children:["undefined"==typeof window?(0,l.jsx)(o.PreloadCss,{moduleIds:t.modules}):null,(0,l.jsx)(n,{...e})]}):(0,l.jsx)(u.BailoutToCSR,{reason:"next/dynamic",children:(0,l.jsx)(n,{...e})});return(0,l.jsx)(r.Suspense,{fallback:i,children:s})}return d.displayName="LoadableComponent",d}},61481:function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"PreloadCss",{enumerable:!0,get:function(){return u}});let l=n(57437),r=n(58512);function u(e){let{moduleIds:t}=e;if("undefined"!=typeof window)return null;let n=(0,r.getExpectedRequestStore)("next/dynamic css"),u=[];if(n.reactLoadableManifest&&t){let e=n.reactLoadableManifest;for(let n of t){if(!e[n])continue;let t=e[n].files.filter(e=>e.endsWith(".css"));u.push(...t)}}return 0===u.length?null:(0,l.jsx)(l.Fragment,{children:u.map(e=>(0,l.jsx)("link",{precedence:"dynamic",rel:"stylesheet",href:n.assetPrefix+"/_next/"+encodeURI(e),as:"style"},e))})}},68146:function(){}},function(e){e.O(0,[675,971,23,744],function(){return e(e.s=52305)}),_N_E=e.O()}]);