@zaip-ai/cli 7.5.0 → 7.6.0
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 +12 -20
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +2 -2
- package/dist/commands/init.js.map +1 -1
- package/dist/services/adapters.d.ts +1 -1
- package/dist/services/adapters.js +1 -1
- package/dist/services/codex-task-delivery-authority-template.d.ts.map +1 -1
- package/dist/services/codex-task-delivery-authority-template.js +39 -1
- package/dist/services/codex-task-delivery-authority-template.js.map +1 -1
- package/dist/services/global-codex-project-trust.d.ts +1 -1
- package/dist/services/global-codex-project-trust.d.ts.map +1 -1
- package/dist/services/global-codex-project-trust.js +46 -11
- package/dist/services/global-codex-project-trust.js.map +1 -1
- package/dist/services/global-codex-project-trust.test.js +35 -4
- package/dist/services/global-codex-project-trust.test.js.map +1 -1
- package/dist/services/install-agents-template.js +2 -2
- package/dist/services/install-agents-template.js.map +1 -1
- package/dist/services/install-target-windows.test.d.ts +2 -0
- package/dist/services/install-target-windows.test.d.ts.map +1 -0
- package/dist/services/install-target-windows.test.js +39 -0
- package/dist/services/install-target-windows.test.js.map +1 -0
- package/dist/services/install-target.d.ts +6 -0
- package/dist/services/install-target.d.ts.map +1 -0
- package/dist/services/install-target.js +89 -0
- package/dist/services/install-target.js.map +1 -0
- package/dist/services/install-target.test.d.ts +2 -0
- package/dist/services/install-target.test.d.ts.map +1 -0
- package/dist/services/install-target.test.js +47 -0
- package/dist/services/install-target.test.js.map +1 -0
- package/dist/services/logger.js +5 -3
- package/dist/services/logger.js.map +1 -1
- package/package.json +1 -1
- package/templates/.agents/config/agents/discovery.json +1 -1
- package/templates/.agents/dashboard/.zaip-managed.json +72 -32
- package/templates/.agents/dashboard/apps/frontend/dist/assets/{ProjectSettingsPage-BCsdQtWG.js → ProjectSettingsPage-86kLUrXm.js} +1 -1
- package/templates/.agents/dashboard/apps/frontend/dist/assets/{TraceabilityWorkspace-BN8FwP5S.js → TraceabilityWorkspace-BZ1rH1vl.js} +1 -1
- package/templates/.agents/dashboard/apps/frontend/dist/assets/{index-uIVtG2ZR.js → index-C4uiRYHu.js} +2 -2
- package/templates/.agents/dashboard/apps/frontend/dist/assets/{traceability-DFY7ZDlu.css → traceability-s5SzQnzt.css} +1 -1
- package/templates/.agents/dashboard/apps/frontend/dist/assets/traceability-vQx9R6BQ.js +1 -0
- package/templates/.agents/dashboard/apps/frontend/dist/index.html +3 -3
- package/templates/.agents/dashboard/apps/frontend/e2e/release-delivery-fixture.mjs +117 -0
- package/templates/.agents/dashboard/apps/frontend/e2e/release-delivery-lab.mjs +246 -0
- package/templates/.agents/dashboard/apps/frontend/e2e/release-delivery-receipt.mjs +65 -0
- package/templates/.agents/dashboard/apps/frontend/package.json +1 -1
- package/templates/.agents/dashboard/apps/frontend/src/dashboard-runtime-status.ts +5 -1
- package/templates/.agents/dashboard/apps/frontend/src/release-delivery.test.tsx +78 -0
- package/templates/.agents/dashboard/apps/frontend/src/use-runtime-status.dom.test.ts +28 -6
- package/templates/.agents/dashboard/apps/frontend/src/use-runtime-status.ts +18 -7
- package/templates/.agents/dashboard/modules/cost-monitor/package.json +1 -1
- package/templates/.agents/dashboard/modules/operations/package.json +1 -1
- package/templates/.agents/dashboard/modules/traceability/package.json +1 -1
- package/templates/.agents/dashboard/modules/traceability/src/contracts.ts +11 -0
- package/templates/.agents/dashboard/modules/traceability/src/react/ReleaseDeliveryPanel.tsx +60 -0
- package/templates/.agents/dashboard/modules/traceability/src/react/TaskTracePanel.tsx +9 -57
- package/templates/.agents/dashboard/modules/traceability/src/react/release-delivery-panel.css +26 -0
- package/templates/.agents/dashboard/modules/traceability/src/react/trace-date-format.ts +33 -0
- package/templates/.agents/dashboard/modules/traceability/src/react/trace-stage-labels.ts +28 -0
- package/templates/.agents/dashboard/packages/branding/package.json +1 -1
- package/templates/.agents/dashboard/packages/contracts/package.json +1 -1
- package/templates/.agents/dashboard/packages/data-export/package.json +1 -1
- package/templates/.agents/dashboard/packages/local-runtime/dist/server.cjs +236 -235
- package/templates/.agents/dashboard/packages/local-runtime/dist/sqlite-read-model.cjs +81 -81
- package/templates/.agents/dashboard/packages/local-runtime/package.json +1 -1
- package/templates/.agents/dashboard/packages/local-runtime/server.mjs +236 -235
- package/templates/.agents/dashboard/packages/local-runtime/src/server-release-receipt.ts +71 -0
- package/templates/.agents/dashboard/packages/local-runtime/src/server-trace-release-delivery.ts +120 -0
- package/templates/.agents/dashboard/packages/local-runtime/src/server-trace-routes.ts +5 -4
- package/templates/.agents/dashboard/packages/ui/package.json +1 -1
- package/templates/.agents/dashboard/stack-dependencies.json +3 -3
- package/templates/.agents/dashboard/tests/e2e/package.json +1 -1
- package/templates/.agents/design/.zaip-managed.json +4 -4
- package/templates/.agents/design/apps/catalog/package.json +1 -1
- package/templates/.agents/design/design-system-maker/build.json +94 -79
- package/templates/.agents/design/packages/local-runtime/package.json +1 -1
- package/templates/.agents/requirements/autonomous-assurance.md +1 -1
- package/templates/.agents/requirements/cloud-hostinger-autonomy.md +1 -1
- package/templates/.agents/requirements/comparative-audit.md +1 -1
- package/templates/.agents/requirements/context-engine.md +1 -1
- package/templates/.agents/requirements/cost-observability.md +1 -1
- package/templates/.agents/requirements/dashboard-launch.md +1 -1
- package/templates/.agents/requirements/data-export.md +1 -1
- package/templates/.agents/requirements/design-system.md +1 -1
- package/templates/.agents/requirements/execution-engine.md +1 -1
- package/templates/.agents/requirements/kanban-dashboard.md +1 -1
- package/templates/.agents/requirements/landing-page-forms.md +1 -1
- package/templates/.agents/requirements/model-orchestration.md +1 -1
- package/templates/.agents/requirements/public-distribution.md +1 -1
- package/templates/.agents/requirements/site-performance.md +1 -1
- package/templates/.agents/requirements/software-architecture.md +1 -1
- package/templates/.agents/requirements/strategic-improvements.md +1 -1
- package/templates/.agents/requirements/work-lifecycle.md +1 -1
- package/templates/.agents/requirements/zaip-strategic-95.md +1 -1
- package/templates/.agents/runtime/VERSION +1 -1
- package/templates/.agents/runtime/bin/historical-catalog-b6b6516200bdb412c92063e887ccef329d7c5193b5610cba5346e97c71301394.mjs +318 -0
- package/templates/.agents/runtime/bin/zaip.mjs +149 -109
- package/templates/.agents/runtime/checksums.sha256 +6 -5
- package/templates/.agents/runtime/manifest.json +2 -1
- package/templates/.agents/runtime/provenance.json +4 -4
- package/templates/.agents/runtime/sbom.cdx.json +1 -1
- package/templates/.agents/skills/zaip-skill-github-deploy/scripts/deploy-contract.mjs +49 -70
- package/templates/.agents/skills/zaip-skill-github-deploy/scripts/deploy-idempotent-intent.test.mjs +39 -0
- package/templates/.agents/skills/zaip-skill-github-deploy/scripts/deployment-next-release.mjs +57 -0
- package/templates/.agents/skills/zaip-skill-github-deploy/scripts/deployment-request.mjs +15 -0
- package/templates/.agents/skills/zaip-skill-github-deploy/scripts/publication-intent.mjs +4 -1
- package/templates/.agents/skills/zaip-skill-github-deploy/scripts/publication-proof-runtime/chunks/{chunk-A3ZCURGS.mjs → chunk-CJ5ZQF6M.mjs} +6 -6
- package/templates/.agents/skills/zaip-skill-github-deploy/scripts/publication-proof-runtime/chunks/{chunk-ZOGCYGYB.mjs → chunk-EQTZ3Y7R.mjs} +1 -1
- package/templates/.agents/skills/zaip-skill-github-deploy/scripts/publication-proof-runtime/chunks/chunk-FMNUSV2P.mjs +139 -0
- package/templates/.agents/skills/zaip-skill-github-deploy/scripts/publication-proof-runtime/chunks/{chunk-7SBOEN6U.mjs → chunk-LWS3QVJO.mjs} +2 -2
- package/templates/.agents/skills/zaip-skill-github-deploy/scripts/publication-proof-runtime/lifecycle-records.mjs +1 -1
- package/templates/.agents/skills/zaip-skill-github-deploy/scripts/publication-proof-runtime/manifest.json +14 -13
- package/templates/.agents/skills/zaip-skill-github-deploy/scripts/publication-proof-runtime/native-authority.mjs +1 -1
- package/templates/.agents/skills/zaip-skill-github-deploy/scripts/publication-proof-runtime/proof.mjs +1 -1
- package/templates/.agents/skills/zaip-skill-github-deploy/scripts/publication-proof-runtime/run-records.mjs +1 -1
- package/templates/.agents/skills/zaip-skill-github-deploy/scripts/publication-proof-schema.mjs +1 -1
- package/templates/.agents/zaip-aios/VERSION +1 -1
- package/templates/template-manifest.json +141 -92
- package/templates/.agents/dashboard/apps/frontend/dist/assets/traceability-Boz50W9b.js +0 -1
- package/templates/.agents/skills/zaip-skill-github-deploy/scripts/publication-proof-runtime/chunks/chunk-NJOFXS7P.mjs +0 -137
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{n as e}from"./rolldown-runtime-Bh1tDfsg.js";import{C as t,E as n,S as r,c as i,d as a,f as o,l as s,m as c,p as l,s as u,u as d,w as f,x as p}from"./cost-monitor-YfoKMzCQ.js";import{a as m,c as h,d as g,f as _,i as v,l as y,m as b,n as x,o as S,p as C,r as w,s as T,t as E,u as D}from"./icons-vendor-DSdQAua1.js";var O=e(n(),1);function k(e,t){if(e===null)return`—`;let n=new Date(e);return Number.isNaN(n.getTime())?`—`:new Intl.DateTimeFormat(t,{dateStyle:`short`,timeStyle:`short`}).format(n)}function A(e,t){if(e===null)return`—`;let n=Date.parse(e);if(!Number.isFinite(n))return`—`;let r=Math.max(0,Date.now()-n),i=Math.max(1,Math.round(r/6e4)),a;if(i<60)a=`${i}m`;else{let e=Math.round(i/60);if(e<24)a=`${e}h`;else{let n=Math.round(e/24);if(n<7)a=`${n}d`;else{let e=Math.round(n/7);a=t===`pt-BR`?`${e}sem`:`${e}w`}}}return t===`pt-BR`?`Há ${a}`:`${a} ago`}var j=f();function M({delivery:e,locale:t}){let n=t===`pt-BR`,r=[[`Task`,e.task_status],[`Change`,e.change_status],[`Execution`,e.execution_status]],i=r.every(([,e])=>e===`completed`),a=e.publication===`verified`;return(0,j.jsxs)(`section`,{className:`trace-release-delivery`,"aria-label":n?`Entrega da versão`:`Release delivery`,children:[(0,j.jsx)(`h3`,{children:n?`Entrega da versão`:`Release delivery`}),(0,j.jsxs)(`dl`,{children:[(0,j.jsxs)(`div`,{children:[(0,j.jsx)(`dt`,{children:n?`Publicação`:`Publication`}),(0,j.jsx)(`dd`,{children:a?n?`Confirmada`:`Verified`:n?`Sem confirmação`:`Unverified`})]}),(0,j.jsxs)(`div`,{children:[(0,j.jsx)(`dt`,{children:n?`Fechamento no ZAIP`:`ZAIP closure`}),(0,j.jsx)(`dd`,{children:i?n?`Concluído`:`Completed`:n?`Pendente`:`Pending`})]}),r.map(([e,t])=>(0,j.jsxs)(`div`,{children:[(0,j.jsx)(`dt`,{children:e}),(0,j.jsx)(`dd`,{children:t??(n?`Sem registro`:`Unrecorded`)})]},e))]}),e.blocker&&(0,j.jsxs)(`p`,{children:[(0,j.jsx)(`strong`,{children:n?`Bloqueio`:`Blocker`}),` · `,e.blocker]}),e.next_action&&(0,j.jsxs)(`p`,{children:[(0,j.jsx)(`strong`,{children:n?`Próxima ação`:`Next action`}),` · `,e.next_action]}),e.receipt_path&&(0,j.jsxs)(`p`,{children:[(0,j.jsx)(`strong`,{children:n?`Comprovante`:`Receipt`}),` · `,(0,j.jsx)(`code`,{children:e.receipt_path})]})]})}function N({ariaLabel:e,closeLabel:t,document:n,onClose:r}){return(0,j.jsxs)(`section`,{"aria-label":e,"aria-modal":`true`,className:`trace-document`,role:`dialog`,children:[(0,j.jsxs)(`header`,{children:[(0,j.jsxs)(`div`,{children:[(0,j.jsx)(`small`,{children:n.path}),(0,j.jsx)(`h2`,{children:n.title})]}),(0,j.jsx)(`button`,{"aria-label":t,className:`trace-close-button`,onClick:r,type:`button`,children:(0,j.jsx)(u,{"aria-hidden":`true`,size:20,strokeWidth:2})})]}),(0,j.jsx)(`pre`,{children:n.content})]})}function P({stage:e,stageRecord:t,documents:n,stageCopy:r,stageArtifacts:i,copy:a,onBack:o,onOpenDocument:s,onStageChange:u}){let d=[`definition`,`planning`,`execution`,`decisions`,`verification`,`evidence`],f=d.indexOf(e),p=d[f-1],h=d[f+1],g=n.filter(e=>e.kind===`evidence`).length,_=new Set(n.map(e=>e.kind)).size,v=new Map;for(let e of n)v.set(e.kind,[...v.get(e.kind)??[],e]);let y=t?.last_recorded_at??a.pending;return(0,j.jsxs)(`section`,{className:`trace-stage-detail`,children:[(0,j.jsx)(`header`,{children:(0,j.jsxs)(`div`,{children:[(0,j.jsx)(`p`,{children:r[e].label}),(0,j.jsx)(`h3`,{children:i[e]}),(0,j.jsx)(`small`,{children:y})]})}),(0,j.jsxs)(`div`,{className:`trace-stage-metrics`,children:[(0,j.jsxs)(`article`,{children:[(0,j.jsx)(`span`,{children:a.documents}),(0,j.jsx)(`strong`,{children:n.length})]}),(0,j.jsxs)(`article`,{children:[(0,j.jsx)(`span`,{children:a.types}),(0,j.jsx)(`strong`,{children:_})]}),(0,j.jsxs)(`article`,{children:[(0,j.jsx)(`span`,{children:a.evidenceMetric}),(0,j.jsx)(`strong`,{children:g})]})]}),(0,j.jsx)(`div`,{className:`trace-stage-documents`,children:n.length===0?(0,j.jsx)(`p`,{className:`trace-stage-empty`,children:a.empty}):[...v].map(([e,t])=>(0,j.jsxs)(`section`,{className:`trace-document-group`,children:[(0,j.jsxs)(`h4`,{children:[e,` `,(0,j.jsx)(`small`,{children:t.length})]}),t.map(e=>(0,j.jsxs)(`button`,{onClick:()=>s(e),type:`button`,children:[(0,j.jsx)(`strong`,{children:e.title}),(0,j.jsx)(`small`,{children:e.path})]},e.id))]},e))}),(0,j.jsxs)(`nav`,{"aria-label":a.navigation,className:`trace-stage-navigation`,children:[(0,j.jsxs)(`button`,{className:`trace-navigation-action trace-navigation-previous`,disabled:f===0,onClick:()=>u(d[f-1]),type:`button`,children:[(0,j.jsx)(c,{"aria-hidden":`true`,size:18,strokeWidth:1.9}),(0,j.jsxs)(`span`,{children:[(0,j.jsx)(`small`,{children:a.previous}),(0,j.jsx)(`strong`,{children:p?r[p].label.split(` (`)[0]:`—`})]})]}),(0,j.jsxs)(`div`,{className:`trace-navigation-center`,children:[(0,j.jsx)(`div`,{"aria-hidden":`true`,className:`trace-navigation-progress`,children:d.map((t,n)=>(0,j.jsx)(`span`,{"data-active":t===e,"data-passed":n<f},t))}),(0,j.jsxs)(`small`,{children:[f+1,` `,a.of,` `,d.length]}),(0,j.jsxs)(`button`,{className:`trace-all-stages-button`,onClick:o,type:`button`,children:[(0,j.jsx)(m,{"aria-hidden":`true`,size:15,strokeWidth:1.9}),a.back]})]}),(0,j.jsxs)(`button`,{className:`trace-navigation-action trace-navigation-next`,disabled:f===d.length-1,onClick:()=>u(d[f+1]),type:`button`,children:[(0,j.jsxs)(`span`,{children:[(0,j.jsx)(`small`,{children:a.next}),(0,j.jsx)(`strong`,{children:h?r[h].label.split(` (`)[0]:`—`})]}),(0,j.jsx)(l,{"aria-hidden":`true`,size:18,strokeWidth:1.9})]})]})]})}function F({ariaLabel:e,children:t,closeLabel:n,onClose:r}){return(0,O.useEffect)(()=>{let e=e=>{e.key===`Escape`&&r()};return window.addEventListener(`keydown`,e),()=>window.removeEventListener(`keydown`,e)},[r]),(0,j.jsxs)(`div`,{className:`trace-stage-dialog-backdrop`,role:`presentation`,children:[(0,j.jsx)(`button`,{"aria-label":n,className:`trace-stage-dialog-backdrop-dismiss`,onClick:r,type:`button`}),(0,j.jsxs)(`section`,{"aria-label":e,"aria-modal":`true`,className:`trace-stage-dialog`,role:`dialog`,children:[(0,j.jsx)(`button`,{"aria-label":n,className:`trace-stage-dialog-close`,onClick:r,type:`button`,children:(0,j.jsx)(u,{"aria-hidden":`true`,size:22})}),t]})]})}var I=[`definition`,`planning`,`execution`,`decisions`,`verification`,`evidence`],L={definition:`PRD · Requisitos`,planning:`SPEC · Change`,execution:`Tarefas · DAG · Runs · arquivos`,decisions:`Decisões do planejamento e da execução`,verification:`Testes · revisões · evals · checks`,evidence:`Evidências · resultados · rastreabilidade`},R={definition:`PRD · Requirements`,planning:`SPEC · Change`,execution:`Tasks · DAG · Runs · files`,decisions:`Planning and execution decisions`,verification:`Tests · reviews · evals · checks`,evidence:`Evidence · results · traceability`},z=[`task`,`change`,`spec`,`prd`],B=[`coverage`,`documents`,`evidence`,`links`],V={"pt-BR":{lite:`Leve`,standard:`Padrão`,critical:`Crítico`},"en-US":{lite:`Lite`,standard:`Standard`,critical:`Critical`}},H={definition:D,planning:d,execution:w,decisions:S,verification:x,evidence:h};function U(e,t){return[{label:`Task`,value:e.task_id,onOpen:void 0},{label:`Change`,value:e.change_id,onOpen:t.onOpenChange},{label:`SPEC`,value:e.spec_id,onOpen:t.onOpenSpec},{label:`PRD`,value:e.prd_id,onOpen:t.onOpenPrd}]}var W={definition:{label:`Definição (PRD + Requisitos)`,description:`Objetivo, contexto e critérios que definem o trabalho.`},planning:{label:`Planejamento (SPEC + Change)`,description:`Escopo, solução e mudanças previstas antes da execução.`},execution:{label:`Execução (Tarefas ou DAG)`,description:`Tarefas, dependências da DAG, Runs e arquivos produzidos.`},decisions:{label:`Decisões (Plano e Execução)`,description:`Decisões humanas e da IA tomadas no planejamento e na execução.`},verification:{label:`Verificação (Testes + Revisões)`,description:`Testes, revisões, evals e checks comparam o resultado aos Critérios de Aceite.`},evidence:{label:`Evidências (Resultados + Rastreabilidade)`,description:`Provas reproduzíveis vinculadas às Tasks, Changes, Runs e Critérios de Aceite.`}},G={definition:{label:`Definition (PRD + Requirements)`,description:`Objective, context, and criteria that define the work.`},planning:{label:`Planning (SPEC + Change)`,description:`Scope, solution, and changes planned before execution.`},execution:{label:`Execution (Tasks or DAG)`,description:`Tasks, DAG dependencies, Runs, and produced files.`},decisions:{label:`Decisions (Plan and Execution)`,description:`Human and AI decisions made during planning and execution.`},verification:{label:`Verification (Tests + Reviews)`,description:`Tests, reviews, evals, and checks compare results with acceptance criteria.`},evidence:{label:`Evidence (Results + Traceability)`,description:`Reproducible proof linked to Tasks, Changes, Runs, and acceptance criteria.`}},K={"pt-BR":{aria:`Rastreabilidade da task`,coverage:`etapas rastreadas`,evidence:`evidências`,close:`Fechar`,empty:`Nenhum documento relacionado.`,closeDocument:`Fechar documento`,back:`Voltar às etapas`,previous:`Anterior`,next:`Próxima`,documents:`Documentos`,types:`Tipos`,evidenceMetric:`Evidências`,taskFirst:`Task-first`,specDriven:`Spec-driven`,copyId:`Copiar ID`,copied:`ID copiado`,unlinked:`Não vinculado`,recorded:`Registrada em`,pending:`Pendente`,missingTimestamp:`Sem data/hora`,tests:`testes registrados`,time:`Tempo`,tokens:`Tokens`,cost:`Custo`,measuredRuns:`Runs medidas`,items:`itens`,navigation:`Navegação entre etapas`,of:`de`,stageDetails:`Detalhes da etapa`,document:`Documento`},"en-US":{aria:`Task traceability`,coverage:`tracked stages`,evidence:`evidence items`,close:`Close`,empty:`No related document.`,closeDocument:`Close document`,back:`Back to stages`,previous:`Previous`,next:`Next`,documents:`Documents`,types:`Types`,evidenceMetric:`Evidence`,taskFirst:`Task-first`,specDriven:`Spec-driven`,copyId:`Copy ID`,copied:`ID copied`,unlinked:`Not linked`,recorded:`Recorded at`,pending:`Pending`,missingTimestamp:`Missing date/time`,tests:`recorded tests`,time:`Time`,tokens:`Tokens`,cost:`Cost`,measuredRuns:`measured Runs`,items:`items`,navigation:`Stage navigation`,of:`of`,stageDetails:`Stage details`,document:`Document`}};function q({taskId:e,locale:t=`pt-BR`}){let n=t===`pt-BR`;return(0,j.jsx)(`div`,{className:`trace-backdrop`,children:(0,j.jsxs)(`section`,{"aria-busy":`true`,"aria-label":n?`Carregando rastreabilidade`:`Loading traceability`,"aria-live":`polite`,className:`trace-panel trace-loading-panel`,role:`dialog`,children:[(0,j.jsxs)(`header`,{className:`trace-panel-header`,children:[(0,j.jsxs)(`div`,{className:`trace-heading`,children:[(0,j.jsx)(`span`,{className:`trace-heading-icon trace-loading-icon`,"aria-hidden":`true`,children:(0,j.jsx)(s,{size:22,strokeWidth:1.8})}),(0,j.jsxs)(`div`,{className:`trace-task-summary-content`,children:[(0,j.jsx)(`h2`,{children:n?`Carregando rastreabilidade`:`Loading traceability`}),(0,j.jsx)(`p`,{children:e})]})]}),(0,j.jsxs)(`span`,{className:`trace-loading-status`,children:[(0,j.jsx)(s,{"aria-hidden":`true`,size:15,strokeWidth:2}),n?`Preparando trace`:`Preparing trace`]})]}),(0,j.jsx)(`div`,{className:`trace-loading-identifiers`,"aria-hidden":`true`,children:z.map(e=>(0,j.jsx)(`span`,{},e))}),(0,j.jsx)(`div`,{className:`trace-loading-metrics`,"aria-hidden":`true`,children:B.map(e=>(0,j.jsx)(`span`,{},e))}),(0,j.jsx)(`div`,{className:`trace-loading-stages`,"aria-hidden":`true`,children:I.map(e=>(0,j.jsx)(`span`,{},e))})]})})}function J({trace:e,locale:t=`pt-BR`,onClose:n,onOpenChange:r,onOpenPrd:s,onOpenSpec:c,embedded:d=!1}){let[f,p]=(0,O.useState)(null),[m,h]=(0,O.useState)(null),[S,w]=(0,O.useState)(!1),D=K[t],z=t===`en-US`?G:W,B=t===`en-US`?R:L,q=(0,O.useMemo)(()=>new Map(I.map(t=>[t,e.documents.filter(e=>e.stage===t)])),[e.documents]),J=(0,O.useMemo)(()=>new Map(e.stages.map(e=>[e.stage,e])),[e.stages]),X=Math.round(e.coverage.stages_with_timestamps/e.coverage.total_stages*100),Z=[e.task_id,e.change_id,e.spec_id,e.prd_id].filter(Boolean).length,Q=U(e,{onOpenChange:r,onOpenPrd:s,onOpenSpec:c}),$=k(e.task_created_at,t),ee=A(e.task_created_at,t),te=async()=>{try{await navigator.clipboard.writeText(e.task_id),w(!0),window.setTimeout(()=>w(!1),2e3)}catch{w(!1)}};return(0,j.jsxs)(`div`,{className:d?`trace-embedded`:`trace-backdrop`,children:[(0,j.jsxs)(`section`,{"aria-label":D.aria,"aria-modal":d?void 0:`true`,className:`trace-panel`,role:`dialog`,children:[(0,j.jsxs)(`header`,{className:`trace-panel-header`,children:[(0,j.jsxs)(`div`,{className:`trace-heading`,children:[(0,j.jsx)(`span`,{className:`trace-heading-icon`,"aria-hidden":`true`,children:(0,j.jsx)(i,{size:22,strokeWidth:1.8})}),(0,j.jsxs)(`div`,{className:`trace-task-summary-content`,children:[(0,j.jsx)(`div`,{className:`trace-heading-title`,children:(0,j.jsxs)(`h2`,{children:[(0,j.jsx)(`span`,{className:`trace-title-prefix`,children:`Trace:`}),` `,e.task_title||e.task_id]})}),(0,j.jsx)(`p`,{children:t===`pt-BR`?`Visão completa do ciclo de desenvolvimento`:`Complete development lifecycle view`})]})]}),(0,j.jsxs)(`div`,{className:`trace-header-actions`,children:[(0,j.jsx)(Y,{copy:D,locale:t,usage:e.usage}),d?null:(0,j.jsx)(`button`,{className:`trace-close-button`,"aria-label":D.close,onClick:n,type:`button`,children:(0,j.jsx)(u,{"aria-hidden":`true`,size:20,strokeWidth:2})})]})]}),(0,j.jsxs)(`section`,{className:`trace-task-summary`,"aria-label":t===`pt-BR`?`Resumo da tarefa`:`Task summary`,children:[(0,j.jsxs)(`article`,{children:[(0,j.jsx)(C,{"aria-hidden":`true`,size:17,strokeWidth:1.8}),(0,j.jsxs)(`div`,{className:`trace-task-summary-content`,children:[(0,j.jsx)(`span`,{children:t===`pt-BR`?`Criada em`:`Created at`}),(0,j.jsx)(`strong`,{children:$})]})]}),(0,j.jsxs)(`article`,{children:[(0,j.jsx)(a,{"aria-hidden":`true`,size:17,strokeWidth:1.8}),(0,j.jsxs)(`div`,{className:`trace-task-summary-content`,children:[(0,j.jsx)(`span`,{children:t===`pt-BR`?`Desde a criação`:`Since creation`}),(0,j.jsx)(`strong`,{children:ee})]})]}),(0,j.jsxs)(`article`,{className:`trace-task-progress`,children:[(0,j.jsx)(g,{"aria-hidden":`true`,size:17,strokeWidth:1.8}),(0,j.jsxs)(`div`,{className:`trace-task-summary-content trace-task-progress-content`,children:[(0,j.jsx)(`span`,{children:t===`pt-BR`?`Progresso`:`Progress`}),(0,j.jsxs)(`strong`,{children:[e.task_progress,`%`]}),(0,j.jsx)(`progress`,{max:100,value:e.task_progress})]})]}),(0,j.jsxs)(`article`,{className:`trace-task-classification`,children:[(0,j.jsx)(b,{"aria-hidden":`true`,size:17,strokeWidth:1.8}),(0,j.jsxs)(`div`,{className:`trace-task-summary-content`,children:[(0,j.jsx)(`span`,{children:t===`pt-BR`?`Classificação`:`Classification`}),(0,j.jsxs)(`div`,{className:`trace-task-badges`,children:[(0,j.jsxs)(`span`,{className:`trace-mode-badge`,children:[(0,j.jsx)(E,{"aria-hidden":`true`,size:12,strokeWidth:2}),e.spec_id===null?D.taskFirst:D.specDriven]}),e.task_risk?(0,j.jsxs)(`span`,{className:`trace-risk-badge`,"data-risk":e.task_risk,children:[(0,j.jsx)(x,{"aria-hidden":`true`,size:12,strokeWidth:2}),V[t][e.task_risk]]}):null]})]})]})]}),e.release_delivery&&(0,j.jsx)(M,{delivery:e.release_delivery,locale:t}),(0,j.jsx)(`section`,{className:`trace-overview trace-lineage`,"aria-label":t===`pt-BR`?`Identificadores vinculados`:`Linked identifiers`,children:Q.map(({label:e,value:n,onOpen:r})=>{let i=n!==null&&r!==void 0,a=e===`Task`&&n!==null,o=(0,j.jsxs)(j.Fragment,{children:[(0,j.jsxs)(`div`,{className:`trace-identifier-content`,children:[(0,j.jsxs)(`span`,{children:[(0,j.jsx)(v,{"aria-hidden":`true`,size:11,strokeWidth:2}),e]}),(0,j.jsx)(`strong`,{title:n??D.unlinked,children:n??D.unlinked})]}),a?(0,j.jsx)(`button`,{"aria-label":S?t===`pt-BR`?`ID da tarefa copiado`:`Task ID copied`:t===`pt-BR`?`Copiar ID da tarefa`:`Copy task ID`,className:`trace-identifier-copy`,onClick:()=>void te(),title:S?t===`pt-BR`?`Copiado`:`Copied`:void 0,type:`button`,children:S?(0,j.jsx)(_,{"aria-hidden":`true`,size:15}):(0,j.jsx)(y,{"aria-hidden":`true`,size:15})}):null,i?(0,j.jsx)(l,{"aria-hidden":`true`,size:15,strokeWidth:1.9}):null]});return(0,j.jsx)(`article`,{"data-empty":n===null,"data-linked":n!==null,"data-navigable":i,children:i?(0,j.jsx)(`button`,{"aria-label":`${t===`pt-BR`?`Abrir`:`Open`} ${e}: ${n}`,className:`trace-identifier-navigation`,onClick:()=>r(n),type:`button`,children:o}):(0,j.jsx)(`div`,{className:`trace-identifier-static`,children:o})},e)})}),(0,j.jsxs)(`section`,{className:`trace-metrics`,"aria-label":t===`pt-BR`?`Resumo da rastreabilidade`:`Traceability summary`,children:[(0,j.jsxs)(`article`,{children:[(0,j.jsx)(`span`,{className:`trace-metric-icon`,children:(0,j.jsx)(i,{"aria-hidden":`true`,size:18})}),(0,j.jsxs)(`div`,{children:[(0,j.jsxs)(`strong`,{children:[X,`%`]}),(0,j.jsx)(`span`,{children:D.coverage})]}),(0,j.jsxs)(`small`,{children:[e.coverage.stages_with_timestamps,` `,D.of,` `,e.coverage.total_stages]})]}),(0,j.jsxs)(`article`,{children:[(0,j.jsx)(`span`,{className:`trace-metric-icon`,children:(0,j.jsx)(T,{"aria-hidden":`true`,size:18})}),(0,j.jsxs)(`div`,{children:[(0,j.jsx)(`strong`,{children:e.documents.length}),(0,j.jsx)(`span`,{children:D.documents})]}),(0,j.jsx)(`small`,{children:t===`pt-BR`?`no ciclo completo`:`in the full lifecycle`})]}),(0,j.jsxs)(`article`,{children:[(0,j.jsx)(`span`,{className:`trace-metric-icon`,children:(0,j.jsx)(b,{"aria-hidden":`true`,size:18})}),(0,j.jsxs)(`div`,{children:[(0,j.jsx)(`strong`,{children:e.coverage.evidence_count}),(0,j.jsx)(`span`,{children:D.evidenceMetric})]}),(0,j.jsxs)(`small`,{children:[e.coverage.test_count,` `,D.tests]})]}),(0,j.jsxs)(`article`,{children:[(0,j.jsx)(`span`,{className:`trace-metric-icon`,children:(0,j.jsx)(v,{"aria-hidden":`true`,size:18})}),(0,j.jsxs)(`div`,{children:[(0,j.jsx)(`strong`,{children:Z}),(0,j.jsx)(`span`,{children:t===`pt-BR`?`Vínculos`:`Links`})]}),(0,j.jsx)(`small`,{children:`Task · Change · SPEC · PRD`})]})]}),(0,j.jsx)(`div`,{className:`trace-stage-menu`,children:I.map((e,n)=>{let r=H[e],i=(q.get(e)??[]).length;return(0,j.jsxs)(`button`,{className:`trace-stage-menu-button`,"data-stage":e,onClick:()=>h(e),type:`button`,children:[(0,j.jsx)(`span`,{className:`trace-stage-number`,children:String(n+1).padStart(2,`0`)}),(0,j.jsx)(r,{className:`trace-stage-icon`,"aria-hidden":`true`,size:22,strokeWidth:1.8}),(0,j.jsx)(`strong`,{children:z[e].label}),(0,j.jsx)(`em`,{children:z[e].description}),(0,j.jsxs)(`span`,{className:`trace-stage-action`,children:[(0,j.jsxs)(`small`,{children:[(0,j.jsx)(o,{"aria-hidden":`true`,size:13}),` `,i,` `,D.items]}),(0,j.jsxs)(`span`,{children:[t===`pt-BR`?`Ver etapa`:`View stage`,(0,j.jsx)(l,{"aria-hidden":`true`,size:13,strokeWidth:2})]})]})]},e)})})]}),m?(0,j.jsx)(F,{ariaLabel:D.stageDetails,closeLabel:t===`pt-BR`?`Fechar detalhes da etapa`:`Close stage details`,onClose:()=>h(null),children:(0,j.jsx)(P,{copy:D,documents:q.get(m)??[],locale:t,onBack:()=>h(null),onOpenDocument:p,onStageChange:h,stage:m,stageArtifacts:B,stageRecord:J.get(m),stageCopy:z})}):null,f?(0,j.jsx)(N,{ariaLabel:`${D.document} ${f.title}`,closeLabel:D.closeDocument,document:f,onClose:()=>p(null)}):null]})}function Y({usage:e,locale:t,copy:n}){let i=[{label:n.time,metric:e.duration_ms,value:X(e.duration_ms.value,t)},{label:n.tokens,metric:e.total_tokens,value:e.total_tokens.value===null?`—`:p(e.total_tokens.value,t)},{label:n.cost,metric:e.cost,value:e.cost.value===null||e.cost.currency===null?`—`:r(e.cost.value,e.cost.currency,t)}];return(0,j.jsx)(`section`,{"aria-label":t===`pt-BR`?`Uso agregado da Task`:`Aggregated Task usage`,children:(0,j.jsx)(`dl`,{className:`trace-usage-strip`,children:i.map(({label:t,metric:r,value:i})=>{let a=Math.round(r.coverage_ratio*100),o=`${r.known_runs}/${e.run_count} ${n.measuredRuns} · ${a}%`;return(0,j.jsxs)(`div`,{title:o,children:[(0,j.jsxs)(`dt`,{children:[t,(0,j.jsx)(`span`,{"aria-hidden":`true`,className:`trace-usage-coverage`,"data-complete":r.unknown_runs===0}),(0,j.jsx)(`span`,{className:`trace-usage-sr-only`,children:o})]}),(0,j.jsx)(`dd`,{children:i})]},t)})})})}function X(e,n){return e===null?`—`:t(e,n)}export{J as n,q as t};
|
|
@@ -6,14 +6,14 @@
|
|
|
6
6
|
<meta name="color-scheme" content="dark light" />
|
|
7
7
|
<link rel="icon" type="image/png" href="/icon_zaip.png" />
|
|
8
8
|
<title>Dashboard Zaip AIOS</title>
|
|
9
|
-
<script type="module" crossorigin src="/assets/index-
|
|
9
|
+
<script type="module" crossorigin src="/assets/index-C4uiRYHu.js"></script>
|
|
10
10
|
<link rel="modulepreload" crossorigin href="/assets/rolldown-runtime-Bh1tDfsg.js">
|
|
11
11
|
<link rel="modulepreload" crossorigin href="/assets/cost-monitor-YfoKMzCQ.js">
|
|
12
12
|
<link rel="modulepreload" crossorigin href="/assets/react-vendor-rGvJzdn5.js">
|
|
13
13
|
<link rel="modulepreload" crossorigin href="/assets/icons-vendor-DSdQAua1.js">
|
|
14
|
-
<link rel="modulepreload" crossorigin href="/assets/traceability-
|
|
14
|
+
<link rel="modulepreload" crossorigin href="/assets/traceability-vQx9R6BQ.js">
|
|
15
15
|
<link rel="stylesheet" crossorigin href="/assets/cost-monitor-BESDS3aE.css">
|
|
16
|
-
<link rel="stylesheet" crossorigin href="/assets/traceability-
|
|
16
|
+
<link rel="stylesheet" crossorigin href="/assets/traceability-s5SzQnzt.css">
|
|
17
17
|
<link rel="stylesheet" crossorigin href="/assets/index-4cl5FQBn.css">
|
|
18
18
|
</head>
|
|
19
19
|
<body>
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import { mkdir, readFile, writeFile } from "node:fs/promises";
|
|
2
|
+
import { dirname, join } from "node:path";
|
|
3
|
+
import { deliveryReceipt } from "./release-delivery-receipt.mjs";
|
|
4
|
+
|
|
5
|
+
const when = "2026-01-01T02:30:00.000Z";
|
|
6
|
+
|
|
7
|
+
export async function createDeliveryFixture(root, createObservabilityFixture) {
|
|
8
|
+
const cases = await createObservabilityFixture(root);
|
|
9
|
+
const task = cases.find((item) => item.status === "completed");
|
|
10
|
+
const actor = cases.find((item) => item.status === "blocked");
|
|
11
|
+
const executionId = "EXEC-2026-01-01-00-00-LAB-DELIVERY-A001";
|
|
12
|
+
const records = join(root, ".agents/records");
|
|
13
|
+
const taskPath = join(records, "tasks/2026/01", task.task + ".md");
|
|
14
|
+
const taskContent = await readFile(taskPath, "utf8");
|
|
15
|
+
const hash = "a".repeat(64);
|
|
16
|
+
const ref = { revision: 1, hash, execution_id: executionId };
|
|
17
|
+
await writeFile(
|
|
18
|
+
taskPath,
|
|
19
|
+
taskContent.replace(
|
|
20
|
+
/^---\r?\n/,
|
|
21
|
+
'---\ntarget_release: "7.6"\nplan_ref: ' + JSON.stringify(ref) + "\n",
|
|
22
|
+
),
|
|
23
|
+
);
|
|
24
|
+
const executionPath = join(records, "executions/2026/01", executionId, "execution.md");
|
|
25
|
+
const decisions = join(records, "changes/2026/01", actor.change, "decisions");
|
|
26
|
+
const humanId = "DEC-HUMAN-2026-01-01-00-00-LAB-A001";
|
|
27
|
+
const receipt = await deliveryReceipt(root, task, actor, executionId, humanId);
|
|
28
|
+
async function put(path, fields) {
|
|
29
|
+
await mkdir(dirname(path), { recursive: true });
|
|
30
|
+
const markdown =
|
|
31
|
+
"---\n" +
|
|
32
|
+
Object.entries(fields)
|
|
33
|
+
.map(([key, value]) => key + ": " + JSON.stringify(value))
|
|
34
|
+
.join("\n") +
|
|
35
|
+
"\n---\n\n# Synthetic dashboard regression\n";
|
|
36
|
+
await writeFile(path, markdown);
|
|
37
|
+
}
|
|
38
|
+
function decision(id, origin, payload, confirmed = true) {
|
|
39
|
+
return put(join(decisions, id + ".md"), {
|
|
40
|
+
schema_version: 2,
|
|
41
|
+
id,
|
|
42
|
+
title: "Synthetic release attestation for local dashboard test",
|
|
43
|
+
scope_type: "change",
|
|
44
|
+
scope_id: actor.change,
|
|
45
|
+
origin,
|
|
46
|
+
category: "contract",
|
|
47
|
+
context: "Isolated test",
|
|
48
|
+
decision: JSON.stringify(payload),
|
|
49
|
+
reason: "Exercise the release projection",
|
|
50
|
+
alternatives: [],
|
|
51
|
+
consequences: ["Synthetic evidence"],
|
|
52
|
+
reversible: true,
|
|
53
|
+
rollback: "Discard fixture",
|
|
54
|
+
confidence: origin === "human" ? null : 1,
|
|
55
|
+
created_at: when,
|
|
56
|
+
confirmed_at: origin === "human" && confirmed ? when : null,
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
async function setExecution(status) {
|
|
60
|
+
await put(executionPath, {
|
|
61
|
+
schema_version: 2,
|
|
62
|
+
id: executionId,
|
|
63
|
+
revision: status === "completed" ? 2 : 1,
|
|
64
|
+
status,
|
|
65
|
+
status_reason: status === "blocked" ? "Synthetic open execution" : null,
|
|
66
|
+
policy: {
|
|
67
|
+
failure_policy: "stop_on_terminal_failure",
|
|
68
|
+
max_parallelism: 1,
|
|
69
|
+
max_operational_retries: 1,
|
|
70
|
+
max_repair_cycles_per_task: 0,
|
|
71
|
+
verification_mode: "scoped",
|
|
72
|
+
},
|
|
73
|
+
created_at: when,
|
|
74
|
+
updated_at: when,
|
|
75
|
+
started_at: when,
|
|
76
|
+
finished_at: status === "completed" ? when : null,
|
|
77
|
+
result: status === "completed" ? "Synthetic closure" : null,
|
|
78
|
+
kind: "delivery",
|
|
79
|
+
client_turn_id: "synthetic-turn",
|
|
80
|
+
origin: { type: "task", task_id: task.task },
|
|
81
|
+
plan_revision: 1,
|
|
82
|
+
plan_hash: hash,
|
|
83
|
+
dag: {
|
|
84
|
+
nodes: [{ task_id: task.task, change_id: task.change, depends_on: [] }],
|
|
85
|
+
topological_order: [task.task],
|
|
86
|
+
},
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
function authorize(target = task.task, confirmed = true) {
|
|
90
|
+
return decision(
|
|
91
|
+
humanId,
|
|
92
|
+
"human",
|
|
93
|
+
{ ...receipt.authorization, target_task_id: target },
|
|
94
|
+
confirmed,
|
|
95
|
+
);
|
|
96
|
+
}
|
|
97
|
+
async function issue() {
|
|
98
|
+
await receipt.write();
|
|
99
|
+
await decision(receipt.issuanceId, "agent", receipt.issuance);
|
|
100
|
+
}
|
|
101
|
+
await setExecution("blocked");
|
|
102
|
+
await authorize();
|
|
103
|
+
return {
|
|
104
|
+
taskId: task.task,
|
|
105
|
+
otherTaskId: actor.task,
|
|
106
|
+
receiptPath:
|
|
107
|
+
".agents/records/changes/2026/01/" +
|
|
108
|
+
actor.change +
|
|
109
|
+
"/decisions/" +
|
|
110
|
+
receipt.issuanceId +
|
|
111
|
+
".md",
|
|
112
|
+
authorize,
|
|
113
|
+
issue,
|
|
114
|
+
setExecution,
|
|
115
|
+
writeReceipt: receipt.write,
|
|
116
|
+
};
|
|
117
|
+
}
|
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
// Run from the checkout root after building the dashboard and CLI.
|
|
2
|
+
import assert from "node:assert/strict";
|
|
3
|
+
import { execFileSync, spawn } from "node:child_process";
|
|
4
|
+
import { randomBytes } from "node:crypto";
|
|
5
|
+
import { once } from "node:events";
|
|
6
|
+
import { mkdir, mkdtemp, realpath, rm, writeFile } from "node:fs/promises";
|
|
7
|
+
import { tmpdir } from "node:os";
|
|
8
|
+
import { basename, dirname, join, resolve } from "node:path";
|
|
9
|
+
import { setTimeout as delay } from "node:timers/promises";
|
|
10
|
+
import { chromium, expect } from "@playwright/test";
|
|
11
|
+
import { createObservabilityFixture } from "../../../tests/observability-fixture.mjs";
|
|
12
|
+
import { createDeliveryFixture } from "./release-delivery-fixture.mjs";
|
|
13
|
+
|
|
14
|
+
const repository = await realpath(process.cwd());
|
|
15
|
+
const temporary = await realpath(tmpdir());
|
|
16
|
+
const workspace = await mkdtemp(join(temporary, "zaip-v76-dashboard-"));
|
|
17
|
+
const token = randomBytes(24).toString("hex");
|
|
18
|
+
const dashboard = join(repository, ".agents/dashboard");
|
|
19
|
+
const runtime = join(dashboard, "packages/local-runtime");
|
|
20
|
+
const env = {
|
|
21
|
+
...process.env,
|
|
22
|
+
ZAIP_WORKSPACE: workspace,
|
|
23
|
+
ZAIP_SQLITE_DB_PATH: join(workspace, ".local/sqlite/dashboard.sqlite"),
|
|
24
|
+
ZAIP_UI_ROOT: resolve(process.env.ZAIP_LAB_UI_DIST || join(dashboard, "apps/frontend/dist")),
|
|
25
|
+
ZAIP_UI_TOKEN: token,
|
|
26
|
+
ZAIP_SERVER_PORT: "0",
|
|
27
|
+
ZAIP_DASHBOARD_WATCH_SOURCES: "0",
|
|
28
|
+
};
|
|
29
|
+
const output = process.env.ZAIP_LAB_EVIDENCE;
|
|
30
|
+
const observations = [];
|
|
31
|
+
let browser;
|
|
32
|
+
|
|
33
|
+
function privateCommand(command, args) {
|
|
34
|
+
return execFileSync(command, args, {
|
|
35
|
+
cwd: workspace,
|
|
36
|
+
env,
|
|
37
|
+
encoding: "utf8",
|
|
38
|
+
windowsHide: true,
|
|
39
|
+
maxBuffer: 4 * 1024 * 1024,
|
|
40
|
+
timeout: 90000,
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
function rebuildManifest() {
|
|
44
|
+
const result = JSON.parse(
|
|
45
|
+
privateCommand(process.execPath, [
|
|
46
|
+
join(repository, "packages/cli/dist/index.js"),
|
|
47
|
+
"manifest",
|
|
48
|
+
"rebuild",
|
|
49
|
+
"--confirm-full-scan",
|
|
50
|
+
"--workspace",
|
|
51
|
+
workspace,
|
|
52
|
+
"--json",
|
|
53
|
+
]),
|
|
54
|
+
);
|
|
55
|
+
assert.ok(result.indexed > 0 && result.indexed < 64, "unexpected fixture record count");
|
|
56
|
+
}
|
|
57
|
+
function refresh() {
|
|
58
|
+
rebuildManifest();
|
|
59
|
+
// Startup may serve its previous valid SQLite generation. Promote the new one through the shipped CLI.
|
|
60
|
+
privateCommand(process.execPath, [join(runtime, "scripts/rebuild-sqlite-read-model.mjs")]);
|
|
61
|
+
}
|
|
62
|
+
async function withPreview(inspect) {
|
|
63
|
+
const child = spawn(process.execPath, [join(runtime, "dist/server.cjs")], {
|
|
64
|
+
cwd: repository,
|
|
65
|
+
env,
|
|
66
|
+
windowsHide: true,
|
|
67
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
68
|
+
});
|
|
69
|
+
const closed = once(child, "close");
|
|
70
|
+
const lease = new AbortController();
|
|
71
|
+
let leaseReader;
|
|
72
|
+
let logs = "";
|
|
73
|
+
for (const stream of [child.stdout, child.stderr])
|
|
74
|
+
stream.on("data", (chunk) => {
|
|
75
|
+
logs = (logs + chunk).slice(-16384);
|
|
76
|
+
});
|
|
77
|
+
try {
|
|
78
|
+
await expect
|
|
79
|
+
.poll(
|
|
80
|
+
() => {
|
|
81
|
+
if (child.exitCode !== null) throw Error("preview exited before readiness");
|
|
82
|
+
return logs.match(/http:\/\/127\.0\.0\.1:\d+\/api\/v2\/health/)?.[0];
|
|
83
|
+
},
|
|
84
|
+
{ timeout: 45000 },
|
|
85
|
+
)
|
|
86
|
+
.toBeTruthy();
|
|
87
|
+
const origin = new URL(logs.match(/http:\/\/127\.0\.0\.1:\d+\/api\/v2\/health/)[0]).origin;
|
|
88
|
+
// The lab owns this preview until inspect completes. Acquire the standard
|
|
89
|
+
// launcher lease while Chromium opens a fresh context on this loopback port.
|
|
90
|
+
const deadline = setTimeout(() => lease.abort(), 10000);
|
|
91
|
+
try {
|
|
92
|
+
const response = await fetch(origin + "/api/v2/browser-lease?token=" + token, {
|
|
93
|
+
redirect: "error",
|
|
94
|
+
signal: lease.signal,
|
|
95
|
+
});
|
|
96
|
+
assert.equal(response.status, 200);
|
|
97
|
+
assert.match(response.headers.get("content-type") || "", /text\/event-stream/);
|
|
98
|
+
leaseReader = response.body.getReader();
|
|
99
|
+
const frame = await leaseReader.read();
|
|
100
|
+
assert.ok(!frame.done && frame.value.length > 0, "preview lease did not open");
|
|
101
|
+
} finally {
|
|
102
|
+
clearTimeout(deadline);
|
|
103
|
+
}
|
|
104
|
+
const readHealth = async () =>
|
|
105
|
+
(await fetch(origin + "/api/v2/health", { signal: AbortSignal.timeout(10000) })).json();
|
|
106
|
+
const started = Date.now();
|
|
107
|
+
const initial = await readHealth();
|
|
108
|
+
assert.equal(await realpath(initial.workspace), workspace);
|
|
109
|
+
let current = initial;
|
|
110
|
+
while (current.snapshot_state !== "current") {
|
|
111
|
+
assert.ok(!current.projection_refresh_failure, "preview snapshot refresh failed");
|
|
112
|
+
assert.ok(Date.now() - started < 30000, "preview snapshot did not become current");
|
|
113
|
+
await delay(100);
|
|
114
|
+
current = await readHealth();
|
|
115
|
+
}
|
|
116
|
+
console.log(
|
|
117
|
+
JSON.stringify({
|
|
118
|
+
pid: child.pid,
|
|
119
|
+
initial_snapshot: initial.snapshot_state,
|
|
120
|
+
final_snapshot: current.snapshot_state,
|
|
121
|
+
elapsed_ms: Date.now() - started,
|
|
122
|
+
}),
|
|
123
|
+
);
|
|
124
|
+
|
|
125
|
+
return await inspect(origin, child.pid);
|
|
126
|
+
} finally {
|
|
127
|
+
lease.abort();
|
|
128
|
+
leaseReader?.releaseLock();
|
|
129
|
+
if (child.exitCode === null && child.signalCode === null) child.kill();
|
|
130
|
+
await closed;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
async function see(origin, pid, fixture, phase, published, closed) {
|
|
135
|
+
const context = await browser.newContext({
|
|
136
|
+
locale: "pt-BR",
|
|
137
|
+
viewport: { width: 1365, height: 900 },
|
|
138
|
+
});
|
|
139
|
+
try {
|
|
140
|
+
const page = await context.newPage();
|
|
141
|
+
page.setDefaultTimeout(30000);
|
|
142
|
+
const path = "/api/v2/tasks/" + fixture.taskId + "/trace";
|
|
143
|
+
const received = [];
|
|
144
|
+
page.on("response", async (response) => {
|
|
145
|
+
if (response.ok() && new URL(response.url()).pathname === path)
|
|
146
|
+
received.push(await response.json());
|
|
147
|
+
});
|
|
148
|
+
await page.route("**/*", (route) =>
|
|
149
|
+
new URL(route.request().url()).origin === origin ? route.continue() : route.abort(),
|
|
150
|
+
);
|
|
151
|
+
await page.goto(origin + "/?token=" + token, { waitUntil: "domcontentloaded" });
|
|
152
|
+
await page
|
|
153
|
+
.getByRole("navigation", { name: "Áreas do dashboard" })
|
|
154
|
+
.getByRole("button", { name: /Rastreabilidade/ })
|
|
155
|
+
.click();
|
|
156
|
+
const search = page.getByRole("combobox", { name: "Buscar task por nome ou ID" });
|
|
157
|
+
await search.click();
|
|
158
|
+
await search.fill(fixture.taskId);
|
|
159
|
+
await page
|
|
160
|
+
.locator('[role="option"][id="traceability-task-option-' + fixture.taskId + '"]')
|
|
161
|
+
.click();
|
|
162
|
+
await expect.poll(() => received.at(-1)?.task_id, { timeout: 30000 }).toBe(fixture.taskId);
|
|
163
|
+
const delivery = received.at(-1).release_delivery;
|
|
164
|
+
assert.ok(delivery, "release projection missing on the real trace endpoint");
|
|
165
|
+
assert.equal(delivery.publication, published ? "verified" : "unverified");
|
|
166
|
+
assert.equal(delivery.execution_status, closed ? "completed" : "blocked");
|
|
167
|
+
assert.equal(delivery.receipt_path, published ? fixture.receiptPath : null);
|
|
168
|
+
const panel = page.getByRole("region", { name: "Entrega da versão" });
|
|
169
|
+
await expect(panel).toBeVisible();
|
|
170
|
+
await expect(panel).toContainText(published ? "Confirmada" : "Sem confirmação");
|
|
171
|
+
await expect(panel).toContainText(closed ? "Concluído" : "Pendente");
|
|
172
|
+
if (published) await expect(panel).toContainText(fixture.receiptPath);
|
|
173
|
+
else await expect(panel).not.toContainText(fixture.receiptPath);
|
|
174
|
+
if (!closed || !published) {
|
|
175
|
+
assert.ok(delivery.blocker && delivery.next_action);
|
|
176
|
+
await expect(panel).toContainText(delivery.blocker);
|
|
177
|
+
await expect(panel).toContainText(delivery.next_action);
|
|
178
|
+
}
|
|
179
|
+
if (output) await panel.screenshot({ path: join(output, phase + ".png") });
|
|
180
|
+
observations.push({
|
|
181
|
+
phase,
|
|
182
|
+
pid,
|
|
183
|
+
publication: delivery.publication,
|
|
184
|
+
execution: delivery.execution_status,
|
|
185
|
+
receipt: delivery.receipt_path,
|
|
186
|
+
});
|
|
187
|
+
} finally {
|
|
188
|
+
await context.close();
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
try {
|
|
193
|
+
// Explicit --workspace and a physical Git root keep the parent checkout out of all rebuilds.
|
|
194
|
+
assert.equal(dirname(await realpath(workspace)), temporary);
|
|
195
|
+
privateCommand("git", ["init", "--quiet"]);
|
|
196
|
+
assert.equal(
|
|
197
|
+
await realpath(privateCommand("git", ["rev-parse", "--show-toplevel"]).trim()),
|
|
198
|
+
workspace,
|
|
199
|
+
);
|
|
200
|
+
if (output) await mkdir(output, { recursive: true });
|
|
201
|
+
const fixture = await createDeliveryFixture(workspace, createObservabilityFixture);
|
|
202
|
+
browser = await chromium.launch();
|
|
203
|
+
const inspect = (phase, published, closed) =>
|
|
204
|
+
withPreview((origin, pid) => see(origin, pid, fixture, phase, published, closed));
|
|
205
|
+
refresh();
|
|
206
|
+
await inspect("missing-issuance", false, false);
|
|
207
|
+
await fixture.issue();
|
|
208
|
+
refresh();
|
|
209
|
+
await inspect("published-open", true, false);
|
|
210
|
+
await inspect("published-open-after-restart", true, false);
|
|
211
|
+
assert.notEqual(observations.at(-2).pid, observations.at(-1).pid);
|
|
212
|
+
await fixture.setExecution("completed");
|
|
213
|
+
refresh();
|
|
214
|
+
await inspect("closed", true, true);
|
|
215
|
+
await fixture.authorize(fixture.otherTaskId);
|
|
216
|
+
refresh();
|
|
217
|
+
await inspect("wrong-human-target", false, true);
|
|
218
|
+
await fixture.authorize();
|
|
219
|
+
refresh();
|
|
220
|
+
await fixture.writeReceipt(true);
|
|
221
|
+
await inspect("tampered-receipt-bytes", false, true);
|
|
222
|
+
await fixture.writeReceipt();
|
|
223
|
+
await fixture.authorize(fixture.taskId, false);
|
|
224
|
+
assert.throws(rebuildManifest, /Human decisions require explicit confirmation provenance/);
|
|
225
|
+
// Probe the read-only path with a corrupt source that the canonical writer refused.
|
|
226
|
+
privateCommand(process.execPath, [join(runtime, "scripts/rebuild-sqlite-read-model.mjs")]);
|
|
227
|
+
await inspect("unconfirmed-human-decision", false, true);
|
|
228
|
+
const report = JSON.stringify(
|
|
229
|
+
{
|
|
230
|
+
node: process.version,
|
|
231
|
+
chromium: browser.version(),
|
|
232
|
+
platform: process.platform,
|
|
233
|
+
fixture: "synthetic loopback",
|
|
234
|
+
observations,
|
|
235
|
+
},
|
|
236
|
+
null,
|
|
237
|
+
2,
|
|
238
|
+
);
|
|
239
|
+
if (output) await writeFile(join(output, "release-dashboard.json"), report + "\n");
|
|
240
|
+
console.log(report);
|
|
241
|
+
} finally {
|
|
242
|
+
if (browser) await browser.close();
|
|
243
|
+
const actual = await realpath(workspace);
|
|
244
|
+
assert.ok(dirname(actual) === temporary && basename(actual).startsWith("zaip-v76-dashboard-"));
|
|
245
|
+
await rm(actual, { recursive: true, force: true, maxRetries: 4, retryDelay: 200 });
|
|
246
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { mkdir, readFile, writeFile } from "node:fs/promises";
|
|
2
|
+
import { dirname, join, resolve } from "node:path";
|
|
3
|
+
import { pathToFileURL } from "node:url";
|
|
4
|
+
import { tsImport } from "tsx/esm/api";
|
|
5
|
+
|
|
6
|
+
export async function deliveryReceipt(root, task, actor, executionId, humanId) {
|
|
7
|
+
const { authorizationPayload, issuancePayload, readPostPublicationReceipt, sha } = await tsImport(
|
|
8
|
+
pathToFileURL(resolve("packages/cli/src/post-publication-receipt.ts")).href,
|
|
9
|
+
import.meta.url,
|
|
10
|
+
);
|
|
11
|
+
const base = {
|
|
12
|
+
schema_version: 3,
|
|
13
|
+
kind: "post_publication_closure",
|
|
14
|
+
actor_task_id: actor.task,
|
|
15
|
+
actor_execution_id: "EXEC-2026-01-01-00-00-ACTOR-LAB-A001",
|
|
16
|
+
actor_run_id: actor.run,
|
|
17
|
+
client_thread_id: "lab-thread",
|
|
18
|
+
client_turn_id: "lab-turn",
|
|
19
|
+
human_authorization_sha256: sha("authorized synthetic confirmation"),
|
|
20
|
+
target_task_id: task.task,
|
|
21
|
+
target_spec_id: null,
|
|
22
|
+
target_execution_id: executionId,
|
|
23
|
+
target_release: "7.6",
|
|
24
|
+
expected_task_revision: 1,
|
|
25
|
+
target_change_id: task.change,
|
|
26
|
+
expected_change_revision: 1,
|
|
27
|
+
expected_change_status: "blocked",
|
|
28
|
+
expected_spec_revision: null,
|
|
29
|
+
expected_spec_status: null,
|
|
30
|
+
expected_execution_revision: 1,
|
|
31
|
+
expected_execution_status: "blocked",
|
|
32
|
+
state_sha256: sha("lab initial state"),
|
|
33
|
+
proof: {
|
|
34
|
+
candidate_sha: "1".repeat(40),
|
|
35
|
+
published_sha: "1".repeat(40),
|
|
36
|
+
release_url: "https://github.com/zaip-ai/zaip-aios/releases/tag/v7.6",
|
|
37
|
+
ci_run_id: 101,
|
|
38
|
+
publish_run_id: 102,
|
|
39
|
+
cycle_sha256: sha("lab cycle"),
|
|
40
|
+
proof_content_sha256: sha("lab artifact inventory"),
|
|
41
|
+
npm_integrity: "sha512-" + Buffer.alloc(64, 1).toString("base64"),
|
|
42
|
+
release_asset_digest: "sha256:" + sha("lab asset"),
|
|
43
|
+
release_assets_sha256: sha("lab assets"),
|
|
44
|
+
evidence_ids: ["EVD-SYNTHETIC-FIXTURE"],
|
|
45
|
+
},
|
|
46
|
+
human_decision_id: humanId,
|
|
47
|
+
};
|
|
48
|
+
const issuanceId = "DEC-AI-POSTPUB-" + sha(JSON.stringify(base)).slice(0, 24).toUpperCase();
|
|
49
|
+
const receipt = { ...base, issuance_decision_id: issuanceId };
|
|
50
|
+
const issuance = JSON.parse(issuancePayload(receipt));
|
|
51
|
+
const locator =
|
|
52
|
+
".agents/private/state/recovery/post-publication/" + issuance.receipt_sha256 + ".json";
|
|
53
|
+
const path = join(root, locator);
|
|
54
|
+
await mkdir(dirname(path), { recursive: true });
|
|
55
|
+
async function write(tampered = false) {
|
|
56
|
+
const bytes = tampered ? { ...receipt, state_sha256: sha("changed after issuance") } : receipt;
|
|
57
|
+
await writeFile(path, JSON.stringify(bytes) + "\n");
|
|
58
|
+
if (!tampered)
|
|
59
|
+
await readPostPublicationReceipt(
|
|
60
|
+
{ readText: (file) => readFile(join(root, file), "utf8") },
|
|
61
|
+
locator,
|
|
62
|
+
);
|
|
63
|
+
}
|
|
64
|
+
return { issuanceId, issuance, authorization: authorizationPayload(receipt), write };
|
|
65
|
+
}
|
|
@@ -8,15 +8,19 @@ export interface DashboardRuntimeStatus {
|
|
|
8
8
|
projection_refresh_failure?: { code?: string; message?: string } | null;
|
|
9
9
|
}
|
|
10
10
|
|
|
11
|
+
export class TransientHealthError extends Error {}
|
|
12
|
+
|
|
11
13
|
export async function readDashboardRuntimeStatus(
|
|
12
14
|
signal: AbortSignal,
|
|
13
15
|
): Promise<DashboardRuntimeStatus> {
|
|
14
16
|
const response = await fetch("/api/v2/health", { cache: "no-store", signal });
|
|
17
|
+
if (response.status >= 500)
|
|
18
|
+
throw new TransientHealthError("Dashboard temporariamente indisponível");
|
|
19
|
+
if (!response.ok) throw new Error("Identidade do Dashboard indisponível");
|
|
15
20
|
const value = await response.json();
|
|
16
21
|
// Pending capture can report degraded while the snapshot is fully readable.
|
|
17
22
|
// A failed HTTP request must still be surfaced as a loading error.
|
|
18
23
|
if (
|
|
19
|
-
!response.ok ||
|
|
20
24
|
value?.kind !== "zaip-dashboard-sqlite-runtime" ||
|
|
21
25
|
typeof value.workspace !== "string" ||
|
|
22
26
|
typeof value.workspace_name !== "string" ||
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import type { TaskTrace } from "@zaip-ai/dashboard-traceability/contracts";
|
|
2
|
+
import { TaskTracePanel } from "@zaip-ai/dashboard-traceability/react";
|
|
3
|
+
import { renderToStaticMarkup } from "react-dom/server";
|
|
4
|
+
import { describe, expect, it } from "vitest";
|
|
5
|
+
|
|
6
|
+
const metric = { value: null, known_runs: 0, unknown_runs: 0, coverage_ratio: 0 };
|
|
7
|
+
const trace: TaskTrace = {
|
|
8
|
+
schema_version: 2,
|
|
9
|
+
layout_version: 3,
|
|
10
|
+
readonly: true,
|
|
11
|
+
source: ".agents/records",
|
|
12
|
+
task_id: "TASK-LAB",
|
|
13
|
+
task_title: "Laboratório",
|
|
14
|
+
task_risk: "standard",
|
|
15
|
+
task_created_at: null,
|
|
16
|
+
task_progress: 100,
|
|
17
|
+
spec_id: null,
|
|
18
|
+
prd_id: null,
|
|
19
|
+
change_id: "CHG-LAB",
|
|
20
|
+
usage: {
|
|
21
|
+
run_count: 0,
|
|
22
|
+
duration_ms: metric,
|
|
23
|
+
total_tokens: metric,
|
|
24
|
+
cost: { ...metric, currency: null },
|
|
25
|
+
},
|
|
26
|
+
stages: [],
|
|
27
|
+
documents: [],
|
|
28
|
+
coverage: {
|
|
29
|
+
stages_with_documents: 0,
|
|
30
|
+
stages_with_timestamps: 0,
|
|
31
|
+
total_stages: 6,
|
|
32
|
+
evidence_count: 0,
|
|
33
|
+
test_count: 0,
|
|
34
|
+
},
|
|
35
|
+
};
|
|
36
|
+
const delivery = {
|
|
37
|
+
publication: "verified" as const,
|
|
38
|
+
receipt_path: ".agents/example/receipt.json",
|
|
39
|
+
task_status: "completed",
|
|
40
|
+
change_status: "completed",
|
|
41
|
+
execution_status: "running",
|
|
42
|
+
blocker: "Execução em andamento",
|
|
43
|
+
next_action: "Verifique o recibo da execução.",
|
|
44
|
+
};
|
|
45
|
+
function render(input: Parameters<typeof TaskTracePanel>[0]["trace"]) {
|
|
46
|
+
return renderToStaticMarkup(<TaskTracePanel onClose={() => undefined} trace={input} />);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
describe("release delivery in the task trace", () => {
|
|
50
|
+
it("shows verified publication, actionable open closure and the receipt independently", () => {
|
|
51
|
+
const html = render({ ...trace, release_delivery: delivery });
|
|
52
|
+
expect(html).toContain("<dt>Publicação</dt><dd>Confirmada</dd>");
|
|
53
|
+
expect(html).toContain("<dt>Fechamento no ZAIP</dt><dd>Pendente</dd>");
|
|
54
|
+
expect(html).toContain(delivery.blocker);
|
|
55
|
+
expect(html).toContain(delivery.next_action);
|
|
56
|
+
expect(html).toContain(delivery.receipt_path);
|
|
57
|
+
});
|
|
58
|
+
it("does not infer publication from completed records or closure from a missing record", () => {
|
|
59
|
+
const completed = {
|
|
60
|
+
...delivery,
|
|
61
|
+
publication: "unverified" as const,
|
|
62
|
+
execution_status: "completed",
|
|
63
|
+
blocker: null,
|
|
64
|
+
next_action: null,
|
|
65
|
+
receipt_path: null,
|
|
66
|
+
};
|
|
67
|
+
const html = render({ ...trace, release_delivery: completed });
|
|
68
|
+
expect(html).toContain("<dt>Publicação</dt><dd>Sem confirmação</dd>");
|
|
69
|
+
expect(html).toContain("<dt>Fechamento no ZAIP</dt><dd>Concluído</dd>");
|
|
70
|
+
expect(html).not.toContain("<strong>Comprovante</strong>");
|
|
71
|
+
expect(render({ ...trace, release_delivery: { ...completed, change_status: null } })).toContain(
|
|
72
|
+
"<dt>Fechamento no ZAIP</dt><dd>Pendente</dd>",
|
|
73
|
+
);
|
|
74
|
+
});
|
|
75
|
+
it("keeps non-release and older traces unchanged", () => {
|
|
76
|
+
expect(render(trace)).not.toContain("Entrega da versão");
|
|
77
|
+
});
|
|
78
|
+
});
|