Files
sentryagent-idp/portal/.next/static/chunks/app/get-started/page-31e1ee0acda82a62.js
SentryAgent.ai Developer d1e6af25aa 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>
2026-04-02 04:29:50 +00:00

1 line
12 KiB
JavaScript

(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[719],{79045:function(e,t,n){Promise.resolve().then(n.bind(n,63933))},63933:function(e,t,n){"use strict";n.d(t,{GetStartedWizard:function(){return g}});var s=n(57437),r=n(2265);function a(e){let{current:t,total:n}=e;return(0,s.jsx)("div",{className:"mb-8 flex items-center gap-2",children:Array.from({length:n},(e,t)=>t+1).map(e=>(0,s.jsxs)(r.Fragment,{children:[(0,s.jsx)("div",{className:["flex h-8 w-8 items-center justify-center rounded-full text-sm font-bold",e<t?"bg-brand-600 text-white":e===t?"border-2 border-brand-600 bg-brand-50 text-brand-700":"bg-slate-200 text-slate-500"].join(" "),children:e<t?"✓":e}),e<n&&(0,s.jsx)("div",{className:["h-0.5 flex-1",e<t?"bg-brand-600":"bg-slate-200"].join(" ")})]},e))})}function l(e){let{text:t}=e,[n,a]=(0,r.useState)(!1),l=async()=>{await navigator.clipboard.writeText(t),a(!0),setTimeout(()=>a(!1),2e3)};return(0,s.jsx)("button",{onClick:()=>void l(),className:"ml-2 rounded bg-slate-100 px-2 py-1 text-xs font-medium text-slate-600 transition-colors hover:bg-slate-200",children:n?"Copied!":"Copy"})}function i(e){let{message:t}=e;return(0,s.jsx)("div",{className:"mb-4 rounded-lg border border-red-200 bg-red-50 px-4 py-3 text-sm text-red-700",children:t})}function o(e){let{onNext:t}=e;return(0,s.jsxs)("div",{children:[(0,s.jsx)("h2",{className:"mb-2 text-2xl font-bold text-slate-900",children:"Step 1: Account Setup"}),(0,s.jsx)("p",{className:"mb-6 text-slate-600",children:"Before registering your first agent, make sure you have the AgentIdP server running."}),(0,s.jsx)("ol",{className:"mb-8 space-y-4",children:[{n:1,title:"Clone the repository",code:"git clone https://github.com/sentryagent/sentryagent-idp.git"},{n:2,title:"Copy environment variables",code:"cp .env.example .env"},{n:3,title:"Start the server",code:"docker compose up -d && npm run db:migrate"},{n:4,title:"Verify the server is healthy",code:"curl http://localhost:3000/health"}].map(e=>{let{n:t,title:n,code:r}=e;return(0,s.jsxs)("li",{className:"flex gap-4",children:[(0,s.jsx)("span",{className:"mt-0.5 flex h-6 w-6 flex-shrink-0 items-center justify-center rounded-full bg-brand-600 text-xs font-bold text-white",children:t}),(0,s.jsxs)("div",{className:"flex-1",children:[(0,s.jsx)("p",{className:"mb-1 font-medium text-slate-800",children:n}),(0,s.jsxs)("div",{className:"flex items-center rounded-lg bg-slate-900 px-3 py-2",children:[(0,s.jsx)("code",{className:"flex-1 text-sm text-slate-100",children:r}),(0,s.jsx)(l,{text:r})]})]})]},t)})}),(0,s.jsx)("button",{onClick:t,className:"rounded-lg bg-brand-600 px-6 py-2.5 font-semibold text-white transition-colors hover:bg-brand-700",children:"My server is running →"})]})}function d(e){let{agentName:t,onAgentNameChange:n,agentId:r,loading:a,error:o,onRegister:d,onNext:c}=e;return(0,s.jsxs)("div",{children:[(0,s.jsx)("h2",{className:"mb-2 text-2xl font-bold text-slate-900",children:"Step 2: Register Your Agent"}),(0,s.jsx)("p",{className:"mb-6 text-slate-600",children:"Give your agent a name and register it with AgentIdP. You will receive a unique Agent ID."}),o&&(0,s.jsx)(i,{message:o}),r?(0,s.jsxs)("div",{className:"mb-6 rounded-xl border border-green-200 bg-green-50 p-6",children:[(0,s.jsx)("p",{className:"mb-1 text-sm font-semibold text-green-700",children:"Agent registered successfully!"}),(0,s.jsxs)("div",{className:"flex items-center gap-2",children:[(0,s.jsxs)("p",{className:"text-sm text-slate-700",children:["Agent ID:"," ",(0,s.jsx)("code",{className:"rounded bg-slate-100 px-1.5 py-0.5 font-mono text-sm",children:r})]}),(0,s.jsx)(l,{text:r})]})]}):(0,s.jsxs)("div",{className:"mb-6",children:[(0,s.jsx)("label",{htmlFor:"agent-name",className:"mb-1.5 block text-sm font-medium text-slate-700",children:"Agent Name"}),(0,s.jsxs)("div",{className:"flex gap-3",children:[(0,s.jsx)("input",{id:"agent-name",type:"text",value:t,onChange:e=>n(e.target.value),placeholder:"e.g. my-summarisation-agent",className:"flex-1 rounded-lg border border-slate-300 px-4 py-2.5 text-sm focus:border-brand-500 focus:outline-none focus:ring-2 focus:ring-brand-200"}),(0,s.jsx)("button",{onClick:d,disabled:a||""===t.trim(),className:"rounded-lg bg-brand-600 px-5 py-2.5 text-sm font-semibold text-white transition-colors hover:bg-brand-700 disabled:cursor-not-allowed disabled:opacity-50",children:a?"Registering…":"Register Agent"})]})]}),r&&(0,s.jsx)("button",{onClick:c,className:"rounded-lg bg-brand-600 px-6 py-2.5 font-semibold text-white transition-colors hover:bg-brand-700",children:"Generate Credentials →"})]})}function c(e){let{agentId:t,clientId:n,clientSecret:r,loading:a,error:o,onGenerate:d,onNext:c}=e;return(0,s.jsxs)("div",{children:[(0,s.jsx)("h2",{className:"mb-2 text-2xl font-bold text-slate-900",children:"Step 3: Generate Credentials"}),(0,s.jsxs)("p",{className:"mb-6 text-slate-600",children:["Generate OAuth 2.0 client credentials for agent"," ",(0,s.jsx)("code",{className:"rounded bg-slate-100 px-1.5 py-0.5 text-sm",children:t}),". Store your client secret securely — it will not be shown again."]}),o&&(0,s.jsx)(i,{message:o}),n&&r?(0,s.jsx)("div",{className:"mb-6 space-y-4",children:(0,s.jsxs)("div",{className:"rounded-xl border border-brand-200 bg-brand-50 p-5",children:[(0,s.jsx)("p",{className:"mb-3 text-sm font-semibold text-brand-700",children:"Credentials generated. Store these securely!"}),(0,s.jsxs)("div",{className:"space-y-3",children:[(0,s.jsxs)("div",{children:[(0,s.jsx)("p",{className:"mb-1 text-xs font-semibold uppercase tracking-wider text-slate-500",children:"Client ID"}),(0,s.jsxs)("div",{className:"flex items-center gap-2 rounded-lg bg-white px-3 py-2 shadow-sm",children:[(0,s.jsx)("code",{className:"flex-1 break-all font-mono text-sm text-slate-800",children:n}),(0,s.jsx)(l,{text:n})]})]}),(0,s.jsxs)("div",{children:[(0,s.jsx)("p",{className:"mb-1 text-xs font-semibold uppercase tracking-wider text-slate-500",children:"Client Secret"}),(0,s.jsxs)("div",{className:"flex items-center gap-2 rounded-lg bg-white px-3 py-2 shadow-sm",children:[(0,s.jsx)("code",{className:"flex-1 break-all font-mono text-sm text-slate-800",children:r}),(0,s.jsx)(l,{text:r})]})]})]})]})}):(0,s.jsx)("button",{onClick:d,disabled:a,className:"mb-6 rounded-lg bg-brand-600 px-6 py-2.5 font-semibold text-white transition-colors hover:bg-brand-700 disabled:cursor-not-allowed disabled:opacity-50",children:a?"Generating…":"Generate Credentials"}),n&&r&&(0,s.jsx)("button",{onClick:c,className:"rounded-lg bg-brand-600 px-6 py-2.5 font-semibold text-white transition-colors hover:bg-brand-700",children:"Choose Your SDK →"})]})}let x=[{id:"nodejs",label:"Node.js / TypeScript",description:"npm install @sentryagent/idp-sdk"},{id:"python",label:"Python",description:"pip install sentryagent-idp"},{id:"go",label:"Go",description:"go get github.com/sentryagent/idp-sdk-go"},{id:"java",label:"Java",description:"Maven / Gradle — ai.sentryagent:idp-sdk:1.0.0"}];function m(e){let{selectedSdk:t,onSdkChange:n,clientId:r,clientSecret:a,apiUrl:i}=e,o=function(e,t,n,s){switch(e){case"nodejs":return"import { AgentIdPClient } from '@sentryagent/idp-sdk';\n\nconst client = new AgentIdPClient({\n apiUrl: '".concat(t,"',\n clientId: '").concat(n,"',\n clientSecret: '").concat(s,"',\n});\n\nconst { accessToken } = await client.tokens.issue();\nconsole.log('Access token:', accessToken);");case"python":return'from sentryagent_idp import AgentIdPClient\n\nclient = AgentIdPClient(\n api_url="'.concat(t,'",\n client_id="').concat(n,'",\n client_secret="').concat(s,'",\n)\n\ntoken_response = client.tokens.issue()\nprint("Access token:", token_response.access_token)');case"go":return'import idp "github.com/sentryagent/idp-sdk-go"\n\nclient := idp.NewClient(idp.Config{\n APIURL: "'.concat(t,'",\n ClientID: "').concat(n,'",\n ClientSecret: "').concat(s,'",\n})\n\ntoken, err := client.Tokens.Issue(ctx)\nif err != nil {\n panic(err)\n}\nfmt.Println("Access token:", token.AccessToken)');case"java":return'AgentIdPClient client = AgentIdPClient.builder()\n .apiUrl("'.concat(t,'")\n .clientId("').concat(n,'")\n .clientSecret("').concat(s,'")\n .build();\n\nTokenResponse token = client.tokens().issue();\nSystem.out.println("Access token: " + token.getAccessToken());');default:return""}}(t,i,r,a);return(0,s.jsxs)("div",{children:[(0,s.jsx)("h2",{className:"mb-2 text-2xl font-bold text-slate-900",children:"Step 4: Choose Your SDK"}),(0,s.jsx)("p",{className:"mb-6 text-slate-600",children:"Select your language and copy the ready-to-run code snippet below. Your credentials are pre-filled."}),(0,s.jsx)("div",{className:"mb-6 grid grid-cols-2 gap-3 sm:grid-cols-4",children:x.map(e=>{let{id:r,label:a,description:l}=e;return(0,s.jsxs)("button",{onClick:()=>n(r),className:["rounded-xl border p-4 text-left transition-all",t===r?"border-brand-500 bg-brand-50 shadow-md":"border-slate-200 bg-white hover:border-brand-300 hover:bg-brand-50"].join(" "),children:[(0,s.jsx)("p",{className:["mb-1 text-sm font-semibold",t===r?"text-brand-700":"text-slate-800"].join(" "),children:a}),(0,s.jsx)("p",{className:"text-xs text-slate-500",children:l})]},r)})}),(0,s.jsxs)("div",{children:[(0,s.jsxs)("div",{className:"mb-2 flex items-center justify-between",children:[(0,s.jsx)("p",{className:"text-sm font-semibold uppercase tracking-wider text-slate-500",children:"Ready-to-run code"}),(0,s.jsx)(l,{text:o})]}),(0,s.jsx)("pre",{className:"overflow-x-auto rounded-xl bg-slate-900 px-5 py-5 text-sm leading-relaxed text-slate-100",children:(0,s.jsx)("code",{children:o})})]}),(0,s.jsxs)("div",{className:"mt-8 rounded-xl border border-green-200 bg-green-50 p-5 text-center",children:[(0,s.jsx)("p",{className:"text-lg font-bold text-green-800",children:"You are all set!"}),(0,s.jsx)("p",{className:"mt-1 text-sm text-green-700",children:"Your agent is registered and you have credentials. Start making authenticated API calls using the snippet above."})]})]})}function g(e){let{apiUrl:t}=e,[n,l]=(0,r.useState)({step:1,agentName:"",agentId:null,clientId:null,clientSecret:null,selectedSdk:"nodejs",loading:!1,error:null}),i=e=>{l(t=>({...t,step:e,error:null}))},x=async()=>{l(e=>({...e,loading:!0,error:null}));try{let s=await fetch("".concat(t,"/agents"),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({name:n.agentName.trim()})});if(!s.ok){var e;let t=await s.json();throw Error(null!==(e=t.message)&&void 0!==e?e:"HTTP ".concat(s.status))}let r=await s.json();l(e=>({...e,agentId:r.agentId,loading:!1,error:null}))}catch(e){l(t=>({...t,loading:!1,error:e instanceof Error?e.message:"Failed to register agent"}))}},g=async()=>{if(n.agentId){l(e=>({...e,loading:!0,error:null}));try{let s=await fetch("".concat(t,"/agents/").concat(n.agentId,"/credentials"),{method:"POST",headers:{"Content-Type":"application/json"}});if(!s.ok){var e;let t=await s.json();throw Error(null!==(e=t.message)&&void 0!==e?e:"HTTP ".concat(s.status))}let r=await s.json();l(e=>({...e,clientId:r.clientId,clientSecret:r.clientSecret,loading:!1,error:null}))}catch(e){l(t=>({...t,loading:!1,error:e instanceof Error?e.message:"Failed to generate credentials"}))}}};return(0,s.jsxs)("div",{className:"mx-auto max-w-3xl",children:[(0,s.jsx)("div",{className:"mb-2 flex gap-2 text-xs font-medium text-slate-500",children:["Account Setup","Register Agent","Generate Credentials","Choose SDK"].map((e,t)=>(0,s.jsx)("span",{className:["flex-1 text-center",t+1===n.step?"font-bold text-brand-700":""].join(" "),children:e},e))}),(0,s.jsx)(a,{current:n.step,total:4}),(0,s.jsxs)("div",{className:"rounded-2xl border border-slate-200 bg-white p-8 shadow-sm",children:[1===n.step&&(0,s.jsx)(o,{onNext:()=>i(2)}),2===n.step&&(0,s.jsx)(d,{agentName:n.agentName,onAgentNameChange:e=>{l(t=>({...t,agentName:e}))},agentId:n.agentId,loading:n.loading,error:n.error,onRegister:()=>void x(),onNext:()=>i(3)}),3===n.step&&n.agentId&&(0,s.jsx)(c,{agentId:n.agentId,clientId:n.clientId,clientSecret:n.clientSecret,loading:n.loading,error:n.error,onGenerate:()=>void g(),onNext:()=>i(4)}),4===n.step&&n.clientId&&n.clientSecret&&(0,s.jsx)(m,{selectedSdk:n.selectedSdk,onSdkChange:e=>{l(t=>({...t,selectedSdk:e}))},clientId:n.clientId,clientSecret:n.clientSecret,apiUrl:t})]})]})}}},function(e){e.O(0,[971,23,744],function(){return e(e.s=79045)}),_N_E=e.O()}]);