@miadi/connector 0.1.22 → 0.1.23
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/approve.d.ts +1 -0
- package/dist/approve.js +7 -2
- package/dist/decisions.d.ts +1 -1
- package/dist/decisions.js +7 -2
- package/dist/draft-review.d.ts +1 -0
- package/dist/draft-review.js +1 -1
- package/dist/mission-standard.d.ts +2 -0
- package/dist/mission-standard.js +2 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +1 -1
package/dist/approve.d.ts
CHANGED
package/dist/approve.js
CHANGED
|
@@ -147,7 +147,7 @@ export function runBrief(record, approver, sessions, instructions, providerAttrs
|
|
|
147
147
|
: []),
|
|
148
148
|
// A person may approve past an open question: the worker reads it, and says in its result what it could not settle (jgwill/Miadi#939).
|
|
149
149
|
...(openAspects.length
|
|
150
|
-
? ["", "These questions were open against the mission standard when it was approved. Settle what reading can settle, and say in your result what you could not:", "", "<open_questions>", ...openAspects.map((f) => text(`${f.aspect} ${f.name}: ${f.ask}`)), "</open_questions>"]
|
|
150
|
+
? ["", "These questions were open against the mission standard when it was approved. Settle what reading can settle, and say in your result what you could not:", "", "<open_questions>", ...openAspects.map((f) => text(`${f.aspect} ${f.name}: ${f.ask}${f.settled_by === "person" ? " Only the person can answer this: ask them, and do not assume it." : ""}`)), "</open_questions>"]
|
|
151
151
|
: []),
|
|
152
152
|
...(instructions
|
|
153
153
|
? [
|
|
@@ -956,7 +956,12 @@ function draftReviewSection(r, review, canAnswer = false) {
|
|
|
956
956
|
.join("");
|
|
957
957
|
const openCodes = new Set(open.map((f) => f.aspect));
|
|
958
958
|
const unchecked = review.not_checked.filter((n) => !openCodes.has(n.aspect));
|
|
959
|
-
const
|
|
959
|
+
const partly = unchecked.filter((n) => n.in_part);
|
|
960
|
+
const uncovered = unchecked.filter((n) => !n.in_part);
|
|
961
|
+
const uncheckedLine = [
|
|
962
|
+
...partly.map((n) => stateLine("Checked in part", EYE_PATHS, `Checked in part: <span class="code">${escapeHtml(n.aspect)}</span> ${escapeHtml(n.name)} (${escapeHtml(n.in_part)})`)),
|
|
963
|
+
...(uncovered.length ? [stateLine("Read it yourself", EYE_PATHS, `No check covers these, so read the mission for them: ${uncovered.map((n) => `<span class="code">${escapeHtml(n.aspect)}</span> ${escapeHtml(n.name)}`).join(" · ")}`)] : []),
|
|
964
|
+
].join("\n");
|
|
960
965
|
const heading = open.length ? `${open.length} open on the mission standard v${review.standard.version}` : `The mission standard v${review.standard.version}`;
|
|
961
966
|
return `<section class="standard" aria-label="The mission standard">
|
|
962
967
|
<h2>${escapeHtml(heading)}</h2>
|
package/dist/decisions.d.ts
CHANGED
|
@@ -19,4 +19,4 @@ export declare class DecisionTokens {
|
|
|
19
19
|
* and calls `decide_request` through the host. In a host without that bridge it
|
|
20
20
|
* shows each request's approval page instead.
|
|
21
21
|
*/
|
|
22
|
-
export declare const DECISIONS_CARD_HTML = "<!doctype html>\n<html lang=\"en\"><head><meta charset=\"utf-8\"><meta name=\"viewport\" content=\"width=device-width,initial-scale=1\">\n<style>\n:root{color-scheme:light dark;--fg:#1d1b18;--muted:#5b5650;--line:#d9d4cc;--accent:#7a4a00;--ok:#1d6b3a;--err:#b00020;--chip:#f1ede6}\n@media (prefers-color-scheme:dark){:root{--fg:#ece8e1;--muted:#b3ada4;--line:#3a3631;--accent:#ffd700;--ok:#7fd49b;--err:#ff8a80;--chip:#24211d}}\n*{box-sizing:border-box}\nbody{margin:0;color:var(--fg);font:15px/1.45 system-ui,sans-serif;background:transparent}\nmain{padding:12px;display:grid;gap:12px}\n.empty,.note{color:var(--muted)}\narticle{border:1px solid var(--line);border-radius:10px;padding:12px}\nh2{font-size:15px;margin:0 0 4px}\n.kind{display:inline-block;font-size:12px;padding:1px 8px;border-radius:999px;background:var(--chip);color:var(--muted);margin-bottom:6px}\n.meta{font-size:13px;color:var(--muted);margin:0 0 6px}\n.does{margin:6px 0;font-weight:600}\ndetails{margin:6px 0}\nsummary{cursor:pointer;color:var(--muted);font-size:13px}\npre{white-space:pre-wrap;overflow-wrap:anywhere;font-size:12px;margin:6px 0 0;max-height:240px;overflow:auto}\ntextarea{width:100%;min-height:64px;padding:8px;border:1px solid var(--line);border-radius:8px;background:transparent;color:var(--fg);font:inherit;margin-top:8px}\n.row{display:flex;flex-wrap:wrap;gap:8px;margin-top:8px}\nbutton{padding:8px 12px;border-radius:8px;border:1px solid var(--line);background:transparent;color:var(--fg);font:inherit;cursor:pointer;min-height:40px}\nbutton.primary{border-color:var(--accent);outline:1px solid var(--accent)}\nbutton:focus-visible,a:focus-visible,textarea:focus-visible{outline:2px solid var(--accent);outline-offset:2px}\nbutton[disabled]{opacity:.55;cursor:default}\na{color:inherit}\n.done{color:var(--ok);font-weight:600}\n.std{border-top:1px solid var(--line);margin:8px 0;padding-top:8px;display:grid;gap:8px}\nh3{font-size:14px;margin:0;font-weight:600}\n.aspects{list-style:none;margin:4px 0;padding:0;display:grid;gap:14px}\n.asp{display:grid;grid-template-columns:16px 1fr;gap:6px;font-size:14px;overflow-wrap:anywhere}\n.asp .gl{margin-top:3px;color:var(--muted);display:block}\n.asp p{margin:1px 0}\n.asp .nm{color:var(--muted)}\n.asp .ask{font-weight:600}\n.asp details{margin:0}\n.asp details[open]{border-left:2px solid var(--accent);padding-left:8px;margin-top:2px}\n.asp summary{padding:8px 0}\n.who{display:flex;gap:8px;align-items:center}\n.who .settler{flex:1}\n.yours .settler{color:var(--fg);font-weight:600}\n.yours .gl{color:var(--accent)}\n.iconbtn{min-height:34px;width:34px;padding:0;display:inline-grid;place-items:center;flex:none;border-color:var(--accent);color:var(--accent)}\n.openL{display:none}\ndetails[open]>summary .openL{display:inline}\ndetails[open]>summary .closedL{display:none}\n.fact{margin:0;font-size:14px;overflow-wrap:anywhere}\n.code{font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:13px}\n.small{font-size:13px;color:var(--muted);margin:0;overflow-wrap:anywhere}\nblockquote{margin:4px 0 0;padding-left:8px;border-left:2px solid var(--line);font-size:14px;overflow-wrap:anywhere}\nsummary:focus-visible{outline:2px solid var(--accent);outline-offset:2px}\n</style></head><body><main id=\"root\" aria-live=\"polite\"><p class=\"note\">Loading requests\u2026</p></main>\n<script>\n(function(){\n var root=document.getElementById(\"root\");\n var decided={};\n // A redraw while a decision is being recorded must not offer the buttons again.\n var pending={};\n var errors={};\n // A decision still running is followed to its outcome (jgwill/Miadi#924): one read every POLL_MS, at most POLL_MAX.\n var POLL_MS=3000,POLL_MAX=100,polls={};\n // An error that leaves the request open offers its approval page under it.\n var relink={};\n function el(tag,attrs,text){var e=document.createElement(tag);if(attrs)for(var k in attrs){if(k===\"class\")e.className=attrs[k];else e.setAttribute(k,attrs[k]);}if(text!=null)e.textContent=text;return e;}\n function host(){return window.openai||null;}\n function data(){var h=host();return h&&h.toolOutput?h.toolOutput:null;}\n function tokens(){var h=host();var m=h&&h.toolResponseMetadata;return (m&&m[\"miadi/decisionTokens\"])||{};}\n function render(){\n var d=data();root.textContent=\"\";\n if(!d){root.appendChild(el(\"p\",{class:\"note\"},\"Waiting for the request list.\"));return;}\n var list=d.decisions||[];\n if(!list.length){root.appendChild(el(\"p\",{class:\"empty\"},d.message||\"No request is waiting for a decision.\"));return;}\n if(!d.can_decide_here&&d.reason){root.appendChild(el(\"p\",{class:\"note\"},d.reason));}\n var t=tokens();\n list.forEach(function(r){root.appendChild(card(r,t[r.id]));});\n }\n // Where a request stands, as the connector projected it: the label, its lines, and the review it produced.\n function decidedBlock(d){\n var box=el(\"div\",{role:\"status\",class:d.cls});\n if(d.note)box.appendChild(el(\"p\",{class:\"line\"},d.note));\n box.appendChild(el(\"p\",{class:\"label\"},d.label));\n (d.lines||[]).forEach(function(l){box.appendChild(el(\"p\",{class:\"line\"},l));});\n if(d.url){var p=el(\"p\",{class:\"line\"});p.appendChild(el(\"a\",{href:d.url,target:\"_blank\",rel:\"noopener\"},d.url));box.appendChild(p);}\n return box;\n }\n function toolResult(res){\n var out=(res&&(res.structuredContent||res.structured_content))||null;\n if(!out&&res&&res.content&&res.content[0]&&res.content[0].text){try{out=JSON.parse(res.content[0].text);}catch(e){out={message:res.content[0].text};}}\n return out;\n }\n function projectionView(p,note){return {cls:p.stage===\"failed\"?\"fail\":[\"recording\",\"dispatching\"].indexOf(p.stage)!==-1?\"note\":\"done\",stage:p.stage,label:p.label,lines:p.lines||[],url:p.receipt_url||null,note:note||null};}\n // Read where a request stands. Still running: read again later. Never decided (the call was lost on the way): offer the decision again.\n function follow(r,lost){\n if(!host()||!host().callTool)return;\n polls[r.id]=(polls[r.id]||0)+1;\n host().callTool(\"get_run_result\",{record_id:r.id}).then(function(res){\n var out=toolResult(res);var p=out&&(out.projection||(out.data&&out.data.projection));\n if(!p){if(lost){delete decided[r.id];errors[r.id]=lost;}render();return;}\n if(p.stage===\"awaiting_decision\"){delete decided[r.id];if(lost)errors[r.id]=lost+\" Nothing was decided; decide again.\";render();return;}\n var note=decided[r.id]&&decided[r.id].note;\n decided[r.id]=projectionView(p,note);delete errors[r.id];render();\n if(p.stage===\"recording\"&&polls[r.id]<POLL_MAX)setTimeout(function(){follow(r);},POLL_MS);\n },function(err){\n if(lost){decided[r.id]={cls:\"note\",stage:\"recording\",label:\"Your decision may be recorded. Checking again\u2026\",lines:[],url:null,note:null};render();}\n if(polls[r.id]<POLL_MAX)setTimeout(function(){follow(r,lost);},POLL_MS);\n });\n }\n var SETTLED={drafter:\"The drafting agent can answer this.\",person:\"Only you can answer this. Write it under Instructions.\",bystander:\"Only the person deciding can answer this, in their instructions.\",local_agent:\"A local agent can settle this from the running system.\"};\n var ARROW='<svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" width=\"16\" height=\"16\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.9\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M12 17V3\"/><path d=\"m6 11 6 6 6-6\"/><path d=\"M19 21H5\"/></svg>';\n var DASHED='<path d=\"M10.1 2.182a10 10 0 0 1 3.8 0\"/><path d=\"M13.9 21.818a10 10 0 0 1-3.8 0\"/><path d=\"M17.609 3.721a10 10 0 0 1 2.69 2.7\"/><path d=\"M2.182 13.9a10 10 0 0 1 0-3.8\"/><path d=\"M20.279 17.609a10 10 0 0 1-2.7 2.69\"/><path d=\"M21.818 10.1a10 10 0 0 1 0 3.8\"/><path d=\"M3.721 6.391a10 10 0 0 1 2.7-2.69\"/><path d=\"M6.391 20.279a10 10 0 0 1-2.69-2.7\"/>';var EYE='<path d=\"M2.062 12.348a1 1 0 0 1 0-.696 10.75 10.75 0 0 1 19.876 0 1 1 0 0 1 0 .696 10.75 10.75 0 0 1-19.876 0\"/><circle cx=\"12\" cy=\"12\" r=\"3\"/>';\n function glyph(label,paths){return '<svg role=\"img\" aria-label=\"'+label+'\" viewBox=\"0 0 24 24\" width=\"16\" height=\"16\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.9\" stroke-linecap=\"round\" stroke-linejoin=\"round\">'+paths+'</svg>';}\n // A redraw rebuilds the card: what the person typed and which reasons they opened stay.\n var typed={};var whyOpen={};var boxes={};\n function stateLine(label,paths,build){var row=el(\"div\",{class:\"asp state\"});var g=el(\"span\",{class:\"gl\"});g.innerHTML=glyph(label,paths);row.appendChild(g);var t=el(\"p\",{class:\"small\"});build(t);row.appendChild(t);return row;}\n // The mission standard's open aspects, for the person deciding: what only they can answer first, and no verdict (jgwill/Miadi#939).\n function standardBlock(r,token){\n var rv=r.draft_review;\n var canAnswer=Boolean(token&&host()&&host().callTool);\n var s=el(\"section\",{class:\"std\",\"aria-label\":\"The mission standard\"});\n var list=rv?(rv.needs_revision||[]).slice().sort(function(a,b){var p=(b.settled_by===\"person\"?1:0)-(a.settled_by===\"person\"?1:0);return p||String(a.aspect).localeCompare(String(b.aspect));}):[];\n var version=rv&&rv.standard?\" v\"+rv.standard.version:\"\";\n s.appendChild(el(\"h3\",null,list.length?list.length+\" open on the mission standard\"+version:\"The mission standard\"+version));\n if(r.delivery){\n var place=el(\"p\",{class:\"fact\"});place.appendChild(el(\"span\",{class:\"small\"},\"The result lands at: \"));var disputed=list.some(function(f){return f.aspect===\"S1\";});\n place.appendChild(el(\"span\",disputed?{class:\"small\"}:null,r.delivery));\n if(disputed)place.appendChild(el(\"span\",{class:\"small\"},\" (S1 below asks about this)\"));\n s.appendChild(place);\n }\n if(r.person_words){var w=el(\"div\");w.appendChild(el(\"p\",{class:\"small\"},\"The person's words, as the drafting agent quoted them:\"));w.appendChild(el(\"blockquote\",null,r.person_words));s.appendChild(w);}\n if(!rv){s.appendChild(stateLine(\"Read it yourself\",EYE,function(t){t.textContent=\"No check ran on this version of the mission. Read it yourself.\";}));return s;}\n if(!list.length)s.appendChild(stateLine(\"Nothing flagged\",DASHED,function(t){t.textContent=\"Nothing flagged on the aspects checked.\";}));\n else{\n var ul=el(\"ul\",{class:\"aspects\"});\n list.forEach(function(f){\n var mine=f.settled_by===\"person\"&&canAnswer;\n var row=el(\"li\",{class:\"asp\"+(mine?\" yours\":\"\")});\n var g=el(\"span\",{class:\"gl\"});g.innerHTML=glyph(\"Open aspect\",DASHED);row.appendChild(g);\n var t=el(\"div\");\n var name=el(\"p\",{class:\"nm\"});name.appendChild(el(\"span\",{class:\"code\"},f.aspect));name.appendChild(el(\"span\",null,\" \"+f.name));t.appendChild(name);\n t.appendChild(el(\"p\",{class:\"ask\"},f.ask));\n if(f.span&&f.span!==r.delivery)t.appendChild(el(\"p\",{class:\"small\"},\"The mission says: \"+f.span));\n if(f.note)t.appendChild(el(\"p\",{class:\"small\"},f.note));\n var who=el(\"div\",{class:\"who\"});\n who.appendChild(el(\"p\",{class:\"small settler\"},(f.settled_by===\"person\"&&!canAnswer?SETTLED.bystander:SETTLED[f.settled_by])||f.settled_by));\n if(mine){\n var go=el(\"button\",{type:\"button\",class:\"iconbtn\",\"aria-label\":\"Go to Instructions\",title:\"Go to Instructions\"});go.innerHTML=ARROW;\n go.addEventListener(\"click\",function(){var box=boxes[r.id];if(box){if(box.scrollIntoView)box.scrollIntoView({block:\"center\"});box.focus();}});\n who.appendChild(go);\n }\n t.appendChild(who);\n var key=r.id+\"/\"+f.aspect;\n var why=el(\"details\");if(whyOpen[key])why.setAttribute(\"open\",\"\");\n why.addEventListener(\"toggle\",function(){whyOpen[key]=why.open;});\n var sum=el(\"summary\");sum.appendChild(el(\"span\",{class:\"closedL\"},\"Why\"));sum.appendChild(el(\"span\",{class:\"openL\"},\"Hide why\"));why.appendChild(sum);\n why.appendChild(el(\"p\",{class:\"small\"},f.why));\n var by=String(f.checked_by||\"\").split(\" \")[0]===\"jev\"?\"Jev\":f.checked_by===\"code\"?\"a check in code\":\"the \"+f.checked_by;\n why.appendChild(el(\"p\",{class:\"small\"},\"Flagged by \"+by+\".\"));\n t.appendChild(why);\n row.appendChild(t);ul.appendChild(row);\n });\n s.appendChild(ul);\n }\n var open={};list.forEach(function(f){open[f.aspect]=true;});\n var rest=(rv.not_checked||[]).filter(function(n){return !open[n.aspect];});\n if(rest.length)s.appendChild(stateLine(\"Read it yourself\",EYE,function(t){\n t.appendChild(el(\"span\",null,\"No check covers these, so read the mission for them: \"));\n rest.forEach(function(n,i){if(i)t.appendChild(el(\"span\",null,\" \u00B7 \"));t.appendChild(el(\"span\",{class:\"code\"},n.aspect));t.appendChild(el(\"span\",null,\" \"+n.name));});\n }));\n if(canAnswer&&list.some(function(f){return f.settled_by===\"drafter\";}))s.appendChild(el(\"p\",{class:\"small\"},\"To put the drafting agent's questions to it, say what to revise under Instructions and send it back.\"));\n if(canAnswer&&list.length)s.appendChild(el(\"p\",{class:\"small\"},\"Approving as it stands starts the session, and the worker reads these questions with the task.\"));\n return s;\n }\n function card(r,token){\n var a=el(\"article\",{\"aria-label\":r.title});\n a.appendChild(el(\"span\",{class:\"kind\"},r.kind_label||r.kind));\n a.appendChild(el(\"h2\",null,r.title));\n a.appendChild(el(\"p\",{class:\"meta\"},\"Asked by \"+r.by+(r.via?\" through \"+r.via:\"\")+\" \u00B7 \"+new Date(r.created_at).toLocaleString()+(r.circle?\" \u00B7 \"+r.circle+\" circle\":\"\")));\n a.appendChild(el(\"p\",{class:\"does\"},r.consequence));\n if(r.intention)a.appendChild(el(\"p\",null,r.intention));\n if(!decided[r.id]&&!pending[r.id]&&r.projection&&r.projection.stage===\"awaiting_decision\"&&(r.kind===\"run_request\"||r.kind===\"work_proposal\"||r.draft_review||r.delivery||r.person_words))a.appendChild(standardBlock(r,token));\n var det=el(\"details\");det.appendChild(el(\"summary\",null,\"What exactly is asked\"));det.appendChild(el(\"pre\",null,r.detail||\"\"));a.appendChild(det);\n var status=el(\"p\",{role:\"status\"});\n if(r.projection&&r.projection.stage!==\"awaiting_decision\"&&(!decided[r.id]||[\"recording\",\"dispatching\"].indexOf(r.projection.stage)===-1)){decided[r.id]=projectionView(r.projection);}\n if(decided[r.id]){\n var shown=decided[r.id];a.appendChild(decidedBlock(shown));\n if(shown.stage===\"recording\"&&polls[r.id]===undefined&&host()&&host().callTool){polls[r.id]=0;setTimeout(function(){follow(r);},POLL_MS);}\n if([\"recording\",\"dispatching\"].indexOf(shown.stage)!==-1&&host()&&host().callTool){\n var refresh=el(\"button\",{type:\"button\"},\"Refresh status\");\n refresh.addEventListener(\"click\",function(){\n refresh.disabled=true;\n host().callTool(\"get_run_result\",{record_id:r.id}).then(function(res){\n var out=toolResult(res);var p=out&&(out.projection||(out.data&&out.data.projection));\n if(p){decided[r.id]=projectionView(p);delete errors[r.id];}\n else{errors[r.id]=(out&&out.message)||\"Status could not be refreshed.\";}\n render();\n },function(err){errors[r.id]=\"Status could not be refreshed: \"+String(err&&err.message||err);render();});\n });\n a.appendChild(refresh);\n }\n if(errors[r.id])a.appendChild(el(\"p\",{class:\"fail\",role:\"status\"},errors[r.id]));\n return a;\n }\n function approvalLink(){var p=el(\"p\",{class:\"note\"});p.appendChild(document.createTextNode(\"Decide on its approval page: \"));p.appendChild(el(\"a\",{href:r.approval_url,target:\"_blank\",rel:\"noopener\"},\"open the approval page\"));return p;}\n if(pending[r.id]){status.className=\"note\";status.textContent=\"Recording your decision\u2026\";a.appendChild(status);return a;}\n if(!token||!host()||!host().callTool){a.appendChild(approvalLink());return a;}\n var ta=el(\"textarea\",{\"aria-label\":\"Instructions or changes (needed to approve with changes or send back)\",placeholder:\"Instructions or changes (needed to approve with changes or send back)\"});\n ta.value=typed[r.id]||\"\";boxes[r.id]=ta;\n ta.addEventListener(\"input\",function(){typed[r.id]=ta.value;});\n a.appendChild(ta);\n var row=el(\"div\",{class:\"row\"});\n // The ring on a mission would move with its report and read as a verdict, so a mission's buttons carry none (jgwill/Miadi#939).\n var mission=r.kind===\"run_request\"||r.kind===\"work_proposal\";\n var buttons=[[\"approve\",\"Approve\",mission?\"\":\"primary\"],[\"approve_with_changes\",\"Approve with my changes\",\"\"],[\"request_revision\",\"Send back for revision\",\"\"],[\"decline\",\"Decline\",\"\"]];\n var btns=[];\n buttons.forEach(function(b){var x=el(\"button\",{type:\"button\",class:b[2]},b[1]);x.addEventListener(\"click\",function(){go(b[0]);});btns.push(x);row.appendChild(x);});\n a.appendChild(row);a.appendChild(status);\n if(errors[r.id]){status.className=\"fail\";status.textContent=errors[r.id];if(relink[r.id])a.appendChild(approvalLink());}\n function go(choice){\n var text=ta.value.trim();\n if((choice===\"approve_with_changes\"||choice===\"request_revision\")&&!text){status.className=\"fail\";status.textContent=choice===\"request_revision\"?\"Say what to revise.\":\"Write the changes to apply.\";ta.focus();return;}\n btns.forEach(function(x){x.disabled=true;});status.className=\"note\";status.textContent=\"Recording your decision\u2026\";pending[r.id]=true;delete errors[r.id];\n host().callTool(\"decide_request\",{record_id:r.id,decision:choice,instructions:text||undefined,decision_token:token}).then(function(res){\n var out=toolResult(res);\n // The connector answers with the request's projection, also when a click finds it decided already.\n var proj=out&&(out.projection||(out.detail&&out.detail.projection));\n var code=out&&out.error;\n delete pending[r.id];\n // The token expired or the request was revised, and it still awaits a decision: say so and keep it open.\n if(code&&(!proj||proj.stage===\"awaiting_decision\")){errors[r.id]=(out&&out.message)||\"Not recorded.\";relink[r.id]=true;render();return;}\n var note=out&&out.replayed?\"This decision was already recorded. Nothing ran again.\":code===\"decision_conflict\"?\"A different decision was recorded first. Here is where it stands.\":code===\"already_decided\"?\"This request was already decided. Here is where it stands.\":null;\n if(proj){decided[r.id]=projectionView(proj,note);}\n else{decided[r.id]={cls:code?\"fail\":\"done\",label:code?((out&&out.message)||\"Not recorded.\"):((out&&out.summary)||\"Recorded.\"),lines:[],url:null,note:null};}\n render();\n },function(err){\n // The host gave up waiting; the connector may still have recorded it. Read before offering the buttons again (#924).\n delete pending[r.id];\n decided[r.id]={cls:\"note\",stage:\"recording\",label:\"Checking whether your decision was recorded\u2026\",lines:[],url:null,note:null};\n polls[r.id]=0;render();\n follow(r,\"Not recorded: \"+(err&&err.message?err.message:String(err))+\".\");\n });\n }\n return a;\n }\n window.addEventListener(\"openai:set_globals\",render);\n render();\n})();\n</script></body></html>";
|
|
22
|
+
export declare const DECISIONS_CARD_HTML = "<!doctype html>\n<html lang=\"en\"><head><meta charset=\"utf-8\"><meta name=\"viewport\" content=\"width=device-width,initial-scale=1\">\n<style>\n:root{color-scheme:light dark;--fg:#1d1b18;--muted:#5b5650;--line:#d9d4cc;--accent:#7a4a00;--ok:#1d6b3a;--err:#b00020;--chip:#f1ede6}\n@media (prefers-color-scheme:dark){:root{--fg:#ece8e1;--muted:#b3ada4;--line:#3a3631;--accent:#ffd700;--ok:#7fd49b;--err:#ff8a80;--chip:#24211d}}\n*{box-sizing:border-box}\nbody{margin:0;color:var(--fg);font:15px/1.45 system-ui,sans-serif;background:transparent}\nmain{padding:12px;display:grid;gap:12px}\n.empty,.note{color:var(--muted)}\narticle{border:1px solid var(--line);border-radius:10px;padding:12px}\nh2{font-size:15px;margin:0 0 4px}\n.kind{display:inline-block;font-size:12px;padding:1px 8px;border-radius:999px;background:var(--chip);color:var(--muted);margin-bottom:6px}\n.meta{font-size:13px;color:var(--muted);margin:0 0 6px}\n.does{margin:6px 0;font-weight:600}\ndetails{margin:6px 0}\nsummary{cursor:pointer;color:var(--muted);font-size:13px}\npre{white-space:pre-wrap;overflow-wrap:anywhere;font-size:12px;margin:6px 0 0;max-height:240px;overflow:auto}\ntextarea{width:100%;min-height:64px;padding:8px;border:1px solid var(--line);border-radius:8px;background:transparent;color:var(--fg);font:inherit;margin-top:8px}\n.row{display:flex;flex-wrap:wrap;gap:8px;margin-top:8px}\nbutton{padding:8px 12px;border-radius:8px;border:1px solid var(--line);background:transparent;color:var(--fg);font:inherit;cursor:pointer;min-height:40px}\nbutton.primary{border-color:var(--accent);outline:1px solid var(--accent)}\nbutton:focus-visible,a:focus-visible,textarea:focus-visible{outline:2px solid var(--accent);outline-offset:2px}\nbutton[disabled]{opacity:.55;cursor:default}\na{color:inherit}\n.done{color:var(--ok);font-weight:600}\n.std{border-top:1px solid var(--line);margin:8px 0;padding-top:8px;display:grid;gap:8px}\nh3{font-size:14px;margin:0;font-weight:600}\n.aspects{list-style:none;margin:4px 0;padding:0;display:grid;gap:14px}\n.asp{display:grid;grid-template-columns:16px 1fr;gap:6px;font-size:14px;overflow-wrap:anywhere}\n.asp .gl{margin-top:3px;color:var(--muted);display:block}\n.asp p{margin:1px 0}\n.asp .nm{color:var(--muted)}\n.asp .ask{font-weight:600}\n.asp details{margin:0}\n.asp details[open]{border-left:2px solid var(--accent);padding-left:8px;margin-top:2px}\n.asp summary{padding:8px 0}\n.who{display:flex;gap:8px;align-items:center}\n.who .settler{flex:1}\n.yours .settler{color:var(--fg);font-weight:600}\n.yours .gl{color:var(--accent)}\n.iconbtn{min-height:34px;width:34px;padding:0;display:inline-grid;place-items:center;flex:none;border-color:var(--accent);color:var(--accent)}\n.openL{display:none}\ndetails[open]>summary .openL{display:inline}\ndetails[open]>summary .closedL{display:none}\n.fact{margin:0;font-size:14px;overflow-wrap:anywhere}\n.code{font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:13px}\n.small{font-size:13px;color:var(--muted);margin:0;overflow-wrap:anywhere}\nblockquote{margin:4px 0 0;padding-left:8px;border-left:2px solid var(--line);font-size:14px;overflow-wrap:anywhere}\nsummary:focus-visible{outline:2px solid var(--accent);outline-offset:2px}\n</style></head><body><main id=\"root\" aria-live=\"polite\"><p class=\"note\">Loading requests\u2026</p></main>\n<script>\n(function(){\n var root=document.getElementById(\"root\");\n var decided={};\n // A redraw while a decision is being recorded must not offer the buttons again.\n var pending={};\n var errors={};\n // A decision still running is followed to its outcome (jgwill/Miadi#924): one read every POLL_MS, at most POLL_MAX.\n var POLL_MS=3000,POLL_MAX=100,polls={};\n // An error that leaves the request open offers its approval page under it.\n var relink={};\n function el(tag,attrs,text){var e=document.createElement(tag);if(attrs)for(var k in attrs){if(k===\"class\")e.className=attrs[k];else e.setAttribute(k,attrs[k]);}if(text!=null)e.textContent=text;return e;}\n function host(){return window.openai||null;}\n function data(){var h=host();return h&&h.toolOutput?h.toolOutput:null;}\n function tokens(){var h=host();var m=h&&h.toolResponseMetadata;return (m&&m[\"miadi/decisionTokens\"])||{};}\n function render(){\n var d=data();root.textContent=\"\";\n if(!d){root.appendChild(el(\"p\",{class:\"note\"},\"Waiting for the request list.\"));return;}\n var list=d.decisions||[];\n if(!list.length){root.appendChild(el(\"p\",{class:\"empty\"},d.message||\"No request is waiting for a decision.\"));return;}\n if(!d.can_decide_here&&d.reason){root.appendChild(el(\"p\",{class:\"note\"},d.reason));}\n var t=tokens();\n list.forEach(function(r){root.appendChild(card(r,t[r.id]));});\n }\n // Where a request stands, as the connector projected it: the label, its lines, and the review it produced.\n function decidedBlock(d){\n var box=el(\"div\",{role:\"status\",class:d.cls});\n if(d.note)box.appendChild(el(\"p\",{class:\"line\"},d.note));\n box.appendChild(el(\"p\",{class:\"label\"},d.label));\n (d.lines||[]).forEach(function(l){box.appendChild(el(\"p\",{class:\"line\"},l));});\n if(d.url){var p=el(\"p\",{class:\"line\"});p.appendChild(el(\"a\",{href:d.url,target:\"_blank\",rel:\"noopener\"},d.url));box.appendChild(p);}\n return box;\n }\n function toolResult(res){\n var out=(res&&(res.structuredContent||res.structured_content))||null;\n if(!out&&res&&res.content&&res.content[0]&&res.content[0].text){try{out=JSON.parse(res.content[0].text);}catch(e){out={message:res.content[0].text};}}\n return out;\n }\n function projectionView(p,note){return {cls:p.stage===\"failed\"?\"fail\":[\"recording\",\"dispatching\"].indexOf(p.stage)!==-1?\"note\":\"done\",stage:p.stage,label:p.label,lines:p.lines||[],url:p.receipt_url||null,note:note||null};}\n // Read where a request stands. Still running: read again later. Never decided (the call was lost on the way): offer the decision again.\n function follow(r,lost){\n if(!host()||!host().callTool)return;\n polls[r.id]=(polls[r.id]||0)+1;\n host().callTool(\"get_run_result\",{record_id:r.id}).then(function(res){\n var out=toolResult(res);var p=out&&(out.projection||(out.data&&out.data.projection));\n if(!p){if(lost){delete decided[r.id];errors[r.id]=lost;}render();return;}\n if(p.stage===\"awaiting_decision\"){delete decided[r.id];if(lost)errors[r.id]=lost+\" Nothing was decided; decide again.\";render();return;}\n var note=decided[r.id]&&decided[r.id].note;\n decided[r.id]=projectionView(p,note);delete errors[r.id];render();\n if(p.stage===\"recording\"&&polls[r.id]<POLL_MAX)setTimeout(function(){follow(r);},POLL_MS);\n },function(err){\n if(lost){decided[r.id]={cls:\"note\",stage:\"recording\",label:\"Your decision may be recorded. Checking again\u2026\",lines:[],url:null,note:null};render();}\n if(polls[r.id]<POLL_MAX)setTimeout(function(){follow(r,lost);},POLL_MS);\n });\n }\n var SETTLED={drafter:\"The drafting agent can answer this.\",person:\"Only you can answer this. Write it under Instructions.\",bystander:\"Only the person deciding can answer this, in their instructions.\",local_agent:\"A local agent can settle this from the running system.\"};\n var ARROW='<svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" width=\"16\" height=\"16\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.9\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M12 17V3\"/><path d=\"m6 11 6 6 6-6\"/><path d=\"M19 21H5\"/></svg>';\n var DASHED='<path d=\"M10.1 2.182a10 10 0 0 1 3.8 0\"/><path d=\"M13.9 21.818a10 10 0 0 1-3.8 0\"/><path d=\"M17.609 3.721a10 10 0 0 1 2.69 2.7\"/><path d=\"M2.182 13.9a10 10 0 0 1 0-3.8\"/><path d=\"M20.279 17.609a10 10 0 0 1-2.7 2.69\"/><path d=\"M21.818 10.1a10 10 0 0 1 0 3.8\"/><path d=\"M3.721 6.391a10 10 0 0 1 2.7-2.69\"/><path d=\"M6.391 20.279a10 10 0 0 1-2.69-2.7\"/>';var EYE='<path d=\"M2.062 12.348a1 1 0 0 1 0-.696 10.75 10.75 0 0 1 19.876 0 1 1 0 0 1 0 .696 10.75 10.75 0 0 1-19.876 0\"/><circle cx=\"12\" cy=\"12\" r=\"3\"/>';\n function glyph(label,paths){return '<svg role=\"img\" aria-label=\"'+label+'\" viewBox=\"0 0 24 24\" width=\"16\" height=\"16\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.9\" stroke-linecap=\"round\" stroke-linejoin=\"round\">'+paths+'</svg>';}\n // A redraw rebuilds the card: what the person typed and which reasons they opened stay.\n var typed={};var whyOpen={};var boxes={};\n function stateLine(label,paths,build){var row=el(\"div\",{class:\"asp state\"});var g=el(\"span\",{class:\"gl\"});g.innerHTML=glyph(label,paths);row.appendChild(g);var t=el(\"p\",{class:\"small\"});build(t);row.appendChild(t);return row;}\n // The mission standard's open aspects, for the person deciding: what only they can answer first, and no verdict (jgwill/Miadi#939).\n function standardBlock(r,token){\n var rv=r.draft_review;\n var canAnswer=Boolean(token&&host()&&host().callTool);\n var s=el(\"section\",{class:\"std\",\"aria-label\":\"The mission standard\"});\n var list=rv?(rv.needs_revision||[]).slice().sort(function(a,b){var p=(b.settled_by===\"person\"?1:0)-(a.settled_by===\"person\"?1:0);return p||String(a.aspect).localeCompare(String(b.aspect));}):[];\n var version=rv&&rv.standard?\" v\"+rv.standard.version:\"\";\n s.appendChild(el(\"h3\",null,list.length?list.length+\" open on the mission standard\"+version:\"The mission standard\"+version));\n if(r.delivery){\n var place=el(\"p\",{class:\"fact\"});place.appendChild(el(\"span\",{class:\"small\"},\"The result lands at: \"));var disputed=list.some(function(f){return f.aspect===\"S1\";});\n place.appendChild(el(\"span\",disputed?{class:\"small\"}:null,r.delivery));\n if(disputed)place.appendChild(el(\"span\",{class:\"small\"},\" (S1 below asks about this)\"));\n s.appendChild(place);\n }\n if(r.person_words){var w=el(\"div\");w.appendChild(el(\"p\",{class:\"small\"},\"The person's words, as the drafting agent quoted them:\"));w.appendChild(el(\"blockquote\",null,r.person_words));s.appendChild(w);}\n if(!rv){s.appendChild(stateLine(\"Read it yourself\",EYE,function(t){t.textContent=\"No check ran on this version of the mission. Read it yourself.\";}));return s;}\n if(!list.length)s.appendChild(stateLine(\"Nothing flagged\",DASHED,function(t){t.textContent=\"Nothing flagged on the aspects checked.\";}));\n else{\n var ul=el(\"ul\",{class:\"aspects\"});\n list.forEach(function(f){\n var mine=f.settled_by===\"person\"&&canAnswer;\n var row=el(\"li\",{class:\"asp\"+(mine?\" yours\":\"\")});\n var g=el(\"span\",{class:\"gl\"});g.innerHTML=glyph(\"Open aspect\",DASHED);row.appendChild(g);\n var t=el(\"div\");\n var name=el(\"p\",{class:\"nm\"});name.appendChild(el(\"span\",{class:\"code\"},f.aspect));name.appendChild(el(\"span\",null,\" \"+f.name));t.appendChild(name);\n t.appendChild(el(\"p\",{class:\"ask\"},f.ask));\n if(f.span&&f.span!==r.delivery)t.appendChild(el(\"p\",{class:\"small\"},\"The mission says: \"+f.span));\n if(f.note)t.appendChild(el(\"p\",{class:\"small\"},f.note));\n var who=el(\"div\",{class:\"who\"});\n who.appendChild(el(\"p\",{class:\"small settler\"},(f.settled_by===\"person\"&&!canAnswer?SETTLED.bystander:SETTLED[f.settled_by])||f.settled_by));\n if(mine){\n var go=el(\"button\",{type:\"button\",class:\"iconbtn\",\"aria-label\":\"Go to Instructions\",title:\"Go to Instructions\"});go.innerHTML=ARROW;\n go.addEventListener(\"click\",function(){var box=boxes[r.id];if(box){if(box.scrollIntoView)box.scrollIntoView({block:\"center\"});box.focus();}});\n who.appendChild(go);\n }\n t.appendChild(who);\n var key=r.id+\"/\"+f.aspect;\n var why=el(\"details\");if(whyOpen[key])why.setAttribute(\"open\",\"\");\n why.addEventListener(\"toggle\",function(){whyOpen[key]=why.open;});\n var sum=el(\"summary\");sum.appendChild(el(\"span\",{class:\"closedL\"},\"Why\"));sum.appendChild(el(\"span\",{class:\"openL\"},\"Hide why\"));why.appendChild(sum);\n why.appendChild(el(\"p\",{class:\"small\"},f.why));\n var by=String(f.checked_by||\"\").split(\" \")[0]===\"jev\"?\"Jev\":f.checked_by===\"code\"?\"a check in code\":\"the \"+f.checked_by;\n why.appendChild(el(\"p\",{class:\"small\"},\"Flagged by \"+by+\".\"));\n t.appendChild(why);\n row.appendChild(t);ul.appendChild(row);\n });\n s.appendChild(ul);\n }\n var open={};list.forEach(function(f){open[f.aspect]=true;});\n var unseen=(rv.not_checked||[]).filter(function(n){return !open[n.aspect];});\n var rest=unseen.filter(function(n){return !n.in_part;});\n unseen.filter(function(n){return n.in_part;}).forEach(function(n){\n s.appendChild(stateLine(\"Checked in part\",EYE,function(t){t.appendChild(el(\"span\",null,\"Checked in part: \"));t.appendChild(el(\"span\",{class:\"code\"},n.aspect));t.appendChild(el(\"span\",null,\" \"+n.name+\" (\"+n.in_part+\")\"));}));\n });\n if(rest.length)s.appendChild(stateLine(\"Read it yourself\",EYE,function(t){\n t.appendChild(el(\"span\",null,\"No check covers these, so read the mission for them: \"));\n rest.forEach(function(n,i){if(i)t.appendChild(el(\"span\",null,\" \u00B7 \"));t.appendChild(el(\"span\",{class:\"code\"},n.aspect));t.appendChild(el(\"span\",null,\" \"+n.name));});\n }));\n if(canAnswer&&list.some(function(f){return f.settled_by===\"drafter\";}))s.appendChild(el(\"p\",{class:\"small\"},\"To put the drafting agent's questions to it, say what to revise under Instructions and send it back.\"));\n var refused=r.provider_authorization&&r.provider_authorization.authorized===false;\n if(canAnswer&&list.length&&!refused)s.appendChild(el(\"p\",{class:\"small\"},\"Approving as it stands starts the session, and the worker reads these questions with the task.\"));\n return s;\n }\n function card(r,token){\n var a=el(\"article\",{\"aria-label\":r.title});\n a.appendChild(el(\"span\",{class:\"kind\"},r.kind_label||r.kind));\n a.appendChild(el(\"h2\",null,r.title));\n a.appendChild(el(\"p\",{class:\"meta\"},\"Asked by \"+r.by+(r.via?\" through \"+r.via:\"\")+\" \u00B7 \"+new Date(r.created_at).toLocaleString()+(r.circle?\" \u00B7 \"+r.circle+\" circle\":\"\")));\n a.appendChild(el(\"p\",{class:\"does\"},r.consequence));\n if(r.intention)a.appendChild(el(\"p\",null,r.intention));\n if(!decided[r.id]&&!pending[r.id]&&r.projection&&r.projection.stage===\"awaiting_decision\"&&(r.kind===\"run_request\"||r.kind===\"work_proposal\"||r.draft_review||r.delivery||r.person_words))a.appendChild(standardBlock(r,token));\n var det=el(\"details\");det.appendChild(el(\"summary\",null,\"What exactly is asked\"));det.appendChild(el(\"pre\",null,r.detail||\"\"));a.appendChild(det);\n var status=el(\"p\",{role:\"status\"});\n if(r.projection&&r.projection.stage!==\"awaiting_decision\"&&(!decided[r.id]||[\"recording\",\"dispatching\"].indexOf(r.projection.stage)===-1)){decided[r.id]=projectionView(r.projection);}\n if(decided[r.id]){\n var shown=decided[r.id];a.appendChild(decidedBlock(shown));\n if(shown.stage===\"recording\"&&polls[r.id]===undefined&&host()&&host().callTool){polls[r.id]=0;setTimeout(function(){follow(r);},POLL_MS);}\n if([\"recording\",\"dispatching\"].indexOf(shown.stage)!==-1&&host()&&host().callTool){\n var refresh=el(\"button\",{type:\"button\"},\"Refresh status\");\n refresh.addEventListener(\"click\",function(){\n refresh.disabled=true;\n host().callTool(\"get_run_result\",{record_id:r.id}).then(function(res){\n var out=toolResult(res);var p=out&&(out.projection||(out.data&&out.data.projection));\n if(p){decided[r.id]=projectionView(p);delete errors[r.id];}\n else{errors[r.id]=(out&&out.message)||\"Status could not be refreshed.\";}\n render();\n },function(err){errors[r.id]=\"Status could not be refreshed: \"+String(err&&err.message||err);render();});\n });\n a.appendChild(refresh);\n }\n if(errors[r.id])a.appendChild(el(\"p\",{class:\"fail\",role:\"status\"},errors[r.id]));\n return a;\n }\n function approvalLink(){var p=el(\"p\",{class:\"note\"});p.appendChild(document.createTextNode(\"Decide on its approval page: \"));p.appendChild(el(\"a\",{href:r.approval_url,target:\"_blank\",rel:\"noopener\"},\"open the approval page\"));return p;}\n if(pending[r.id]){status.className=\"note\";status.textContent=\"Recording your decision\u2026\";a.appendChild(status);return a;}\n if(!token||!host()||!host().callTool){a.appendChild(approvalLink());return a;}\n var ta=el(\"textarea\",{\"aria-label\":\"Instructions or changes (needed to approve with changes or send back)\",placeholder:\"Instructions or changes (needed to approve with changes or send back)\"});\n ta.value=typed[r.id]||\"\";boxes[r.id]=ta;\n ta.addEventListener(\"input\",function(){typed[r.id]=ta.value;});\n a.appendChild(ta);\n var row=el(\"div\",{class:\"row\"});\n // The ring on a mission would move with its report and read as a verdict, so a mission's buttons carry none (jgwill/Miadi#939).\n var mission=r.kind===\"run_request\"||r.kind===\"work_proposal\";\n var buttons=[[\"approve\",\"Approve\",mission?\"\":\"primary\"],[\"approve_with_changes\",\"Approve with my changes\",\"\"],[\"request_revision\",\"Send back for revision\",\"\"],[\"decline\",\"Decline\",\"\"]];\n var btns=[];\n buttons.forEach(function(b){var x=el(\"button\",{type:\"button\",class:b[2]},b[1]);x.addEventListener(\"click\",function(){go(b[0]);});btns.push(x);row.appendChild(x);});\n a.appendChild(row);a.appendChild(status);\n if(errors[r.id]){status.className=\"fail\";status.textContent=errors[r.id];if(relink[r.id])a.appendChild(approvalLink());}\n function go(choice){\n var text=ta.value.trim();\n if((choice===\"approve_with_changes\"||choice===\"request_revision\")&&!text){status.className=\"fail\";status.textContent=choice===\"request_revision\"?\"Say what to revise.\":\"Write the changes to apply.\";ta.focus();return;}\n btns.forEach(function(x){x.disabled=true;});status.className=\"note\";status.textContent=\"Recording your decision\u2026\";pending[r.id]=true;delete errors[r.id];\n host().callTool(\"decide_request\",{record_id:r.id,decision:choice,instructions:text||undefined,decision_token:token}).then(function(res){\n var out=toolResult(res);\n // The connector answers with the request's projection, also when a click finds it decided already.\n var proj=out&&(out.projection||(out.detail&&out.detail.projection));\n var code=out&&out.error;\n delete pending[r.id];\n // The token expired or the request was revised, and it still awaits a decision: say so and keep it open.\n if(code&&(!proj||proj.stage===\"awaiting_decision\")){errors[r.id]=(out&&out.message)||\"Not recorded.\";relink[r.id]=true;render();return;}\n var note=out&&out.replayed?\"This decision was already recorded. Nothing ran again.\":code===\"decision_conflict\"?\"A different decision was recorded first. Here is where it stands.\":code===\"already_decided\"?\"This request was already decided. Here is where it stands.\":null;\n if(proj){decided[r.id]=projectionView(proj,note);}\n else{decided[r.id]={cls:code?\"fail\":\"done\",label:code?((out&&out.message)||\"Not recorded.\"):((out&&out.summary)||\"Recorded.\"),lines:[],url:null,note:null};}\n render();\n },function(err){\n // The host gave up waiting; the connector may still have recorded it. Read before offering the buttons again (#924).\n delete pending[r.id];\n decided[r.id]={cls:\"note\",stage:\"recording\",label:\"Checking whether your decision was recorded\u2026\",lines:[],url:null,note:null};\n polls[r.id]=0;render();\n follow(r,\"Not recorded: \"+(err&&err.message?err.message:String(err))+\".\");\n });\n }\n return a;\n }\n window.addEventListener(\"openai:set_globals\",render);\n render();\n})();\n</script></body></html>";
|
package/dist/decisions.js
CHANGED
|
@@ -234,13 +234,18 @@ summary:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
|
|
|
234
234
|
s.appendChild(ul);
|
|
235
235
|
}
|
|
236
236
|
var open={};list.forEach(function(f){open[f.aspect]=true;});
|
|
237
|
-
var
|
|
237
|
+
var unseen=(rv.not_checked||[]).filter(function(n){return !open[n.aspect];});
|
|
238
|
+
var rest=unseen.filter(function(n){return !n.in_part;});
|
|
239
|
+
unseen.filter(function(n){return n.in_part;}).forEach(function(n){
|
|
240
|
+
s.appendChild(stateLine("Checked in part",EYE,function(t){t.appendChild(el("span",null,"Checked in part: "));t.appendChild(el("span",{class:"code"},n.aspect));t.appendChild(el("span",null," "+n.name+" ("+n.in_part+")"));}));
|
|
241
|
+
});
|
|
238
242
|
if(rest.length)s.appendChild(stateLine("Read it yourself",EYE,function(t){
|
|
239
243
|
t.appendChild(el("span",null,"No check covers these, so read the mission for them: "));
|
|
240
244
|
rest.forEach(function(n,i){if(i)t.appendChild(el("span",null," · "));t.appendChild(el("span",{class:"code"},n.aspect));t.appendChild(el("span",null," "+n.name));});
|
|
241
245
|
}));
|
|
242
246
|
if(canAnswer&&list.some(function(f){return f.settled_by==="drafter";}))s.appendChild(el("p",{class:"small"},"To put the drafting agent's questions to it, say what to revise under Instructions and send it back."));
|
|
243
|
-
|
|
247
|
+
var refused=r.provider_authorization&&r.provider_authorization.authorized===false;
|
|
248
|
+
if(canAnswer&&list.length&&!refused)s.appendChild(el("p",{class:"small"},"Approving as it stands starts the session, and the worker reads these questions with the task."));
|
|
244
249
|
return s;
|
|
245
250
|
}
|
|
246
251
|
function card(r,token){
|
package/dist/draft-review.d.ts
CHANGED
package/dist/draft-review.js
CHANGED
|
@@ -194,7 +194,7 @@ export async function reviewDraft({ record, records, standard, adapter, now = Da
|
|
|
194
194
|
notChecked.push({ aspect: a.code, name: a.name, reason: "This version of the connector runs no check for it." });
|
|
195
195
|
}
|
|
196
196
|
if (a.not_checked)
|
|
197
|
-
notChecked.push({ aspect: a.code, name: a.name, reason: a.not_checked });
|
|
197
|
+
notChecked.push({ aspect: a.code, name: a.name, reason: a.not_checked, ...(a.checked_in_part ? { in_part: a.checked_in_part } : {}) });
|
|
198
198
|
}
|
|
199
199
|
// For a finding Jev raised on the mission, the sentence it is about. A failure leaves the finding without one.
|
|
200
200
|
const raised = needs.flatMap((f) => {
|
|
@@ -39,6 +39,8 @@ export interface StandardAspect {
|
|
|
39
39
|
jev?: JevCheck;
|
|
40
40
|
/** Why this version of the connector does not check it, or checks only part of it. */
|
|
41
41
|
not_checked?: string;
|
|
42
|
+
/** What is checked when only part of the aspect is, in words for the person deciding. */
|
|
43
|
+
checked_in_part?: string;
|
|
42
44
|
}
|
|
43
45
|
export interface MissionStandard {
|
|
44
46
|
name: string;
|
package/dist/mission-standard.js
CHANGED
|
@@ -57,6 +57,7 @@ export const BUILT_IN_STANDARD = {
|
|
|
57
57
|
fix: "Say which in the mission.",
|
|
58
58
|
settled_by: "drafter",
|
|
59
59
|
not_checked: "Only shared issues are compared. The local reviewer judges other overlap, and it does not run yet (jgwill/Miadi#939 A3).",
|
|
60
|
+
checked_in_part: "only shared issues are compared",
|
|
60
61
|
},
|
|
61
62
|
{
|
|
62
63
|
code: "S4",
|
|
@@ -127,7 +128,7 @@ export function parseStandard(text, version) {
|
|
|
127
128
|
if (!["drafter", "person", "local_agent"].includes(a.settled_by))
|
|
128
129
|
throw new Error(`aspect ${a.code}: settled_by is drafter, person or local_agent`);
|
|
129
130
|
const jev = checkOf(a.jev);
|
|
130
|
-
return { code: a.code, name: a.name, requires: a.requires, why: a.why, ask: a.ask, ...(isText(a.fix) ? { fix: a.fix } : {}), settled_by: a.settled_by, ...(jev ? { jev } : {}), ...(isText(a.not_checked) ? { not_checked: a.not_checked } : {}) };
|
|
131
|
+
return { code: a.code, name: a.name, requires: a.requires, why: a.why, ask: a.ask, ...(isText(a.fix) ? { fix: a.fix } : {}), settled_by: a.settled_by, ...(jev ? { jev } : {}), ...(isText(a.not_checked) ? { not_checked: a.not_checked } : {}), ...(isText(a.checked_in_part) ? { checked_in_part: a.checked_in_part } : {}) };
|
|
131
132
|
});
|
|
132
133
|
const preferences = {};
|
|
133
134
|
for (const [person, list] of Object.entries(raw.preferences ?? {})) {
|
package/dist/version.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const VERSION = "0.1.
|
|
1
|
+
export declare const VERSION = "0.1.23";
|
package/dist/version.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const VERSION = "0.1.
|
|
1
|
+
export const VERSION = "0.1.23";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@miadi/connector",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.23",
|
|
4
4
|
"description": "The Miadi connector: one remote MCP service through which a person signed in with their Miadi person token, from ChatGPT or any MCP client, reads sessions, reviews, episodes and circles and records observations, inquiries, handoffs and proposals with their name on each record.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Miadi",
|