@rubytech/create-maxy-code 0.1.325 → 0.1.327

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.
Files changed (34) hide show
  1. package/package.json +1 -1
  2. package/payload/platform/plugins/admin/mcp/dist/__tests__/admin-authoring-skill-gate.test.js +9 -2
  3. package/payload/platform/plugins/admin/mcp/dist/__tests__/admin-authoring-skill-gate.test.js.map +1 -1
  4. package/payload/platform/plugins/admin/mcp/dist/content-producer-authoring-skills.d.ts +1 -1
  5. package/payload/platform/plugins/admin/mcp/dist/content-producer-authoring-skills.d.ts.map +1 -1
  6. package/payload/platform/plugins/admin/mcp/dist/content-producer-authoring-skills.js +11 -1
  7. package/payload/platform/plugins/admin/mcp/dist/content-producer-authoring-skills.js.map +1 -1
  8. package/payload/platform/plugins/admin/skills/deck-pages/SKILL.md +13 -7
  9. package/payload/platform/plugins/admin/skills/professional-document/SKILL.md +9 -3
  10. package/payload/platform/plugins/slides/skills/deck-system/SKILL.md +2 -0
  11. package/payload/platform/templates/specialists/agents/content-producer.md +2 -2
  12. package/payload/premium-plugins/management-consulting/.claude-plugin/plugin.json +1 -1
  13. package/payload/premium-plugins/management-consulting/PLUGIN.md +5 -2
  14. package/payload/premium-plugins/management-consulting/skills/decision-memo/SKILL.md +9 -0
  15. package/payload/premium-plugins/management-consulting/skills/narrative-builder/SKILL.md +9 -0
  16. package/payload/premium-plugins/management-consulting/skills/pitch-deck/SKILL.md +142 -0
  17. package/payload/premium-plugins/writer-craft/skills/voice-mirror/SKILL.md +4 -2
  18. package/payload/server/public/assets/{AdminLoginScreens-BRuf77z9.js → AdminLoginScreens-DNsCEyvZ.js} +1 -1
  19. package/payload/server/public/assets/AdminShell-DqyjA9x-.js +1 -0
  20. package/payload/server/public/assets/{admin-BhME5PGQ.js → admin-3jmCp4G3.js} +1 -1
  21. package/payload/server/public/assets/{browser-DW_bivL3.js → browser-DarU3c-V.js} +1 -1
  22. package/payload/server/public/assets/chat-CG-r6QZ2.js +1 -0
  23. package/payload/server/public/assets/{graph-Dr2jWCTw.js → graph-CylZ1wV1.js} +1 -1
  24. package/payload/server/public/assets/{operator-D7jjhQy9.js → operator-DgGt6Hc0.js} +1 -1
  25. package/payload/server/public/assets/{page-Dd5g92a7.js → page-Dl3SpCO3.js} +4 -4
  26. package/payload/server/public/assets/{public-BFTed_RH.js → public-8hwaomIS.js} +1 -1
  27. package/payload/server/public/browser.html +2 -2
  28. package/payload/server/public/chat.html +3 -3
  29. package/payload/server/public/graph.html +2 -2
  30. package/payload/server/public/index.html +3 -3
  31. package/payload/server/public/operator.html +4 -4
  32. package/payload/server/public/public.html +3 -3
  33. package/payload/server/public/assets/AdminShell-DNHJCrt1.js +0 -1
  34. package/payload/server/public/assets/chat-CV7vRNtO.js +0 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rubytech/create-maxy-code",
3
- "version": "0.1.325",
3
+ "version": "0.1.327",
4
4
  "description": "Install Maxy — AI for Productive People",
5
5
  "bin": {
6
6
  "create-maxy-code": "./dist/index.js"
@@ -27,8 +27,15 @@ describe("isAdminSeat", () => {
27
27
  });
28
28
  });
29
29
  describe("CONTENT_PRODUCER_AUTHORING_SKILLS", () => {
30
- it("is exactly the three content-producer-invoked authoring/render/publish skills", () => {
31
- expect([...CONTENT_PRODUCER_AUTHORING_SKILLS].sort()).toEqual(["a4-print-documents", "professional-document", "publish-site"].sort());
30
+ it("is the render/publish authoring skills plus the consulting prose deliverables", () => {
31
+ expect([...CONTENT_PRODUCER_AUTHORING_SKILLS].sort()).toEqual([
32
+ "a4-print-documents",
33
+ "decision-memo",
34
+ "narrative-builder",
35
+ "pitch-deck",
36
+ "professional-document",
37
+ "publish-site",
38
+ ].sort());
32
39
  });
33
40
  it("excludes admin-invoked skills (unzip-attachment, deck-pages)", () => {
34
41
  // unzip-attachment SKILL.md: "Invoked by the admin agent directly".
@@ -1 +1 @@
1
- {"version":3,"file":"admin-authoring-skill-gate.test.js","sourceRoot":"","sources":["../../src/__tests__/admin-authoring-skill-gate.test.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"admin-authoring-skill-gate.test.js","sourceRoot":"","sources":["../../src/__tests__/admin-authoring-skill-gate.test.ts"],"names":[],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- export declare const CONTENT_PRODUCER_AUTHORING_SKILL_SLUGS: readonly ["professional-document", "a4-print-documents", "publish-site"];
1
+ export declare const CONTENT_PRODUCER_AUTHORING_SKILL_SLUGS: readonly ["professional-document", "a4-print-documents", "publish-site", "decision-memo", "narrative-builder", "pitch-deck"];
2
2
  //# sourceMappingURL=content-producer-authoring-skills.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"content-producer-authoring-skills.d.ts","sourceRoot":"","sources":["../src/content-producer-authoring-skills.ts"],"names":[],"mappings":"AAaA,eAAO,MAAM,sCAAsC,0EAIzC,CAAC"}
1
+ {"version":3,"file":"content-producer-authoring-skills.d.ts","sourceRoot":"","sources":["../src/content-producer-authoring-skills.ts"],"names":[],"mappings":"AAoBA,eAAO,MAAM,sCAAsC,8HAOzC,CAAC"}
@@ -5,15 +5,25 @@
5
5
  // per line and do not reformat to multi-slug lines without updating that parser
6
6
  // (platform/scripts/lib/admin-skills-bootstrap.sh).
7
7
  //
8
- // These three skills are content-producer-owned: the admin seat must dispatch
8
+ // These skills are content-producer-owned: the admin seat must dispatch
9
9
  // content-producer (Agent tool, subagent_type content-producer) rather than
10
10
  // load or author them from its own seat. Each carries the same membership in
11
11
  // its SKILL.md "Invoked from specialists:content-producer" declaration, so the
12
12
  // generator's declaration scan already excludes them; this list is the gate's
13
13
  // compiled-in guard against a declaration regression.
14
+ //
15
+ // The first three are the original render/publish/print authoring skills. The
16
+ // last three are the management-consulting prose deliverables: their output is
17
+ // finished external-facing prose, so they compose on content-producer (the
18
+ // authoring seat, which carries plainly + prose-craft + voice-retrieve-
19
+ // conditioning). The 19 management-consulting analysis-framework skills stay
20
+ // admin-run and are not listed here.
14
21
  export const CONTENT_PRODUCER_AUTHORING_SKILL_SLUGS = [
15
22
  "professional-document",
16
23
  "a4-print-documents",
17
24
  "publish-site",
25
+ "decision-memo",
26
+ "narrative-builder",
27
+ "pitch-deck",
18
28
  ];
19
29
  //# sourceMappingURL=content-producer-authoring-skills.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"content-producer-authoring-skills.js","sourceRoot":"","sources":["../src/content-producer-authoring-skills.ts"],"names":[],"mappings":"AAAA,6EAA6E;AAC7E,gFAAgF;AAChF,+EAA+E;AAC/E,8EAA8E;AAC9E,gFAAgF;AAChF,oDAAoD;AACpD,EAAE;AACF,8EAA8E;AAC9E,4EAA4E;AAC5E,6EAA6E;AAC7E,+EAA+E;AAC/E,8EAA8E;AAC9E,sDAAsD;AACtD,MAAM,CAAC,MAAM,sCAAsC,GAAG;IACpD,uBAAuB;IACvB,oBAAoB;IACpB,cAAc;CACN,CAAC"}
1
+ {"version":3,"file":"content-producer-authoring-skills.js","sourceRoot":"","sources":["../src/content-producer-authoring-skills.ts"],"names":[],"mappings":"AAAA,6EAA6E;AAC7E,gFAAgF;AAChF,+EAA+E;AAC/E,8EAA8E;AAC9E,gFAAgF;AAChF,oDAAoD;AACpD,EAAE;AACF,wEAAwE;AACxE,4EAA4E;AAC5E,6EAA6E;AAC7E,+EAA+E;AAC/E,8EAA8E;AAC9E,sDAAsD;AACtD,EAAE;AACF,8EAA8E;AAC9E,+EAA+E;AAC/E,2EAA2E;AAC3E,wEAAwE;AACxE,6EAA6E;AAC7E,qCAAqC;AACrC,MAAM,CAAC,MAAM,sCAAsC,GAAG;IACpD,uBAAuB;IACvB,oBAAoB;IACpB,cAAc;IACd,eAAe;IACf,mBAAmB;IACnB,YAAY;CACJ,CAAC"}
@@ -1,20 +1,26 @@
1
1
  ---
2
2
  name: deck-pages
3
3
  description: >
4
- Constraints for producing presentation deck pages as HTML slide sequences that
4
+ The slide-deck format spec and generic renderer: HTML slide sequences that
5
5
  download as pixel-perfect PDFs via client-side html2canvas + jsPDF rendering.
6
- Use when creating or modifying any slide deck, pitch deck, presentation, or
7
- multi-slide document intended for PDF download. Also use when the output is a
8
- set of fixed-dimension landscape pages viewed on screen and exported as a PDF.
9
- Trigger phrases: "deck", "pitch deck", "slides", "presentation", "slide deck",
10
- "investor deck", "deck PDF", "download deck", or any request to create a
11
- multi-page slide-based document with a PDF download button.
6
+ Use for the slide format mechanics, for a deck the operator already wrote or
7
+ supplies as HTML, or when the output is a set of fixed-dimension landscape
8
+ pages viewed on screen and exported as a PDF. Trigger phrases: "slides",
9
+ "slide deck", "deck PDF", "download deck", "save this as a deck", or any
10
+ request to turn supplied slide content into a multi-page PDF with a download
11
+ button. Composition of consulting decks (a new-business or credentials pitch,
12
+ a client findings or recommendation deck, a thought-leadership deck) is owned
13
+ by `management-consulting:pitch-deck`; founder fundraise decks by
14
+ `venture-studio:investor-data-room`. This skill carries the format, not the
15
+ consulting method.
12
16
  ---
13
17
 
14
18
  # Deck Pages — Slide-Based PDF Documents
15
19
 
16
20
  Invoked by the admin agent directly.
17
21
 
22
+ This skill is the slide format spec and generic renderer. When the deck is a consulting deliverable (a new-business or credentials pitch, a client findings or recommendation deck, or a thought-leadership deck), its method and house-voice gate are owned by `management-consulting:pitch-deck`, which composes the content and then renders it. Founder fundraise decks are owned by `venture-studio:investor-data-room`. Use this skill for the format mechanics and for decks the operator already wrote or supplies as HTML.
23
+
18
24
  Constraints for producing HTML slide decks that render correctly on screen and export as pixel-perfect PDFs via client-side `html2canvas-pro` + `jsPDF`. Every rule exists because violating it caused a visible rendering problem in exported decks.
19
25
 
20
26
  ## How this differs from A4 print documents
@@ -14,8 +14,12 @@ description: >
14
14
  (prospectus / term sheet / business plan / data room) route to
15
15
  `venture-studio:investor-data-room`; property brochures route to
16
16
  `real-agent:property-brochure`; pre-valuation packs route to
17
- `real-agent:property-preval`; slide decks route to `admin:deck-pages` (format
18
- spec) and `venture-studio:investor-data-room` (composer). Does NOT trigger on
17
+ `real-agent:property-preval`; consulting decks (new-business or credentials
18
+ pitch, client findings or recommendation deck, thought-leadership deck) route
19
+ to `management-consulting:pitch-deck`; founder fundraise decks route to
20
+ `venture-studio:investor-data-room`; generic slide decks the operator already
21
+ wrote or supplies as HTML route to `admin:deck-pages` (format spec). Does NOT
22
+ trigger on
19
23
  format-only phrasings ("PDF", "one-pager", "A4", "brochure", "executive
20
24
  document", "market analysis") — those are owned by `admin:a4-print-documents`.
21
25
  ---
@@ -35,7 +39,9 @@ These checks run in order against the operator brief. The first match wins and s
35
39
  | prospectus, term sheet, data room, business plan, investor, fundraise, raise, round, SEIS, EIS, cap table | `venture-studio:investor-data-room` | Owns the UK seed-raise pack end-to-end (16-section plan, prospectus, term sheet, FCA self-cert appendices). |
36
40
  | property brochure, property listing brochure | `real-agent:property-brochure` | Owns the estate-agent brochure pipeline (brand → property → A4 PDF). |
37
41
  | pre-valuation, preval, valuation pitch, pre-appraisal | `real-agent:property-preval` | Owns the 5-page pre-valuation pitch pack. |
38
- | deck, slides, slide deck, presentation, pitch deck | `admin:deck-pages` (format spec) and `venture-studio:investor-data-room` (composer) | Slide format and full-pitch composition are not A4 documents. |
42
+ | consulting deck, credentials pitch, capabilities deck, client findings deck, recommendation deck, steering-committee deck, board strategy deck, thought-leadership deck | `management-consulting:pitch-deck` | Owns the consulting deck method and the house-voice gate across all three modes. |
43
+ | founder pitch deck, investor deck, fundraise deck | `venture-studio:investor-data-room` | Owns the founder fundraise pitch. |
44
+ | deck, slides, slide deck, presentation (generic, operator-supplied, or save-this-HTML) | `admin:deck-pages` | Slide format spec and generic renderer; not an A4 document and not a consulting composer. |
39
45
  | noun is "plan" and none of the fundraise tokens above match | **Ask the operator** before proceeding: "Is this a fundraise plan (business plan for investors) or an operating / strategic / marketing / transition plan?" If fundraise → refuse, redirect to `venture-studio:investor-data-room`. If non-fundraise → proceed. | The word "plan" splits cleanly between the two composers; the precision doctrine requires asking rather than guessing. |
40
46
 
41
47
  Emit `[professional-document] refuse reason=<owned-by-other-composer> redirect=<skill-name>` on any refusal. Emit `[professional-document] plan-disambiguation asked` when the plan gate fires and `[professional-document] plan-disambiguation answered=<fundraise|non-fundraise>` once the operator answers.
@@ -40,6 +40,8 @@ Based on the user's description, select the right storytelling format. Read the
40
40
 
41
41
  These files are in the same directory as this SKILL.md. Read them from here.
42
42
 
43
+ **Consulting decks arrive composed.** When the brief is a consulting deliverable (a new-business or credentials pitch, a client findings or recommendation deck, or a thought-leadership deck), `management-consulting:pitch-deck` has already chosen the structure and composed the content in the operator's house voice (its findings mode uses the McKinsey SCR engine in `STORYTELLING-mbb.md`). Render that brief through the component library below; do not re-select a storytelling format or re-write the prose.
44
+
43
45
  **Default:** If unclear, use the six-beat TED Talk structure from `STORYTELLING.md`. It adapts to most formats.
44
46
 
45
47
  ## Step 2. Draft the outline
@@ -3,7 +3,7 @@ name: content-producer
3
3
  description: "Author professional business documents (proposal, report, brief, memo, plan, case study, brochure), render PDFs, generate images, and publish static websites. Delegate when the operator asks for a written document, a PDF render, a generated image, or to publish a prepared website."
4
4
  summary: "Produces visual output from your graph: generates images, renders pages to PDF, and hosts static websites you upload as a zip."
5
5
  model: claude-opus-4-8[1m]
6
- tools: Bash, Read, Edit, Write, MultiEdit, Skill, mcp__plugin_memory_memory__memory-search, mcp__plugin_replicate_replicate__image-generate, mcp__plugin_browser_browser__browser-render, mcp__plugin_browser_browser__browser-navigate, mcp__plugin_browser_browser__browser-evaluate, mcp__plugin_browser_browser__browser-resize, mcp__plugin_browser_browser__browser-screenshot, mcp__plugin_browser_browser__browser-pdf-save, mcp__plugin_admin_admin__plugin-read, mcp__plugin_admin_admin__public-hostname, mcp__plugin_admin_admin__publish-site
6
+ tools: Bash, Read, Edit, Write, MultiEdit, Skill, mcp__plugin_memory_memory__memory-search, mcp__plugin_writer-craft_writer-craft__voice-retrieve-conditioning, mcp__plugin_replicate_replicate__image-generate, mcp__plugin_browser_browser__browser-render, mcp__plugin_browser_browser__browser-navigate, mcp__plugin_browser_browser__browser-evaluate, mcp__plugin_browser_browser__browser-resize, mcp__plugin_browser_browser__browser-screenshot, mcp__plugin_browser_browser__browser-pdf-save, mcp__plugin_admin_admin__plugin-read, mcp__plugin_admin_admin__public-hostname, mcp__plugin_admin_admin__publish-site
7
7
  ---
8
8
 
9
9
  # Content Producer
@@ -36,7 +36,7 @@ Generate the HTML to the print-CSS constraints. For A4 print, **the first tool c
36
36
 
37
37
  Render the PDF on device with `browser-pdf-save`: serve or open the HTML, `browser-navigate` to it, then `browser-pdf-save` to the output path — it uses Chromium's print pipeline (honours `@page`/print CSS, prints backgrounds). For glassmorphism cover/back pages that do not survive print, `a4-print-documents` directs you to capture print-fallback images with `browser-screenshot` (element clip) after `browser-resize`; use `browser-evaluate` to hide on-screen chrome before the capture. Do not write or run Playwright scripts — these on-device tools are the rendering path.
38
38
 
39
- When the brief is to author a generic business document (proposal / report / brief / memo / white paper / plan / case study), **the first tool call MUST be `Skill professional-document`. Any browser tool call before the skill is loaded into context is a contract violation.** Load `skill-load skillName=professional-document`: it carries the document-type catalogue, the refusal taxonomy for briefs owned by other composers (fundraise → `venture-studio:investor-data-room`; property → `real-agent:property-brochure` or `:property-preval`; decks → `admin:deck-pages`), the brand-token resolution, and the outline-approve-draft-render-save-deliver workflow. The skill loads `a4-print-documents` itself at the render phase — do not load it earlier. Format-only briefs ("create a PDF of this HTML", "save this as a one-pager", "render this brochure") stay on the existing `a4-print-documents` route above.
39
+ When the brief is to author a generic business document (proposal / report / brief / memo / white paper / plan / case study), **the first tool call MUST be `Skill professional-document`. Any browser tool call before the skill is loaded into context is a contract violation.** Load `skill-load skillName=professional-document`: it carries the document-type catalogue, the refusal taxonomy for briefs owned by other composers (fundraise → `venture-studio:investor-data-room`; property → `real-agent:property-brochure` or `:property-preval`; consulting decks (a new-business or credentials pitch, a client findings or recommendation deck, a thought-leadership deck) → `management-consulting:pitch-deck`; founder fundraise decks → `venture-studio:investor-data-room`; generic slide decks the operator already wrote or supplies as HTML → `admin:deck-pages`), the brand-token resolution, and the outline-approve-draft-render-save-deliver workflow. The skill loads `a4-print-documents` itself at the render phase — do not load it earlier. Format-only briefs ("create a PDF of this HTML", "save this as a one-pager", "render this brochure") stay on the existing `a4-print-documents` route above.
40
40
 
41
41
  ## Hosting websites
42
42
 
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "management-consulting",
3
- "description": "Twenty-one MBB-style strategy skills for client engagements: diagnose the situation, map markets and competition, choose a strategic path, design the operating model, govern risk and value, and land the recommendation with executives. Each skill runs one high-value consulting task to an executive-ready standard.",
3
+ "description": "Twenty-two MBB-style strategy skills for client engagements: diagnose the situation, map markets and competition, choose a strategic path, design the operating model, govern risk and value, and land the recommendation with executives. Each skill runs one high-value consulting task to an executive-ready standard.",
4
4
  "version": "0.1.0",
5
5
  "author": {
6
6
  "name": "Rubytech LLC"
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: management-consulting
3
- description: "Twenty-one MBB-style strategy skills for client engagements: diagnose the situation, map markets and competition, choose a strategic path, design the operating model, govern risk and value, and land the recommendation with executives. Each skill runs one high-value consulting task to an executive-ready standard."
3
+ description: "Twenty-two MBB-style strategy skills for client engagements: diagnose the situation, map markets and competition, choose a strategic path, design the operating model, govern risk and value, and land the recommendation with executives. Each skill runs one high-value consulting task to an executive-ready standard."
4
4
  icon: 📊
5
5
  tools: []
6
6
  always: false
@@ -9,7 +9,7 @@ metadata: {"platform":{"always":false,"embed":["admin"],"pluginKey":"management-
9
9
 
10
10
  # Management Consulting
11
11
 
12
- Twenty-one strategy skills modelled on MBB-style problem solving: structured before analytical, hypothesis-led before exhaustive, executive-ready before verbose. Together they cover a full engagement — diagnose, map, choose, execute, govern, communicate. Each skill is invoked on its own; there is no orchestration layer and no MCP server.
12
+ Twenty-two strategy skills modelled on MBB-style problem solving: structured before analytical, hypothesis-led before exhaustive, executive-ready before verbose. Together they cover a full engagement — diagnose, map, choose, execute, govern, communicate, and present. Each skill is invoked on its own; there is no orchestration layer and no MCP server.
13
13
 
14
14
  The method is McKinsey-inspired in the public sense of the term — crisp framing, MECE logic, 80/20 focus, answer-first communication. It carries no affiliation with or endorsement by any firm.
15
15
 
@@ -65,6 +65,9 @@ The method is McKinsey-inspired in the public sense of the term — crisp framin
65
65
  | `stakeholder-alignment` | A recommendation needs pre-wiring before the decision meeting |
66
66
  | `narrative-builder` | The story must land in the first sixty seconds |
67
67
  | `decision-memo` | An executive needs a clear written recommendation, not a deck |
68
+ | `pitch-deck` | The engagement needs a deck: a new-business or credentials pitch, a client findings or recommendation deck, or a thought-leadership deck — each in the operator's own voice |
69
+
70
+ `decision-memo`, `narrative-builder`, and `pitch-deck` produce finished external-facing prose, so they are composed by `specialists:content-producer` (the authoring seat, which carries `plainly`, `prose-craft`, and `voice-retrieve-conditioning`). The admin seat delegates them from the first point rather than drafting them inline. The other skills run on the admin seat as analysis frameworks.
68
71
 
69
72
  ## When to Activate
70
73
 
@@ -5,6 +5,8 @@ description: Produces concise executive decision memos with recommendation, cont
5
5
 
6
6
  # Decision Memo
7
7
 
8
+ Invoked from `specialists:content-producer`. A decision memo is finished external-facing prose, so it composes on the content-producer seat (which carries `plainly` and `voice-retrieve-conditioning`). The admin seat delegates it from the first point: the admin is refused this skill and dispatches content-producer (Agent tool, `subagent_type: content-producer`).
9
+
8
10
  ## When To Use
9
11
 
10
12
  Use this skill when the user needs a written recommendation that helps executives make a decision without a long deck.
@@ -17,6 +19,13 @@ Write answer-first. Give the decision-maker the recommendation, why it is right,
17
19
 
18
20
  A finished memo rests on a clear read of its audience, the decision in front of them, and the action required. It carries the recommendation and the strongest evidence for it, the options that were considered and why they lost, and the risks, mitigations, economics, and next steps that follow. The draft stays concise and survives a stress-test against the objections an executive will raise. The order in which you assemble these is yours to judge; what the memo must contain is not.
19
21
 
22
+ ## Prose pipeline (runs before any memo prose is drafted)
23
+
24
+ The memo goes out under the business name, so its prose runs through plain English and the house voice before the first sentence.
25
+
26
+ 1. **Plain English.** The first prose action is `skill-load skillName=plainly`. Apply it to every line: the recommendation, the options table, the body. Recursive plain English, no consulting jargon.
27
+ 2. **Voice mirror (hard gate).** Before drafting, call `voice-retrieve-conditioning` with `format: "article"`, `length: "long"`, `scope: "org"`, and `topic` set to the decision's domain. The tool emits its own `[voice-retrieve] …` line. Gate on `status`: on **`ok`**, condition every line on the returned style card and exemplars, then draft. On **`no-data` | `error`**, stop and emit no fabricated prose: tell the operator the voice is not established and offer to establish it (the voice-mirror skill) or to supply the prose for the skill to structure and plainly-polish. Emit `[decision-memo] voice-gate status=<ok|no-data|error> action=<conditioned|stopped|operator-prose>`.
28
+
20
29
  ## Output Format
21
30
 
22
31
  ```markdown
@@ -5,6 +5,8 @@ description: Builds executive strategy narratives using Pyramid Principle, SCQA,
5
5
 
6
6
  # Narrative Builder
7
7
 
8
+ Invoked from `specialists:content-producer`. An executive narrative is finished external-facing prose (headlines and storyline that go in front of a board), so it composes on the content-producer seat (which carries `plainly` and `voice-retrieve-conditioning`). The admin seat delegates it from the first point: the admin is refused this skill and dispatches content-producer (Agent tool, `subagent_type: content-producer`).
9
+
8
10
  ## When To Use
9
11
 
10
12
  Use this skill when the recommendation is mostly known but the story needs to land quickly with executives, boards, investors, or leadership teams.
@@ -22,6 +24,13 @@ Lead with the answer, structure support in a pyramid, and anticipate the questio
22
24
  5. Prepare hostile questions and answers.
23
25
  6. Produce an executive-ready narrative outline.
24
26
 
27
+ ## Prose pipeline (runs before any narrative prose is drafted)
28
+
29
+ The narrative goes out under the business name, so its headlines and body run through plain English and the house voice before the first line.
30
+
31
+ 1. **Plain English.** The first prose action is `skill-load skillName=plainly`. Apply it to every headline and the body. Recursive plain English, no consulting jargon.
32
+ 2. **Voice mirror (hard gate).** Before drafting, call `voice-retrieve-conditioning` with `format: "article"`, `length: "long"`, `scope: "org"`, and `topic` set to the recommendation's domain. The tool emits its own `[voice-retrieve] …` line. Gate on `status`: on **`ok`**, condition every headline and line on the returned style card and exemplars, then draft. On **`no-data` | `error`**, stop and emit no fabricated prose: tell the operator the voice is not established and offer to establish it (the voice-mirror skill) or to supply the prose for the skill to structure and plainly-polish. Emit `[narrative-builder] voice-gate status=<ok|no-data|error> action=<conditioned|stopped|operator-prose>`.
33
+
25
34
  ## Output Format
26
35
 
27
36
  ```markdown
@@ -0,0 +1,142 @@
1
+ ---
2
+ name: pitch-deck
3
+ description: Composes a management-consulting slide deck in the operator's own house voice. Three modes: a new-business or credentials pitch that wins the work, a client findings or recommendation deck that drives a decision, and a thought-leadership deck that positions a point of view. Use for a consulting pitch deck, a capabilities or credentials deck, a client findings deck, a recommendation or steering-committee deck, a board strategy deck, or a thought-leadership or point-of-view deck. Owns the consulting deck method (answer-first pyramid, SCQA/SCR, MECE, full-sentence action titles) and runs every line of prose through plain English and the house voice before it is drafted. Not a founder fundraise deck; that is `venture-studio:investor-data-room`. Not a generic renderer for arbitrary HTML slides; that is `admin:deck-pages`.
4
+ ---
5
+
6
+ # Pitch Deck
7
+
8
+ The consulting bundle's terminal visual deliverable. The sibling skills diagnose, map, choose, and govern; this skill turns their outputs into a deck that earns a decision or wins the work. It owns the method and the voice. It composes only from facts the operator already curated, and it never invents a financial number.
9
+
10
+ ## When to use
11
+
12
+ Pick the mode from the brief. All three live in this one skill.
13
+
14
+ | Mode | Use it when | Engine |
15
+ |------|-------------|--------|
16
+ | **A: new-business / credentials pitch** | The goal is to win the work: a capabilities deck, a credentials pitch, a "why us" deck for a prospect | Fixed spine + domain-themed middle + optional sections (below) |
17
+ | **B: client findings / recommendation** | The goal is to drive a decision: a findings deck, a recommendation, a steering-committee or board deck | SCR, reusing `slides:deck-system` `STORYTELLING-mbb.md` |
18
+ | **C: thought-leadership / topic** | The goal is to position a point of view: an industry report, a trends deck, a conference talk | Content-led with a short credentials tail |
19
+
20
+ ### When not to use
21
+
22
+ - **Founder fundraise deck** (seed/Series raise, investor pitch under the founder's own name) routes to `venture-studio:investor-data-room`.
23
+ - **"Save this HTML as a deck", arbitrary fixed-dimension slide layout, a deck the operator already wrote** routes to `admin:deck-pages` (the format spec and generic slide renderer).
24
+
25
+ ## Where this runs
26
+
27
+ Invoked from `specialists:content-producer`. The admin seat delegates the deck from the first point: it is refused this skill and dispatches content-producer (Agent tool, `subagent_type: content-producer`). Everything then happens on the one seat. content-producer carries `voice-retrieve-conditioning`, loads `plainly`, and holds the render tools, so the method, the voice gate, the prose, and the render all run together: it calls `voice-retrieve-conditioning` directly, gates inline (below), composes the slides, and renders through `slides:deck-system`, exporting the PDF via the existing path. There is no separate render brief and no admin-seat composition.
28
+
29
+ ## The method (all three modes)
30
+
31
+ The generation contract. Apply it before and during every mode.
32
+
33
+ - **Ghost deck first.** Write the full action-title string for the whole deck before any body, chart, or theme. The titles alone are the deck. Build the body only once the title string tells the story.
34
+ - **Answer first (Pyramid).** Lead with the recommendation or the core message. Everything after it is support. The recommendation sits at the top; three to five arguments below it; evidence below each.
35
+ - **SCQA / SCR opening.** Open on common ground (Situation), name the tension (Complication / Question), then the answer (Resolution / Answer). Mode B runs this across the whole deck; Modes A and C use it to open.
36
+ - **MECE grouping.** Every breakdown (findings, services, segments, causes) has parts that do not overlap and together leave no gap. If two points say the same thing, merge them.
37
+ - **Action titles.** Every slide headline is a full-sentence conclusion, not a topic label. "The European market contracted 12% in Q3", not "Market overview". If you cannot write the action title, the slide has no point yet; find the point first.
38
+ - **One message per slide, vertical logic.** Each slide makes exactly one point. The body proves the title and nothing else. Cut anything that does not.
39
+ - **"So what" prune.** For every slide, answer "so what?". A slide that survives only as background is appendix material or is cut.
40
+ - **Reverse-storyboard the horizontal logic.** Read the action titles top to bottom as a list, with no bodies and no charts. They must tell one coherent story and the recommendation must feel inevitable by the end. If the line of titles jumps or repeats, fix the titles before touching the bodies.
41
+ - **Source footnote on every data slide.** Every slide that carries a number shows where the number came from: a graph node, a named publication, or the operator's own figures. A numbered slide with no source line is a defect.
42
+ - **Never invent numbers.** Figures come only from the operator's data or from a sibling skill's output. If a number is missing, leave a visible gap and ask for it; do not fill it.
43
+
44
+ ## Prose pipeline (runs before any slide copy is drafted)
45
+
46
+ Non-negotiable, and it runs before the first word of slide prose. A method-less or voice-less deck reads as generic AI consulting copy under the operator's own business name, which is worse than no deck.
47
+
48
+ ### 1. Plain English
49
+
50
+ The first prose action of the turn is `skill-load skillName=plainly`. Apply it to every prose payload this skill emits: action titles, the executive-summary lines, slide body, captions, and the summary you return to the admin agent. Recursive plain English: an explanation may not itself contain a term that needs explaining. No consulting jargon survives the polish.
51
+
52
+ ### 2. Voice mirror (hard gate)
53
+
54
+ A deck ships under the business name, so it uses the **house voice**, not any one person's personal voice. Before drafting any prose, call `voice-retrieve-conditioning` with `format: "article"`, `length: "long"`, `scope: "org"`, and `topic` set to the engagement domain (for example "operating-model redesign for a regional bank"). The tool itself emits `[voice-retrieve] scope=org format=article status=<s> styleCardBytes=<n> exemplarCount=<k>`; you do not write that line.
55
+
56
+ Then gate on `status`. This diverges from the sibling composers, which silently degrade to a default register; this skill stops instead.
57
+
58
+ - **`ok`** (a style card and/or exemplars came back) conditions every prose payload on the style card and exemplars, then drafts. Output carries the style card's favoured terms and avoids its taboos.
59
+ - **`no-data` | `error`** stops. **Draft no slide prose.** Tell the operator the deck voice is not established and offer two routes: (a) establish the house voice through the voice-mirror skill (backfill or distil their own writing) then re-run, or (b) supply the deck prose themselves, which this skill will then only structure and polish through plain English, never generate.
60
+
61
+ A `scope: "org"` request returns only `ok`, `no-data`, or `error`; `fallback-org` arises solely on a personal-scope request, so it does not occur here. If it ever does, treat it as `ok` since it still carries an org style card.
62
+
63
+ Emit one decision line after the gate, so the choice is logged rather than inferred:
64
+
65
+ ```
66
+ [pitch-deck] voice-gate status=<ok|no-data|error> action=<conditioned|stopped|operator-prose>
67
+ ```
68
+
69
+ `conditioned` when you drafted on a style card, `stopped` when the gate halted drafting, `operator-prose` when the operator supplied the prose and you only structured and polished it.
70
+
71
+ ## Mode A: new-business / credentials pitch
72
+
73
+ Win the work. A fixed spine appears in every deck of this kind; a short domain-themed middle and an optional section set flex the deck to 11–14 slides for the engagement.
74
+
75
+ **Spine (always present, in order):** Cover, Contents, Introduction, Philosophy / Approach, **Services**, *[domain-themed middle]*, **Case Studies**, **Performance Metrics (KPIs)**, **Team**, Contact.
76
+
77
+ **Domain-themed middle (2–5 slides):** the firm's specialty rendered as its own steps: methodology, process, strategy, operational-excellence, or risk steps. A risk advisory firm shows its risk method here; a transformation firm shows its delivery method.
78
+
79
+ **Optional sections (toggle to reach 11–14 slides):** Market Analysis, Testimonials, Industry Experience / Expertise, Why-Choose / CTA.
80
+
81
+ Select the middle and the optionals from the brief. Do not hard-code one slide list; compose the spine plus the sections the engagement needs.
82
+
83
+ ## Mode B: client findings / recommendation
84
+
85
+ Drive a decision. This mode reuses the SCR engine in `slides:deck-system` `STORYTELLING-mbb.md`; read that file and follow it. Do not restate SCR here.
86
+
87
+ **Shape:** Title / Agenda, then a one-page **Executive summary** (SCR, Resolution leading at 60–70% of the message, a bold takeaway over indented supporting numbers), then Situation, Complication, Findings (MECE, action-titled, one chart per finding), Recommendation, Implementation roadmap (Gantt), Next steps, Appendix. The executive summary is written first and rewritten last; a reader who sees only that slide knows the recommendation, the reasoning, and the next step.
88
+
89
+ ## Mode C: thought-leadership / topic
90
+
91
+ Position a point of view. Content-led demand generation, with no client-specific recommendation and no commercial sell; that is what separates it from Modes B and A.
92
+
93
+ **Shape:** Cover, Overview, a hook (a single headline statistic), topic sections (trends, then data, then implications, then challenges, then what to do: transformation / adaptation / innovation), a short About-us / Values credentials tail, Contact / CTA.
94
+
95
+ ## Chart kit
96
+
97
+ Match the chart to the message. `slides:deck-system` ships no consulting-chart component, so build these on-token using its freestyle rules (stay on the theme's colours, fonts, and spacing; name the class; keep the CSS inline). Lead with them in Mode B; they are available to all modes.
98
+
99
+ | Chart | Use it for |
100
+ |-------|-----------|
101
+ | **Waterfall / bridge** | A measure moving between two points (a cost or margin walk) |
102
+ | **Marimekko / Mekko** | Segment × share in one view (market structure) |
103
+ | **2×2, including BCG growth-share** | Prioritisation or portfolio choices |
104
+ | **Gantt** | A phased roadmap with owners and dates |
105
+
106
+ ## Bridge from the analysis skills
107
+
108
+ The deck composes the outputs of the other consulting skills. Numbers come from those outputs or the operator's data only.
109
+
110
+ | Sibling output | Lands in |
111
+ |----------------|----------|
112
+ | `situation-assessment` | Situation |
113
+ | `market-mapping` / `profit-pool-analysis` | Findings / Market Analysis + a Mekko |
114
+ | `strategic-options` | Recommendation + a 2×2 |
115
+ | `business-case-builder` | Economics + a waterfall |
116
+ | `transformation-roadmap` | Implementation + a Gantt |
117
+ | `narrative-builder` / `stakeholder-alignment` | Executive summary + pre-wire |
118
+
119
+ ## Render handoff
120
+
121
+ When `slides` is enabled, the render path is `slides:deck-system`: it carries 25 HTML components, the design tokens, the themes, and the PDF export. content-producer renders the composed slides through `deck-system` on the same seat; the PDF exports via the existing path. There is no new renderer.
122
+
123
+ When `slides` is not enabled, say so and fall back to the always-present `admin:deck-pages` format spec for a slide-based PDF. Never return a blank turn because a dependency is absent.
124
+
125
+ Implement open frameworks in the operator's own brand. Never embed a named firm's branded template or assets.
126
+
127
+ ## Quality bar
128
+
129
+ - The action-title string alone tells the whole story (reverse-storyboard passes).
130
+ - Every data slide carries a source line, and every number traces to the brief or a sibling output.
131
+ - The executive summary (Mode B) stands alone on one slide.
132
+ - Mode A lands at 11–14 slides by toggling the optional sections, not by padding.
133
+ - Every prose payload passed through plain English; nothing reads as generic AI consulting copy.
134
+ - The voice gate decided before any prose was drafted, and the decision is logged.
135
+
136
+ ## Observability
137
+
138
+ ```
139
+ [pitch-deck] voice-gate status=<ok|no-data|error> action=<conditioned|stopped|operator-prose>
140
+ ```
141
+
142
+ The `[voice-retrieve] …` line is emitted by the voice tool itself. A render or export failure surfaces through `content-producer`'s existing `[tool-failure-diag]` line. A misroute is visible as the **absence** of a `skill-load skillName=pitch-deck` line in a consulting-deck turn; the safeguard is that every deck claimant routes consulting-deck intent here.
@@ -17,9 +17,11 @@ The skill is built on five deterministic MCP tools served by the `writer-craft`
17
17
  | `voice-record-feedback` | When the operator edits an agent draft, write a `:VoiceEdit {originalText, editedText, intent, occurredAt, format}-[:FEEDBACK_FOR]->(:VoiceProfile {format})` node. The `intent` field is a Haiku-summarised diff. |
18
18
  | `voice-ingest-session-text` | Write operator turns from the current session as `:Message {format:'text', authorshipMode:'human-only'}` corpus nodes. The agent reads its own operator turns from context and passes them as `turns`. Deduplicates via `contentHash`. Invoked on demand when the operator asks to capture this session's voice. |
19
19
 
20
- ## Surface — admin only, never delegated
20
+ ## Surface — establishment is admin-only; conditioning is shared with the drafting seat
21
21
 
22
- All five tools are admin-allowlisted (`embed: ["admin"]`); they exist only on the admin agent's tool surface. No specialist carries them, by design `format` and `authorshipMode` are editorial choices the operator makes, so voice-mirror is an operator-interactive admin flow, not a step a specialist runs unattended.
22
+ The four **establishment** tools (`voice-tag-content`, `voice-distil-profile`, `voice-ingest-session-text`, `voice-record-feedback`) are admin-allowlisted and exist only on the admin agent's tool surface. No specialist carries them, by design: `format` and `authorshipMode` are editorial choices the operator makes, so building and curating a voice profile is an operator-interactive admin flow, not a step a specialist runs unattended.
23
+
24
+ `voice-retrieve-conditioning` is different. It is the **drafting-time** conditioning tool: a drafting skill calls it to pull the style card and exemplars and condition its prose. It is on the admin surface and is also carried by `specialists:content-producer` (the authoring seat, which holds `plainly` and `prose-craft`), so voice-conditioned drafting can run on whichever seat composes the prose. The consulting prose deliverables (`decision-memo`, `narrative-builder`, `pitch-deck`) compose on content-producer and condition there. The split that holds: the operator curates voice with the four establishment tools on the admin seat; any drafting seat only retrieves it.
23
25
 
24
26
  This matters most right after an ingest. When a specialist (the librarian) files a document and the operator then asks to tag it — "mark that as me / human-only / marketing-copy" — the tagging is yours to run, not the specialist's. The specialist cannot call `voice-tag-content` and will hand back the created node's identifier instead. Take that id and run `voice-tag-content` here. If the id is not in context (a later turn, the librarian's return scrolled off), fall back to the unknown-authorship query in the backfill flow below to find the just-filed node. Never route the tag back into a specialist; a specialist reporting "voice-tag-content is not in my tools" is the boundary working as intended, not a failure to escalate.
25
27
 
@@ -1 +1 @@
1
- import{o as e}from"./chunk-Pqm5yXtL.js";import{L as t,O as n,V as r,b as i,x as a,y as o}from"./OperatorConversations-BqFmHTF1.js";import{i as s}from"./admin-types-CJrGd46U.js";import{g as c,l}from"./AdminShell-DNHJCrt1.js";import{t as u}from"./Checkbox-C3WNcLH8.js";var d=`admin-landing-redirected`,f=`/graph`;function p(e){return e.variant===`operator`?!1:e.appState===`chat`&&!e.alreadyRedirected}var m=e(r(),1);function h(e=`admin`){let[n,r]=(0,m.useState)(`loading`),[i,a]=(0,m.useState)(``),[o,l]=(0,m.useState)(``),[u,h]=(0,m.useState)(``),[g,_]=(0,m.useState)(!1),[v,y]=(0,m.useState)(!1),[b,x]=(0,m.useState)(!1),[S,C]=(0,m.useState)(!1),[w,T]=(0,m.useState)(!1),[E,D]=(0,m.useState)(null),[O,k]=(0,m.useState)(null),[A,j]=(0,m.useState)(void 0),[M,N]=(0,m.useState)(null),[P,F]=(0,m.useState)(void 0),[I,L]=(0,m.useState)(null),[ee,R]=(0,m.useState)(null),[z,B]=(0,m.useState)([]),[V,H]=(0,m.useState)(!1),[U,W]=(0,m.useState)(void 0),G=(0,m.useRef)(void 0),[K,q]=(0,m.useState)(!1);(0,m.useEffect)(()=>{typeof window>`u`||fetch(`/api/remote-auth/status`).then(e=>e.ok?e.json():null).then(e=>{e?.configured&&q(!0)}).catch(()=>{})},[]);let J=(0,m.useRef)(null),Y=(0,m.useRef)(null);(0,m.useEffect)(()=>{async function e(){let e=null;try{e=sessionStorage.getItem(`maxy-admin-session-key`)}catch{}if(!e)return!1;try{let t=await fetch(`/api/admin/session?session_key=${encodeURIComponent(e)}`);if(t.status===401){try{sessionStorage.removeItem(`maxy-admin-session-key`)}catch{}return!1}if(!t.ok)return!1;let n=await t.json();D(n.session_key),R(n.sessionId??null),j(n.businessName),N(n.role??null),F(n.userName===void 0?null:n.userName),L(n.avatar??null);let i=s(n.thinkingView);return G.current=i,W(i),r(`chat`),!0}catch(e){return console.error(`[admin] session restore failed:`,e),!1}}async function t(n=2){try{let i=await fetch(`/api/health`);if(!i.ok){if(n>0)return await new Promise(e=>setTimeout(e,1500)),t(n-1);console.error(`[admin] health check returned ${i.status} after retries`),r(`set-pin`);return}let a=await i.json();if(!a.pin_configured){r(`set-pin`);return}if(!a.claude_authenticated){r(`connect-claude`);return}if(await e())return;r(`enter-pin`)}catch(e){if(n>0)return await new Promise(e=>setTimeout(e,1500)),t(n-1);console.error(`[admin] health check failed:`,e),r(`set-pin`)}}t()},[]),(0,m.useEffect)(()=>{n===`chat`&&fetch(`/api/admin/claude-info`).then(e=>{if(e.ok)return e.json()}).then(e=>{e&&k(e)}).catch(()=>{})},[n]),(0,m.useEffect)(()=>{if(typeof window>`u`)return;let t=!1;try{t=sessionStorage.getItem(d)===`1`}catch{}if(p({appState:n,alreadyRedirected:t,variant:e})){try{sessionStorage.setItem(d,`1`)}catch{}console.info(`[admin-ui] landing-redirect target=${f}`),window.location.replace(f)}},[n,e]);let X=(0,m.useRef)(null);(0,m.useEffect)(()=>{if(n!==`chat`)return;let e=setInterval(async()=>{try{let e=await fetch(`/api/health`);if(e.ok){let t=await e.json();if(t.auth_status===`dead`||t.auth_status===`missing`){r(`connect-claude`);return}}}catch{}if(E)try{let e=await fetch(`/api/admin/session?session_key=${encodeURIComponent(E)}`);if(e.status!==401)return;let n=(await e.clone().json().catch(()=>null))?.code??`unknown-401`;if(n===`remote-auth-required`){t(`heartbeat`,`/api/admin/session`);return}console.warn(`[admin-auth] outcome=heartbeat-detected-expiry code=${n}`),X.current?.()}catch{}},300*1e3);return()=>clearInterval(e)},[n,E]),(0,m.useEffect)(()=>{n===`connect-claude`&&fetch(`/api/health`).then(e=>e.ok?e.json():null).then(e=>{e?.claude_authenticated&&r(`enter-pin`)}).catch(()=>{})},[n]);async function Z(e,t){y(!0);try{let n=await fetch(`/api/admin/session`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({pin:e,...t?{accountId:t}:{}})});if(!n.ok){h((await n.json().catch(()=>({}))).error||`Invalid PIN`);return}let i=await n.json();if(i.accounts&&!i.session_key){console.log(`[admin] account picker shown: userId=${i.userId} accountCount=${i.accounts.length}`),B(i.accounts),r(`account-picker`);return}D(i.session_key),R(i.sessionId??null),j(i.businessName),N(i.role??null),F(i.userName===void 0?null:i.userName),L(i.avatar??null);let o=s(i.thinkingView);if(G.current=o,W(o),t)try{sessionStorage.setItem(`maxy-account-id`,t)}catch{}try{sessionStorage.setItem(`maxy-admin-session-key`,i.session_key)}catch{}a(``),r(`chat`)}catch(e){console.error(`[admin] connection error:`,e),h(`Could not connect.`)}finally{y(!1),H(!1)}}let Q=(0,m.useCallback)(async e=>{if(e.preventDefault(),v)return;h(``);let t=o.trim();if(!t){h(`Please enter your name.`);return}if(i.length<4){h(`PIN must be at least 4 characters.`);return}let n=i;y(!0);try{let e=await fetch(`/api/onboarding/set-pin`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({pin:n,name:t})});if(!e.ok){let t=await e.json().catch(()=>({}));if(e.status===409){console.log(`[admin] PIN already configured — re-checking health`);try{let e=await fetch(`/api/health`);if(e.ok){let n=await e.json();n.pin_configured&&n.claude_authenticated?r(`enter-pin`):n.pin_configured?r(`connect-claude`):h(t.error||`Failed to set PIN.`)}else r(`enter-pin`)}catch{r(`enter-pin`)}return}h(t.error||`Failed to set PIN.`);return}let i=await fetch(`/api/health`);if((i.ok?await i.json():null)?.claude_authenticated){await Z(n);return}a(``),r(`connect-claude`)}catch(e){console.error(`[admin] connection error:`,e),h(`Could not connect.`)}finally{y(!1)}},[i,v,o]),te=(0,m.useCallback)(async e=>{e.preventDefault(),h(``),await Z(i)},[i]),ne=(0,m.useCallback)(async()=>{T(!0);try{if(!await c())return console.warn(`[admin-ui] claude-disconnect not verified — credentials may persist; staying put`),!1;D(null),N(null),F(void 0),L(null);try{sessionStorage.removeItem(`maxy-admin-session-key`),sessionStorage.removeItem(`maxy-account-id`),sessionStorage.removeItem(d)}catch{}return r(`connect-claude`),!0}finally{T(!1)}},[]),$=(0,m.useCallback)(()=>{D(null),N(null),F(void 0),L(null);try{sessionStorage.removeItem(`maxy-admin-session-key`),sessionStorage.removeItem(`maxy-account-id`),sessionStorage.removeItem(d)}catch{}a(``),h(``),r(`enter-pin`)},[]);return(0,m.useEffect)(()=>{X.current=$},[$]),{appState:n,setAppState:r,pin:i,setPin:a,operatorName:o,setOperatorName:l,pinError:u,setPinError:h,showPin:g,setShowPin:_,pinLoading:v,authPolling:b,setAuthPolling:x,authLoading:S,setAuthLoading:C,disconnecting:w,cacheKey:E,setCacheKey:D,claudeInfo:O,setClaudeInfo:k,businessName:A,role:M,userName:P,userAvatar:I,sessionId:ee,setSessionId:R,accounts:z,accountPickerLoading:V,expandAll:U,setExpandAll:W,expandAllDefaultRef:G,remoteAuthEnabled:K,pinInputRef:J,setPinFormRef:Y,handleSetPin:Q,handleLogin:te,handleAccountSelect:(0,m.useCallback)(async e=>{H(!0),h(``),await Z(i,e)},[i]),handleDisconnect:ne,handleLogout:$,handleChangePin:(0,m.useCallback)(async()=>{if(!i){h(`Enter your current PIN first.`);return}y(!0),h(``);try{let e=await fetch(`/api/onboarding/set-pin`,{method:`DELETE`,headers:{"Content-Type":`application/json`},body:JSON.stringify({currentPin:i})});if(!e.ok){h((await e.json().catch(()=>({error:`Incorrect PIN.`}))).error||`Incorrect PIN.`);return}a(``),h(``),r(`set-pin`)}catch(e){console.error(`[admin-auth] change pin failed:`,e),h(e instanceof Error?e.message:String(e))}finally{y(!1)}},[i])}}var g=a();function _({inputRef:e,value:t,onChange:n,onComplete:r,showPin:i,autoFocus:a}){let o=(0,m.useRef)([]);function s(e,r){r.key===`Backspace`?(r.preventDefault(),t[e]?n(t.slice(0,e)+t.slice(e+1)):e>0&&(n(t.slice(0,e-1)+t.slice(e)),o.current[e-1]?.focus())):r.key===`ArrowLeft`&&e>0?o.current[e-1]?.focus():r.key===`ArrowRight`&&e<5?o.current[e+1]?.focus():r.key===`Enter`&&(r.preventDefault(),r.currentTarget.form?.requestSubmit())}function c(e,i){let a=i.nativeEvent.data;if(!a||!/^\d$/.test(a))return;let s=t.split(``);for(s[e]=a;s.length<e;)s.push(``);let c=s.join(``).replace(/\D/g,``).slice(0,6);n(c),c.length===6?r?.(c):e<5&&o.current[e+1]?.focus()}function l(e){e.preventDefault();let t=e.clipboardData.getData(`text`).replace(/\D/g,``).slice(0,6);t&&(n(t),t.length===6?r?.(t):o.current[t.length]?.focus())}return(0,g.jsx)(`div`,{className:`pin-field`,children:Array.from({length:6}).map((n,r)=>(0,g.jsx)(`input`,{ref:t=>{o.current[r]=t,r===0&&e&&(e.current=t)},type:`text`,inputMode:`numeric`,className:`pin-box${t[r]?` pin-box-filled`:``}`,value:t[r]?i?t[r]:`•`:``,onKeyDown:e=>s(r,e),onInput:e=>c(r,e),onPaste:l,onFocus:e=>e.target.select(),autoFocus:a&&r===0,autoComplete:`off`,maxLength:1,"aria-label":`PIN digit ${r+1}`},r))})}function v(e){let{pin:t,setPin:n,showPin:r,setShowPin:a,pinLoading:s,pinError:c,pinInputRef:d,setPinFormRef:f,onSubmit:p,operatorName:m,setOperatorName:h}=e;return(0,g.jsx)(`div`,{className:`connect-page`,children:(0,g.jsxs)(`div`,{className:`connect-content`,children:[(0,g.jsx)(`img`,{src:i,alt:o.productName,className:`connect-logo connect-logo--maxy`}),!o.logoContainsName&&(0,g.jsxs)(`h1`,{className:`connect-title`,children:[`Welcome to `,o.productName]}),(0,g.jsxs)(`p`,{className:`connect-subtitle`,children:[`Tell `,o.productName,` who you are, then choose a PIN.`]}),(0,g.jsxs)(`form`,{ref:f,onSubmit:p,className:`connect-pin-form`,children:[(0,g.jsxs)(`div`,{className:`pin-input-row`,children:[(0,g.jsx)(`input`,{type:`text`,className:`connect-name-input`,placeholder:`Your full name`,value:m,onChange:e=>h(e.target.value),autoComplete:`name`,autoFocus:!0,required:!0,"aria-label":`Your full name`}),(0,g.jsx)(`div`,{style:{width:38,flexShrink:0},"aria-hidden":`true`})]}),(0,g.jsxs)(`div`,{className:`pin-input-row`,children:[(0,g.jsx)(_,{inputRef:d,value:t,onChange:n,onComplete:()=>{},showPin:r}),(0,g.jsx)(l,{variant:`send`,type:`submit`,disabled:!t||!m.trim(),loading:s,"aria-label":`Set PIN`,children:(0,g.jsxs)(`svg`,{viewBox:`0 0 24 24`,fill:`none`,stroke:`currentColor`,strokeWidth:`2`,strokeLinecap:`round`,strokeLinejoin:`round`,children:[(0,g.jsx)(`line`,{x1:`5`,y1:`12`,x2:`19`,y2:`12`}),(0,g.jsx)(`polyline`,{points:`12 5 19 12 12 19`})]})})]}),(0,g.jsx)(u,{checked:r,onChange:()=>a(e=>!e),label:`Show PIN`})]}),c&&(0,g.jsx)(`p`,{className:`admin-pin-error`,children:c})]})})}function y(e){let{pin:t,setPin:n,showPin:r,setShowPin:a,pinLoading:s,pinError:c,pinInputRef:d,onSubmit:f,onChangePin:p,remoteAuthEnabled:m,onSignOutRemote:h}=e;return(0,g.jsxs)(`div`,{className:`connect-page`,children:[m&&h&&(0,g.jsx)(`button`,{type:`button`,className:`connect-signout`,onClick:h,children:`Sign out`}),(0,g.jsxs)(`div`,{className:`connect-content`,children:[(0,g.jsx)(`img`,{src:i,alt:o.productName,className:`connect-logo connect-logo--maxy`}),!o.logoContainsName&&(0,g.jsx)(`h1`,{className:`connect-title`,children:o.productName}),(0,g.jsxs)(`form`,{onSubmit:f,className:`connect-pin-form`,children:[(0,g.jsxs)(`div`,{className:`pin-input-row`,children:[(0,g.jsx)(_,{inputRef:d,value:t,onChange:n,onComplete:()=>{},showPin:r,autoFocus:!0}),(0,g.jsx)(l,{variant:`send`,type:`submit`,disabled:!t,loading:s,children:(0,g.jsxs)(`svg`,{viewBox:`0 0 24 24`,fill:`none`,stroke:`currentColor`,strokeWidth:`2`,strokeLinecap:`round`,strokeLinejoin:`round`,children:[(0,g.jsx)(`line`,{x1:`5`,y1:`12`,x2:`19`,y2:`12`}),(0,g.jsx)(`polyline`,{points:`12 5 19 12 12 19`})]})})]}),(0,g.jsxs)(`div`,{className:`pin-options`,children:[(0,g.jsx)(u,{checked:r,onChange:()=>a(e=>!e),label:`Show PIN`}),(0,g.jsx)(l,{type:`button`,variant:`ghost`,onClick:p,children:`Change PIN`})]})]}),c&&(0,g.jsx)(`p`,{className:`admin-pin-error`,children:c})]})]})}function b(e){let{accounts:t,loading:r,error:a,onSelect:s}=e;return(0,g.jsx)(`div`,{className:`connect-page`,children:(0,g.jsxs)(`div`,{className:`connect-content`,children:[(0,g.jsx)(`img`,{src:i,alt:o.productName,className:`connect-logo connect-logo--maxy`}),!o.logoContainsName&&(0,g.jsx)(`h1`,{className:`connect-title`,children:o.productName}),(0,g.jsx)(`p`,{className:`connect-subtitle`,children:`Select an account`}),(0,g.jsx)(`div`,{className:`account-picker-list`,children:t.map(e=>(0,g.jsxs)(`button`,{className:`account-picker-card`,onClick:()=>s(e.accountId),disabled:r,type:`button`,children:[(0,g.jsx)(`span`,{className:`account-picker-name`,children:e.businessName||e.accountId}),(0,g.jsx)(`span`,{className:`account-picker-role`,children:e.role}),r&&(0,g.jsx)(n,{className:`account-picker-spinner`,size:16})]},e.accountId))}),a&&(0,g.jsx)(`p`,{className:`admin-pin-error`,children:a})]})})}function x(e){let{authPolling:t,setAuthPolling:n,authLoading:r,setAuthLoading:a,pinError:s,setPinError:c,setAppState:u}=e,[d,f]=(0,m.useState)(!1),[p,h]=(0,m.useState)(!1);async function _(){h(!0),c(``);try{let e=await(await fetch(`/api/onboarding/claude-auth`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({action:`launch-browser`})})).json();e.launched?f(!0):e.error&&c(e.error)}catch(e){console.error(`[admin] browser launch error:`,e),c(`Could not launch browser.`)}h(!1)}async function v(){a(!0),c(``);try{let e=await(await fetch(`/api/onboarding/claude-auth`,{method:`POST`})).json();if(e.started){n(!0),f(!0),a(!1);for(let e=0;e<120;e++)if(await new Promise(e=>setTimeout(e,2e3)),(await(await fetch(`/api/onboarding/claude-auth`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({action:`wait`})})).json()).authenticated){await fetch(`/api/onboarding/claude-auth`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({action:`stop`})}),u(`enter-pin`);return}c(`Timed out waiting for sign-in. Try again.`),n(!1)}else e.error&&c(e.error)}catch(e){console.error(`[admin] auth flow error:`,e),c(`Could not start auth flow.`)}a(!1)}async function y(){await fetch(`/api/onboarding/claude-auth`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({action:`stop`})}),n(!1),c(``)}return t||d?(0,g.jsxs)(`div`,{style:{display:`flex`,flexDirection:`column`,height:`100dvh`,overflow:`auto`},children:[(0,g.jsxs)(`header`,{className:`chat-header`,style:{paddingBottom:`12px`,flexShrink:0,position:`relative`,maxWidth:`680px`,width:`100%`,margin:`0 auto`,padding:`24px 20px 12px`},children:[t?(0,g.jsx)(`button`,{onClick:y,style:{position:`absolute`,top:`12px`,right:`12px`,background:`none`,border:`none`,color:`#999`,fontSize:`13px`,cursor:`pointer`,padding:`4px 8px`},"aria-label":`Cancel`,children:`✕`}):(0,g.jsx)(`button`,{onClick:()=>f(!1),style:{position:`absolute`,top:`12px`,right:`12px`,background:`none`,border:`none`,color:`#999`,fontSize:`13px`,cursor:`pointer`,padding:`4px 8px`},"aria-label":`Close browser`,children:`✕`}),(0,g.jsx)(`img`,{src:`/brand/claude.png`,alt:`Claude`,className:`chat-logo`}),(0,g.jsx)(`h1`,{className:`chat-tagline`,children:`Connect Claude`}),(0,g.jsx)(`p`,{className:`chat-intro`,children:t?`Sign in and authorize in the browser below.`:`Open your email or prepare your accounts, then sign in.`}),!t&&(0,g.jsx)(`div`,{style:{marginTop:`12px`},children:(0,g.jsx)(l,{variant:`primary`,onClick:v,disabled:r,children:r?(0,g.jsxs)(g.Fragment,{children:[(0,g.jsx)(`span`,{className:`spin`,style:{display:`inline-block`},children:`✱`}),` Connecting…`]}):`Sign in to Claude`})})]}),(0,g.jsx)(`div`,{style:{flex:1,display:`flex`,flexDirection:`column`,minHeight:0,gap:`10px`,padding:`0 0 16px`},children:(0,g.jsx)(`iframe`,{src:`/vnc-viewer.html`,style:{flex:1,width:`100%`,minHeight:0,border:`none`,background:`#111`,display:`block`},title:`Claude Sign-in`})}),s&&(0,g.jsx)(`p`,{className:`admin-pin-error`,style:{textAlign:`center`,padding:`0 20px 16px`},children:s})]}):(0,g.jsx)(`div`,{className:`connect-page`,children:(0,g.jsxs)(`div`,{className:`connect-content`,children:[(0,g.jsxs)(`div`,{className:`connect-logos`,children:[(0,g.jsx)(`div`,{className:`connect-logo-wrap`,children:(0,g.jsx)(`img`,{src:`/brand/claude.png`,alt:`Claude`,className:`connect-logo`})}),(0,g.jsx)(`svg`,{className:`connect-arrow`,viewBox:`0 0 48 24`,fill:`none`,xmlns:`http://www.w3.org/2000/svg`,children:(0,g.jsx)(`path`,{d:`M0 12h44m0 0l-8-8m8 8l-8 8`,stroke:`currentColor`,strokeWidth:`2`,strokeLinecap:`round`,strokeLinejoin:`round`})}),(0,g.jsxs)(`div`,{className:`connect-logo-wrap`,children:[(0,g.jsx)(`img`,{src:i,alt:o.productName,className:`connect-logo connect-logo--maxy`}),!o.logoContainsName&&(0,g.jsx)(`span`,{className:`connect-logo-label`,children:o.productName})]})]}),(0,g.jsxs)(`h1`,{className:`connect-title`,children:[`Connect Claude to power `,o.productName]}),(0,g.jsx)(`p`,{className:`connect-subtitle`,children:`Sign in with your Anthropic account to get started.`}),(0,g.jsx)(l,{variant:`primary`,onClick:v,disabled:r,children:r?(0,g.jsxs)(g.Fragment,{children:[(0,g.jsx)(`span`,{className:`spin`,style:{display:`inline-block`},children:`✱`}),` Connecting…`]}):`Sign in to Claude`}),(0,g.jsx)(`p`,{style:{marginTop:`6px`,fontSize:`11px`,color:`#999`,maxWidth:`300px`,textAlign:`center`,lineHeight:`1.4`},children:`First time? You may need to sign into your email and Anthropic account in the browser before connecting.`}),(0,g.jsx)(`button`,{onClick:_,disabled:p,style:{marginTop:`12px`,background:`none`,border:`none`,color:`var(--color-primary, #666)`,fontSize:`13px`,cursor:`pointer`,textDecoration:`underline`,textUnderlineOffset:`3px`},children:p?`Launching…`:`Open browser first`}),s&&(0,g.jsx)(`p`,{className:`admin-pin-error`,children:s})]})})}function S({auth:e}){return e.appState===`loading`?(0,g.jsx)(`div`,{className:`connect-page`}):e.appState===`set-pin`?(0,g.jsx)(v,{pin:e.pin,setPin:e.setPin,showPin:e.showPin,setShowPin:e.setShowPin,pinLoading:e.pinLoading,pinError:e.pinError,pinInputRef:e.pinInputRef,setPinFormRef:e.setPinFormRef,onSubmit:e.handleSetPin,operatorName:e.operatorName,setOperatorName:e.setOperatorName}):e.appState===`connect-claude`?(0,g.jsx)(x,{authPolling:e.authPolling,setAuthPolling:e.setAuthPolling,authLoading:e.authLoading,setAuthLoading:e.setAuthLoading,pinError:e.pinError,setPinError:e.setPinError,setAppState:e.setAppState}):e.appState===`enter-pin`?(0,g.jsx)(y,{pin:e.pin,setPin:e.setPin,showPin:e.showPin,setShowPin:e.setShowPin,pinLoading:e.pinLoading,pinError:e.pinError,pinInputRef:e.pinInputRef,onSubmit:e.handleLogin,onChangePin:e.handleChangePin,remoteAuthEnabled:e.remoteAuthEnabled,onSignOutRemote:()=>{console.info(`[admin-ui] remote-auth sign-out → /__remote-auth/logout`),window.location.href=`/__remote-auth/logout`}}):e.appState===`account-picker`?(0,g.jsx)(b,{accounts:e.accounts,loading:e.accountPickerLoading,error:e.pinError,onSelect:e.handleAccountSelect}):null}export{h as n,S as t};
1
+ import{o as e}from"./chunk-Pqm5yXtL.js";import{L as t,O as n,V as r,b as i,x as a,y as o}from"./OperatorConversations-BqFmHTF1.js";import{i as s}from"./admin-types-CJrGd46U.js";import{h as c,l}from"./AdminShell-DqyjA9x-.js";import{t as u}from"./Checkbox-C3WNcLH8.js";var d=`admin-landing-redirected`,f=`/graph`;function p(e){return e.variant===`operator`?!1:e.appState===`chat`&&!e.alreadyRedirected}var m=e(r(),1);function h(e=`admin`){let[n,r]=(0,m.useState)(`loading`),[i,a]=(0,m.useState)(``),[o,l]=(0,m.useState)(``),[u,h]=(0,m.useState)(``),[g,_]=(0,m.useState)(!1),[v,y]=(0,m.useState)(!1),[b,x]=(0,m.useState)(!1),[S,C]=(0,m.useState)(!1),[w,T]=(0,m.useState)(!1),[E,D]=(0,m.useState)(null),[O,k]=(0,m.useState)(null),[A,j]=(0,m.useState)(void 0),[M,N]=(0,m.useState)(null),[P,F]=(0,m.useState)(void 0),[I,L]=(0,m.useState)(null),[ee,R]=(0,m.useState)(null),[z,B]=(0,m.useState)([]),[V,H]=(0,m.useState)(!1),[U,W]=(0,m.useState)(void 0),G=(0,m.useRef)(void 0),[K,q]=(0,m.useState)(!1);(0,m.useEffect)(()=>{typeof window>`u`||fetch(`/api/remote-auth/status`).then(e=>e.ok?e.json():null).then(e=>{e?.configured&&q(!0)}).catch(()=>{})},[]);let J=(0,m.useRef)(null),Y=(0,m.useRef)(null);(0,m.useEffect)(()=>{async function e(){let e=null;try{e=sessionStorage.getItem(`maxy-admin-session-key`)}catch{}if(!e)return!1;try{let t=await fetch(`/api/admin/session?session_key=${encodeURIComponent(e)}`);if(t.status===401){try{sessionStorage.removeItem(`maxy-admin-session-key`)}catch{}return!1}if(!t.ok)return!1;let n=await t.json();D(n.session_key),R(n.sessionId??null),j(n.businessName),N(n.role??null),F(n.userName===void 0?null:n.userName),L(n.avatar??null);let i=s(n.thinkingView);return G.current=i,W(i),r(`chat`),!0}catch(e){return console.error(`[admin] session restore failed:`,e),!1}}async function t(n=2){try{let i=await fetch(`/api/health`);if(!i.ok){if(n>0)return await new Promise(e=>setTimeout(e,1500)),t(n-1);console.error(`[admin] health check returned ${i.status} after retries`),r(`set-pin`);return}let a=await i.json();if(!a.pin_configured){r(`set-pin`);return}if(!a.claude_authenticated){r(`connect-claude`);return}if(await e())return;r(`enter-pin`)}catch(e){if(n>0)return await new Promise(e=>setTimeout(e,1500)),t(n-1);console.error(`[admin] health check failed:`,e),r(`set-pin`)}}t()},[]),(0,m.useEffect)(()=>{n===`chat`&&fetch(`/api/admin/claude-info`).then(e=>{if(e.ok)return e.json()}).then(e=>{e&&k(e)}).catch(()=>{})},[n]),(0,m.useEffect)(()=>{if(typeof window>`u`)return;let t=!1;try{t=sessionStorage.getItem(d)===`1`}catch{}if(p({appState:n,alreadyRedirected:t,variant:e})){try{sessionStorage.setItem(d,`1`)}catch{}console.info(`[admin-ui] landing-redirect target=${f}`),window.location.replace(f)}},[n,e]);let X=(0,m.useRef)(null);(0,m.useEffect)(()=>{if(n!==`chat`)return;let e=setInterval(async()=>{try{let e=await fetch(`/api/health`);if(e.ok){let t=await e.json();if(t.auth_status===`dead`||t.auth_status===`missing`){r(`connect-claude`);return}}}catch{}if(E)try{let e=await fetch(`/api/admin/session?session_key=${encodeURIComponent(E)}`);if(e.status!==401)return;let n=(await e.clone().json().catch(()=>null))?.code??`unknown-401`;if(n===`remote-auth-required`){t(`heartbeat`,`/api/admin/session`);return}console.warn(`[admin-auth] outcome=heartbeat-detected-expiry code=${n}`),X.current?.()}catch{}},300*1e3);return()=>clearInterval(e)},[n,E]),(0,m.useEffect)(()=>{n===`connect-claude`&&fetch(`/api/health`).then(e=>e.ok?e.json():null).then(e=>{e?.claude_authenticated&&r(`enter-pin`)}).catch(()=>{})},[n]);async function Z(e,t){y(!0);try{let n=await fetch(`/api/admin/session`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({pin:e,...t?{accountId:t}:{}})});if(!n.ok){h((await n.json().catch(()=>({}))).error||`Invalid PIN`);return}let i=await n.json();if(i.accounts&&!i.session_key){console.log(`[admin] account picker shown: userId=${i.userId} accountCount=${i.accounts.length}`),B(i.accounts),r(`account-picker`);return}D(i.session_key),R(i.sessionId??null),j(i.businessName),N(i.role??null),F(i.userName===void 0?null:i.userName),L(i.avatar??null);let o=s(i.thinkingView);if(G.current=o,W(o),t)try{sessionStorage.setItem(`maxy-account-id`,t)}catch{}try{sessionStorage.setItem(`maxy-admin-session-key`,i.session_key)}catch{}a(``),r(`chat`)}catch(e){console.error(`[admin] connection error:`,e),h(`Could not connect.`)}finally{y(!1),H(!1)}}let Q=(0,m.useCallback)(async e=>{if(e.preventDefault(),v)return;h(``);let t=o.trim();if(!t){h(`Please enter your name.`);return}if(i.length<4){h(`PIN must be at least 4 characters.`);return}let n=i;y(!0);try{let e=await fetch(`/api/onboarding/set-pin`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({pin:n,name:t})});if(!e.ok){let t=await e.json().catch(()=>({}));if(e.status===409){console.log(`[admin] PIN already configured — re-checking health`);try{let e=await fetch(`/api/health`);if(e.ok){let n=await e.json();n.pin_configured&&n.claude_authenticated?r(`enter-pin`):n.pin_configured?r(`connect-claude`):h(t.error||`Failed to set PIN.`)}else r(`enter-pin`)}catch{r(`enter-pin`)}return}h(t.error||`Failed to set PIN.`);return}let i=await fetch(`/api/health`);if((i.ok?await i.json():null)?.claude_authenticated){await Z(n);return}a(``),r(`connect-claude`)}catch(e){console.error(`[admin] connection error:`,e),h(`Could not connect.`)}finally{y(!1)}},[i,v,o]),te=(0,m.useCallback)(async e=>{e.preventDefault(),h(``),await Z(i)},[i]),ne=(0,m.useCallback)(async()=>{T(!0);try{if(!await c())return console.warn(`[admin-ui] claude-disconnect not verified — credentials may persist; staying put`),!1;D(null),N(null),F(void 0),L(null);try{sessionStorage.removeItem(`maxy-admin-session-key`),sessionStorage.removeItem(`maxy-account-id`),sessionStorage.removeItem(d)}catch{}return r(`connect-claude`),!0}finally{T(!1)}},[]),$=(0,m.useCallback)(()=>{D(null),N(null),F(void 0),L(null);try{sessionStorage.removeItem(`maxy-admin-session-key`),sessionStorage.removeItem(`maxy-account-id`),sessionStorage.removeItem(d)}catch{}a(``),h(``),r(`enter-pin`)},[]);return(0,m.useEffect)(()=>{X.current=$},[$]),{appState:n,setAppState:r,pin:i,setPin:a,operatorName:o,setOperatorName:l,pinError:u,setPinError:h,showPin:g,setShowPin:_,pinLoading:v,authPolling:b,setAuthPolling:x,authLoading:S,setAuthLoading:C,disconnecting:w,cacheKey:E,setCacheKey:D,claudeInfo:O,setClaudeInfo:k,businessName:A,role:M,userName:P,userAvatar:I,sessionId:ee,setSessionId:R,accounts:z,accountPickerLoading:V,expandAll:U,setExpandAll:W,expandAllDefaultRef:G,remoteAuthEnabled:K,pinInputRef:J,setPinFormRef:Y,handleSetPin:Q,handleLogin:te,handleAccountSelect:(0,m.useCallback)(async e=>{H(!0),h(``),await Z(i,e)},[i]),handleDisconnect:ne,handleLogout:$,handleChangePin:(0,m.useCallback)(async()=>{if(!i){h(`Enter your current PIN first.`);return}y(!0),h(``);try{let e=await fetch(`/api/onboarding/set-pin`,{method:`DELETE`,headers:{"Content-Type":`application/json`},body:JSON.stringify({currentPin:i})});if(!e.ok){h((await e.json().catch(()=>({error:`Incorrect PIN.`}))).error||`Incorrect PIN.`);return}a(``),h(``),r(`set-pin`)}catch(e){console.error(`[admin-auth] change pin failed:`,e),h(e instanceof Error?e.message:String(e))}finally{y(!1)}},[i])}}var g=a();function _({inputRef:e,value:t,onChange:n,onComplete:r,showPin:i,autoFocus:a}){let o=(0,m.useRef)([]);function s(e,r){r.key===`Backspace`?(r.preventDefault(),t[e]?n(t.slice(0,e)+t.slice(e+1)):e>0&&(n(t.slice(0,e-1)+t.slice(e)),o.current[e-1]?.focus())):r.key===`ArrowLeft`&&e>0?o.current[e-1]?.focus():r.key===`ArrowRight`&&e<5?o.current[e+1]?.focus():r.key===`Enter`&&(r.preventDefault(),r.currentTarget.form?.requestSubmit())}function c(e,i){let a=i.nativeEvent.data;if(!a||!/^\d$/.test(a))return;let s=t.split(``);for(s[e]=a;s.length<e;)s.push(``);let c=s.join(``).replace(/\D/g,``).slice(0,6);n(c),c.length===6?r?.(c):e<5&&o.current[e+1]?.focus()}function l(e){e.preventDefault();let t=e.clipboardData.getData(`text`).replace(/\D/g,``).slice(0,6);t&&(n(t),t.length===6?r?.(t):o.current[t.length]?.focus())}return(0,g.jsx)(`div`,{className:`pin-field`,children:Array.from({length:6}).map((n,r)=>(0,g.jsx)(`input`,{ref:t=>{o.current[r]=t,r===0&&e&&(e.current=t)},type:`text`,inputMode:`numeric`,className:`pin-box${t[r]?` pin-box-filled`:``}`,value:t[r]?i?t[r]:`•`:``,onKeyDown:e=>s(r,e),onInput:e=>c(r,e),onPaste:l,onFocus:e=>e.target.select(),autoFocus:a&&r===0,autoComplete:`off`,maxLength:1,"aria-label":`PIN digit ${r+1}`},r))})}function v(e){let{pin:t,setPin:n,showPin:r,setShowPin:a,pinLoading:s,pinError:c,pinInputRef:d,setPinFormRef:f,onSubmit:p,operatorName:m,setOperatorName:h}=e;return(0,g.jsx)(`div`,{className:`connect-page`,children:(0,g.jsxs)(`div`,{className:`connect-content`,children:[(0,g.jsx)(`img`,{src:i,alt:o.productName,className:`connect-logo connect-logo--maxy`}),!o.logoContainsName&&(0,g.jsxs)(`h1`,{className:`connect-title`,children:[`Welcome to `,o.productName]}),(0,g.jsxs)(`p`,{className:`connect-subtitle`,children:[`Tell `,o.productName,` who you are, then choose a PIN.`]}),(0,g.jsxs)(`form`,{ref:f,onSubmit:p,className:`connect-pin-form`,children:[(0,g.jsxs)(`div`,{className:`pin-input-row`,children:[(0,g.jsx)(`input`,{type:`text`,className:`connect-name-input`,placeholder:`Your full name`,value:m,onChange:e=>h(e.target.value),autoComplete:`name`,autoFocus:!0,required:!0,"aria-label":`Your full name`}),(0,g.jsx)(`div`,{style:{width:38,flexShrink:0},"aria-hidden":`true`})]}),(0,g.jsxs)(`div`,{className:`pin-input-row`,children:[(0,g.jsx)(_,{inputRef:d,value:t,onChange:n,onComplete:()=>{},showPin:r}),(0,g.jsx)(l,{variant:`send`,type:`submit`,disabled:!t||!m.trim(),loading:s,"aria-label":`Set PIN`,children:(0,g.jsxs)(`svg`,{viewBox:`0 0 24 24`,fill:`none`,stroke:`currentColor`,strokeWidth:`2`,strokeLinecap:`round`,strokeLinejoin:`round`,children:[(0,g.jsx)(`line`,{x1:`5`,y1:`12`,x2:`19`,y2:`12`}),(0,g.jsx)(`polyline`,{points:`12 5 19 12 12 19`})]})})]}),(0,g.jsx)(u,{checked:r,onChange:()=>a(e=>!e),label:`Show PIN`})]}),c&&(0,g.jsx)(`p`,{className:`admin-pin-error`,children:c})]})})}function y(e){let{pin:t,setPin:n,showPin:r,setShowPin:a,pinLoading:s,pinError:c,pinInputRef:d,onSubmit:f,onChangePin:p,remoteAuthEnabled:m,onSignOutRemote:h}=e;return(0,g.jsxs)(`div`,{className:`connect-page`,children:[m&&h&&(0,g.jsx)(`button`,{type:`button`,className:`connect-signout`,onClick:h,children:`Sign out`}),(0,g.jsxs)(`div`,{className:`connect-content`,children:[(0,g.jsx)(`img`,{src:i,alt:o.productName,className:`connect-logo connect-logo--maxy`}),!o.logoContainsName&&(0,g.jsx)(`h1`,{className:`connect-title`,children:o.productName}),(0,g.jsxs)(`form`,{onSubmit:f,className:`connect-pin-form`,children:[(0,g.jsxs)(`div`,{className:`pin-input-row`,children:[(0,g.jsx)(_,{inputRef:d,value:t,onChange:n,onComplete:()=>{},showPin:r,autoFocus:!0}),(0,g.jsx)(l,{variant:`send`,type:`submit`,disabled:!t,loading:s,children:(0,g.jsxs)(`svg`,{viewBox:`0 0 24 24`,fill:`none`,stroke:`currentColor`,strokeWidth:`2`,strokeLinecap:`round`,strokeLinejoin:`round`,children:[(0,g.jsx)(`line`,{x1:`5`,y1:`12`,x2:`19`,y2:`12`}),(0,g.jsx)(`polyline`,{points:`12 5 19 12 12 19`})]})})]}),(0,g.jsxs)(`div`,{className:`pin-options`,children:[(0,g.jsx)(u,{checked:r,onChange:()=>a(e=>!e),label:`Show PIN`}),(0,g.jsx)(l,{type:`button`,variant:`ghost`,onClick:p,children:`Change PIN`})]})]}),c&&(0,g.jsx)(`p`,{className:`admin-pin-error`,children:c})]})]})}function b(e){let{accounts:t,loading:r,error:a,onSelect:s}=e;return(0,g.jsx)(`div`,{className:`connect-page`,children:(0,g.jsxs)(`div`,{className:`connect-content`,children:[(0,g.jsx)(`img`,{src:i,alt:o.productName,className:`connect-logo connect-logo--maxy`}),!o.logoContainsName&&(0,g.jsx)(`h1`,{className:`connect-title`,children:o.productName}),(0,g.jsx)(`p`,{className:`connect-subtitle`,children:`Select an account`}),(0,g.jsx)(`div`,{className:`account-picker-list`,children:t.map(e=>(0,g.jsxs)(`button`,{className:`account-picker-card`,onClick:()=>s(e.accountId),disabled:r,type:`button`,children:[(0,g.jsx)(`span`,{className:`account-picker-name`,children:e.businessName||e.accountId}),(0,g.jsx)(`span`,{className:`account-picker-role`,children:e.role}),r&&(0,g.jsx)(n,{className:`account-picker-spinner`,size:16})]},e.accountId))}),a&&(0,g.jsx)(`p`,{className:`admin-pin-error`,children:a})]})})}function x(e){let{authPolling:t,setAuthPolling:n,authLoading:r,setAuthLoading:a,pinError:s,setPinError:c,setAppState:u}=e,[d,f]=(0,m.useState)(!1),[p,h]=(0,m.useState)(!1);async function _(){h(!0),c(``);try{let e=await(await fetch(`/api/onboarding/claude-auth`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({action:`launch-browser`})})).json();e.launched?f(!0):e.error&&c(e.error)}catch(e){console.error(`[admin] browser launch error:`,e),c(`Could not launch browser.`)}h(!1)}async function v(){a(!0),c(``);try{let e=await(await fetch(`/api/onboarding/claude-auth`,{method:`POST`})).json();if(e.started){n(!0),f(!0),a(!1);for(let e=0;e<120;e++)if(await new Promise(e=>setTimeout(e,2e3)),(await(await fetch(`/api/onboarding/claude-auth`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({action:`wait`})})).json()).authenticated){await fetch(`/api/onboarding/claude-auth`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({action:`stop`})}),u(`enter-pin`);return}c(`Timed out waiting for sign-in. Try again.`),n(!1)}else e.error&&c(e.error)}catch(e){console.error(`[admin] auth flow error:`,e),c(`Could not start auth flow.`)}a(!1)}async function y(){await fetch(`/api/onboarding/claude-auth`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({action:`stop`})}),n(!1),c(``)}return t||d?(0,g.jsxs)(`div`,{style:{display:`flex`,flexDirection:`column`,height:`100dvh`,overflow:`auto`},children:[(0,g.jsxs)(`header`,{className:`chat-header`,style:{paddingBottom:`12px`,flexShrink:0,position:`relative`,maxWidth:`680px`,width:`100%`,margin:`0 auto`,padding:`24px 20px 12px`},children:[t?(0,g.jsx)(`button`,{onClick:y,style:{position:`absolute`,top:`12px`,right:`12px`,background:`none`,border:`none`,color:`#999`,fontSize:`13px`,cursor:`pointer`,padding:`4px 8px`},"aria-label":`Cancel`,children:`✕`}):(0,g.jsx)(`button`,{onClick:()=>f(!1),style:{position:`absolute`,top:`12px`,right:`12px`,background:`none`,border:`none`,color:`#999`,fontSize:`13px`,cursor:`pointer`,padding:`4px 8px`},"aria-label":`Close browser`,children:`✕`}),(0,g.jsx)(`img`,{src:`/brand/claude.png`,alt:`Claude`,className:`chat-logo`}),(0,g.jsx)(`h1`,{className:`chat-tagline`,children:`Connect Claude`}),(0,g.jsx)(`p`,{className:`chat-intro`,children:t?`Sign in and authorize in the browser below.`:`Open your email or prepare your accounts, then sign in.`}),!t&&(0,g.jsx)(`div`,{style:{marginTop:`12px`},children:(0,g.jsx)(l,{variant:`primary`,onClick:v,disabled:r,children:r?(0,g.jsxs)(g.Fragment,{children:[(0,g.jsx)(`span`,{className:`spin`,style:{display:`inline-block`},children:`✱`}),` Connecting…`]}):`Sign in to Claude`})})]}),(0,g.jsx)(`div`,{style:{flex:1,display:`flex`,flexDirection:`column`,minHeight:0,gap:`10px`,padding:`0 0 16px`},children:(0,g.jsx)(`iframe`,{src:`/vnc-viewer.html`,style:{flex:1,width:`100%`,minHeight:0,border:`none`,background:`#111`,display:`block`},title:`Claude Sign-in`})}),s&&(0,g.jsx)(`p`,{className:`admin-pin-error`,style:{textAlign:`center`,padding:`0 20px 16px`},children:s})]}):(0,g.jsx)(`div`,{className:`connect-page`,children:(0,g.jsxs)(`div`,{className:`connect-content`,children:[(0,g.jsxs)(`div`,{className:`connect-logos`,children:[(0,g.jsx)(`div`,{className:`connect-logo-wrap`,children:(0,g.jsx)(`img`,{src:`/brand/claude.png`,alt:`Claude`,className:`connect-logo`})}),(0,g.jsx)(`svg`,{className:`connect-arrow`,viewBox:`0 0 48 24`,fill:`none`,xmlns:`http://www.w3.org/2000/svg`,children:(0,g.jsx)(`path`,{d:`M0 12h44m0 0l-8-8m8 8l-8 8`,stroke:`currentColor`,strokeWidth:`2`,strokeLinecap:`round`,strokeLinejoin:`round`})}),(0,g.jsxs)(`div`,{className:`connect-logo-wrap`,children:[(0,g.jsx)(`img`,{src:i,alt:o.productName,className:`connect-logo connect-logo--maxy`}),!o.logoContainsName&&(0,g.jsx)(`span`,{className:`connect-logo-label`,children:o.productName})]})]}),(0,g.jsxs)(`h1`,{className:`connect-title`,children:[`Connect Claude to power `,o.productName]}),(0,g.jsx)(`p`,{className:`connect-subtitle`,children:`Sign in with your Anthropic account to get started.`}),(0,g.jsx)(l,{variant:`primary`,onClick:v,disabled:r,children:r?(0,g.jsxs)(g.Fragment,{children:[(0,g.jsx)(`span`,{className:`spin`,style:{display:`inline-block`},children:`✱`}),` Connecting…`]}):`Sign in to Claude`}),(0,g.jsx)(`p`,{style:{marginTop:`6px`,fontSize:`11px`,color:`#999`,maxWidth:`300px`,textAlign:`center`,lineHeight:`1.4`},children:`First time? You may need to sign into your email and Anthropic account in the browser before connecting.`}),(0,g.jsx)(`button`,{onClick:_,disabled:p,style:{marginTop:`12px`,background:`none`,border:`none`,color:`var(--color-primary, #666)`,fontSize:`13px`,cursor:`pointer`,textDecoration:`underline`,textUnderlineOffset:`3px`},children:p?`Launching…`:`Open browser first`}),s&&(0,g.jsx)(`p`,{className:`admin-pin-error`,children:s})]})})}function S({auth:e}){return e.appState===`loading`?(0,g.jsx)(`div`,{className:`connect-page`}):e.appState===`set-pin`?(0,g.jsx)(v,{pin:e.pin,setPin:e.setPin,showPin:e.showPin,setShowPin:e.setShowPin,pinLoading:e.pinLoading,pinError:e.pinError,pinInputRef:e.pinInputRef,setPinFormRef:e.setPinFormRef,onSubmit:e.handleSetPin,operatorName:e.operatorName,setOperatorName:e.setOperatorName}):e.appState===`connect-claude`?(0,g.jsx)(x,{authPolling:e.authPolling,setAuthPolling:e.setAuthPolling,authLoading:e.authLoading,setAuthLoading:e.setAuthLoading,pinError:e.pinError,setPinError:e.setPinError,setAppState:e.setAppState}):e.appState===`enter-pin`?(0,g.jsx)(y,{pin:e.pin,setPin:e.setPin,showPin:e.showPin,setShowPin:e.setShowPin,pinLoading:e.pinLoading,pinError:e.pinError,pinInputRef:e.pinInputRef,onSubmit:e.handleLogin,onChangePin:e.handleChangePin,remoteAuthEnabled:e.remoteAuthEnabled,onSignOutRemote:()=>{console.info(`[admin-ui] remote-auth sign-out → /__remote-auth/logout`),window.location.href=`/__remote-auth/logout`}}):e.appState===`account-picker`?(0,g.jsx)(b,{accounts:e.accounts,loading:e.accountPickerLoading,error:e.pinError,onSelect:e.handleAccountSelect}):null}export{h as n,S as t};