arkaos 3.77.0 → 4.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (91) hide show
  1. package/VERSION +1 -1
  2. package/config/agent-allowlists/laravel.yaml +1 -0
  3. package/config/agent-allowlists/node.yaml +1 -0
  4. package/config/agent-allowlists/nuxt.yaml +1 -0
  5. package/config/agent-allowlists/python.yaml +1 -0
  6. package/core/agents/__pycache__/registry_gen.cpython-313.pyc +0 -0
  7. package/core/agents/__pycache__/schema.cpython-313.pyc +0 -0
  8. package/core/agents/registry_gen.py +6 -1
  9. package/core/agents/schema.py +4 -0
  10. package/core/cognition/__pycache__/reorganizer.cpython-313.pyc +0 -0
  11. package/core/cognition/reorganizer.py +37 -7
  12. package/core/governance/__pycache__/design_system_lint.cpython-313.pyc +0 -0
  13. package/core/governance/__pycache__/design_system_lint_cli.cpython-313.pyc +0 -0
  14. package/core/knowledge/__pycache__/agent_match.cpython-313.pyc +0 -0
  15. package/core/knowledge/__pycache__/chunker.cpython-313.pyc +0 -0
  16. package/core/knowledge/__pycache__/ingest.cpython-313.pyc +0 -0
  17. package/core/knowledge/__pycache__/sources.cpython-313.pyc +0 -0
  18. package/core/knowledge/__pycache__/vector_store.cpython-313.pyc +0 -0
  19. package/core/knowledge/agent_match.py +114 -0
  20. package/core/knowledge/chunker.py +45 -0
  21. package/core/knowledge/ingest.py +156 -78
  22. package/core/knowledge/sources.py +138 -0
  23. package/core/knowledge/vector_store.py +52 -0
  24. package/core/squads/__pycache__/loader.cpython-313.pyc +0 -0
  25. package/core/squads/loader.py +25 -0
  26. package/core/sync/__pycache__/agent_provisioner.cpython-313.pyc +0 -0
  27. package/core/sync/agent_provisioner.py +19 -8
  28. package/dashboard/app/components/KnowledgeSourcesList.vue +40 -13
  29. package/dashboard/app/pages/cognition.vue +9 -4
  30. package/dashboard/app/pages/knowledge/[id].vue +669 -0
  31. package/dashboard/app/pages/knowledge/index.vue +1281 -0
  32. package/dashboard/app/types/index.d.ts +1 -1
  33. package/departments/brand/agents/brand-director.yaml +2 -0
  34. package/departments/brand/agents/creative-director.md +4 -0
  35. package/departments/brand/agents/motion-designer.md +5 -1
  36. package/departments/brand/agents/ux-designer.yaml +26 -1
  37. package/departments/brand/agents/ux-researcher.yaml +73 -0
  38. package/departments/brand/agents/ux-strategist.yaml +72 -0
  39. package/departments/brand/agents/visual-designer.md +4 -0
  40. package/departments/brand/agents/visual-designer.yaml +11 -0
  41. package/departments/brand/references/uiux-knowledge-and-tools.md +136 -0
  42. package/departments/dev/agents/ai-engineering/ai-engineering-lead.yaml +76 -0
  43. package/departments/dev/agents/architect.yaml +9 -3
  44. package/departments/dev/agents/backend-core/laravel-eng.yaml +76 -0
  45. package/departments/dev/agents/backend-core/node-ts-eng.yaml +76 -0
  46. package/departments/dev/agents/backend-core/python-eng.yaml +76 -0
  47. package/departments/dev/agents/backend-dev.yaml +10 -4
  48. package/departments/dev/agents/data-platform/etl-eng.yaml +74 -0
  49. package/departments/dev/agents/dba.yaml +7 -3
  50. package/departments/dev/agents/frontend-dev.md +41 -11
  51. package/departments/dev/agents/frontend-dev.yaml +6 -0
  52. package/departments/dev/references/backend-knowledge-and-tools.md +70 -0
  53. package/departments/ecom/agents/retention-manager.yaml +13 -1
  54. package/departments/leadership/agents/culture-coach.yaml +20 -0
  55. package/departments/leadership/agents/hr-specialist.yaml +18 -0
  56. package/departments/leadership/agents/leadership-director.yaml +10 -0
  57. package/departments/org/agents/chief-of-staff.yaml +76 -0
  58. package/departments/org/agents/coo.yaml +11 -0
  59. package/departments/org/agents/okr-steward.yaml +71 -0
  60. package/departments/org/agents/org-designer.yaml +23 -0
  61. package/departments/org/skills/okr-cadence/SKILL.md +34 -0
  62. package/departments/org/skills/principles-audit/SKILL.md +36 -0
  63. package/departments/pm/agents/pm-director.yaml +21 -8
  64. package/departments/pm/agents/product-owner.yaml +24 -2
  65. package/departments/pm/agents/scrum-master.yaml +21 -0
  66. package/departments/pm/agents/strategic-pm.yaml +72 -0
  67. package/departments/pm/skills/discovery-plan/SKILL.md +7 -1
  68. package/departments/quality/agents/cqo.yaml +8 -0
  69. package/departments/saas/agents/cs-manager.yaml +19 -2
  70. package/departments/saas/agents/growth-engineer.yaml +14 -1
  71. package/departments/saas/agents/metrics-analyst.yaml +17 -1
  72. package/departments/saas/agents/revops-lead.yaml +73 -0
  73. package/departments/saas/skills/leaky-bucket/SKILL.md +28 -0
  74. package/departments/saas/skills/voc-loop/SKILL.md +29 -0
  75. package/departments/sales/agents/sales-director.yaml +9 -0
  76. package/departments/sales/agents/sdr.yaml +72 -0
  77. package/departments/strategy/agents/decision-quality.yaml +72 -0
  78. package/departments/strategy/agents/strategy-director.yaml +13 -0
  79. package/departments/strategy/skills/premortem/SKILL.md +33 -0
  80. package/installer/claude-plugins.js +32 -3
  81. package/installer/doctor.js +15 -0
  82. package/installer/frontend-tooling.js +150 -0
  83. package/installer/index.js +28 -0
  84. package/installer/keys.js +1 -0
  85. package/installer/update.js +35 -0
  86. package/knowledge/agents-registry-v2.json +1218 -78
  87. package/package.json +1 -1
  88. package/pyproject.toml +1 -1
  89. package/scripts/__pycache__/dashboard-api.cpython-313.pyc +0 -0
  90. package/scripts/dashboard-api.py +376 -13
  91. package/dashboard/app/pages/knowledge.vue +0 -918
@@ -0,0 +1,73 @@
1
+ id: revops-lead-vicente
2
+ name: Vicente
3
+ role: RevOps Lead
4
+ department: saas
5
+ tier: 1
6
+ model: sonnet
7
+
8
+ behavioral_dna:
9
+ disc:
10
+ primary: D
11
+ secondary: C
12
+ communication_style: "Numbers-first, dashboard-driven, breaks silos between mkt/sales/CS"
13
+ under_pressure: "Unifies the funnel view, fixes the leakiest stage first"
14
+ motivator: "One revenue engine — shared metrics, no departmental silos"
15
+ enneagram:
16
+ type: 3
17
+ wing: 2
18
+ core_motivation: "A predictable, compounding revenue machine end-to-end"
19
+ core_fear: "Siloed funnels and unowned hand-offs leaking revenue"
20
+ subtype: social
21
+ big_five:
22
+ openness: 72
23
+ conscientiousness: 82
24
+ extraversion: 58
25
+ agreeableness: 45
26
+ neuroticism: 26
27
+ mbti:
28
+ type: ENTJ
29
+
30
+ mental_models:
31
+ primary:
32
+ - "Predictable Revenue (Ross)"
33
+ - "Shared revenue metrics (no silos)"
34
+ - "RevOps — unified CRM + funnel"
35
+ secondary:
36
+ - "LTV/CAC ≥ 3 & NRR > 100%"
37
+ - "KB-first (Obsidian canonical source)"
38
+
39
+ authority:
40
+ orchestrate: true
41
+ delegates_to: []
42
+ escalates_to: saas-strategist-tiago
43
+
44
+ expertise:
45
+ domains:
46
+ - revenue operations (cross mkt + sales + CS)
47
+ - unified funnel & CRM hygiene
48
+ - SLA MQL→SQL between marketing and sales
49
+ - revenue metrics (LTV/CAC, NRR, payback)
50
+ - lead scoring & routing
51
+ - commission & forecast modeling
52
+ frameworks:
53
+ - Predictable Revenue (Ross)
54
+ - "Loops > Funnels"
55
+ - Unit Economics (LTV/CAC, NRR)
56
+ - RevOps
57
+ knowledge_sources:
58
+ - "[[Receita Previsivel - Aaron Ross]]"
59
+ - "[[2026-05-30 G4 Pass - Metricas Comerciais Cluster]]"
60
+ - "[[2026-05-30 G4 Pass - Loops de Crescimento Sao Novos Funis]]"
61
+ - "[[Autonomia Por Missões (Não Departamentos)]]"
62
+ depth: expert
63
+ years_equivalent: 11
64
+
65
+ communication:
66
+ language: en
67
+ tone: "data-driven, funnel-oriented, breaks silos"
68
+ vocabulary_level: specialist
69
+ preferred_format: "revenue dashboards, funnel maps, SLA definitions"
70
+ avoid:
71
+ - "departmental metrics that hide the whole funnel"
72
+ - "unowned hand-offs between mkt/sales/CS"
73
+ - "acquisition spend before fixing churn (Leaky Bucket)"
@@ -0,0 +1,28 @@
1
+ ---
2
+ name: saas/leaky-bucket
3
+ description: >
4
+ Leaky-Bucket gate — audit churn and retention BEFORE approving acquisition
5
+ spend. Every 1% of churn compounds against LTV forever, so fix the bucket
6
+ before pouring more in. Owned by the RevOps squad.
7
+ allowed-tools: [Read, Write, Edit, Agent]
8
+ ---
9
+
10
+ # Leaky-Bucket Gate — `/saas leaky-bucket`
11
+
12
+ > **Agent:** Vicente (RevOps Lead) + Patricia (Head of CS) · **Framework:** Leaky Bucket / Retention-first
13
+ > KB: [[Leaky-Bucket Diagnostic]] · [[Retention Flywheel]] · [[Atendimento Como Gerador de Receita]]
14
+
15
+ A **gate** to run before any acquisition campaign or CAC increase. If the bucket leaks, more traffic just leaks faster.
16
+
17
+ ## The gate (pass/fail before acquisition)
18
+ 1. **Measure current churn** (logo + revenue) vs benchmark: B2C 5-7%/mo, B2B 1-2%/mo, Enterprise <1%/mo.
19
+ 2. **NRR check:** is Net Revenue Retention > 100%? If < 100%, expansion is not covering churn → **gate fails**.
20
+ 3. **Activation check:** time-to-first-value and activation rate healthy? Most churn happens between onboarding and the first quick win (48-72h).
21
+ 4. **Compounding math:** show LTV at current churn vs LTV at target churn. A 1-point churn improvement usually beats a 1-point CAC improvement.
22
+
23
+ ## Verdict
24
+ - **PASS** → acquisition is approved; the new revenue will stick.
25
+ - **FAIL** → freeze/limit acquisition; route to the Retain & Recover missions to fix onboarding, NRR and win-back first, then re-run the gate.
26
+
27
+ ## Output
28
+ A short gate report (churn, NRR, activation, LTV-at-current-vs-target) + verdict, in Obsidian. Wire into the Acquire mission as a pre-condition.
@@ -0,0 +1,29 @@
1
+ ---
2
+ name: saas/voc-loop
3
+ description: >
4
+ Voice of Customer loop — collect signal, close the loop with the customer,
5
+ cluster the themes, and run PDCA. Only 1 in 26 unhappy customers complains,
6
+ so closing the loop beats collecting more. Owned by the RevOps squad.
7
+ allowed-tools: [Read, Write, Edit, Agent]
8
+ ---
9
+
10
+ # Voice of Customer Loop — `/saas voc-loop`
11
+
12
+ > **Agent:** Rita S. (SaaS Metrics & VoC Analyst) · **Framework:** Voice of Customer + CX metrics
13
+ > KB: [[Processo Voice of Customer (VoC)]] · [[8 Métricas de CX (Nardon-Siqueira)]]
14
+
15
+ A continuous loop, not a one-off survey. For every 26 dissatisfied customers, only 1 complains — so the signal is scarce and closing the loop matters more than collecting.
16
+
17
+ ## The loop (continuous)
18
+ 1. **Collect** across sources: NPS, CSAT (interaction), CES (friction), support tickets, churn reasons, sales-lost reasons.
19
+ 2. **Close the loop** with the customer who gave the signal — respond, acknowledge, tell them what changed. (This is the step most teams skip and where the value is.)
20
+ 3. **Cluster** signals into themes before acting (don't react to single anecdotes).
21
+ 4. **PDCA:** Plan a fix for the top theme → Do (ship) → Check (did the metric move?) → Act (standardise or revert).
22
+
23
+ ## Metric distinctions (don't conflate)
24
+ - **NPS** = macro loyalty (would you recommend?)
25
+ - **CSAT** = immediate interaction satisfaction
26
+ - **CES** = effort/friction (96% of high-effort customers become less loyal)
27
+
28
+ ## Output
29
+ A VoC theme report (clustered, ranked) + closed-loop log + the PDCA experiment status, in Obsidian. Feed themes to the Activate/Retain missions and to Product (Carolina) for discovery.
@@ -33,6 +33,8 @@ mental_models:
33
33
  - "Challenger Sale (Dixon/Adamson)"
34
34
  - "MEDDIC Qualification"
35
35
  secondary:
36
+ - "Predictable Revenue (Ross)"
37
+ - "Living ICP"
36
38
  - "Sandler Selling System"
37
39
  - "Pipeline Velocity Formula"
38
40
  - "BATNA Negotiation"
@@ -53,6 +55,10 @@ expertise:
53
55
  - discovery calls
54
56
  - deal qualification
55
57
  - revenue forecasting
58
+ - The Ask Method (diagnose before offering)
59
+ - living ICP definition (top 20% most profitable; quarterly review; ICP != Persona)
60
+ - MQL→SQL funnel with SLAs
61
+ - predictable revenue engine (Seeds/Nets/Spears; SDR→AE→CSM specialization)
56
62
  frameworks:
57
63
  - SPIN Selling
58
64
  - Challenger Sale
@@ -60,6 +66,9 @@ expertise:
60
66
  - Sandler
61
67
  - Pipeline Velocity
62
68
  - BATNA
69
+ - The Ask Method
70
+ - "Predictable Revenue (Seeds/Nets/Spears) [[Receita Previsivel - Aaron Ross]]"
71
+ - "MQL→SQL conversion & ICP [[Conversao MQL-SQL e ICP]]"
63
72
  depth: expert
64
73
  years_equivalent: 12
65
74
 
@@ -0,0 +1,72 @@
1
+ id: sdr-martim
2
+ name: Martim
3
+ role: SDR / Pre-Sales
4
+ department: sales
5
+ tier: 2
6
+ model: sonnet
7
+
8
+ behavioral_dna:
9
+ disc:
10
+ primary: I
11
+ secondary: D
12
+ communication_style: "Energetic, outreach-driven, qualifies fast and warmly"
13
+ under_pressure: "Doubles outreach volume, sharpens the qualifying questions"
14
+ motivator: "A full, well-qualified pipeline handed clean to the closers"
15
+ enneagram:
16
+ type: 3
17
+ wing: 2
18
+ core_motivation: "Opening doors and qualifying the right-fit prospects at scale"
19
+ core_fear: "An empty or junk-filled pipeline; wasting the closer's time"
20
+ subtype: social
21
+ big_five:
22
+ openness: 66
23
+ conscientiousness: 68
24
+ extraversion: 78
25
+ agreeableness: 60
26
+ neuroticism: 28
27
+ mbti:
28
+ type: ESFP
29
+
30
+ mental_models:
31
+ primary:
32
+ - "Predictable Revenue — Spears / Cold Calling 2.0 (Ross)"
33
+ - "MQL→SQL qualification with SLA"
34
+ - "ICP fit scoring (not persona)"
35
+ secondary:
36
+ - "The Ask Method (ask before pitching)"
37
+ - "KB-first (Obsidian canonical source)"
38
+
39
+ authority:
40
+ push_code: false
41
+ delegates_to: []
42
+ escalates_to: sales-director-miguel
43
+
44
+ expertise:
45
+ domains:
46
+ - top-of-funnel prospecting & outreach
47
+ - lead qualification (MQL→SQL)
48
+ - cold email & cold calling 2.0
49
+ - ICP fit scoring & disqualification
50
+ - cadence / sequence design
51
+ - hand-off to Account Executive
52
+ frameworks:
53
+ - Predictable Revenue (Seeds/Nets/Spears)
54
+ - "MQL/SQL + SLA"
55
+ - The Ask Method
56
+ - ICP (top 20% most profitable)
57
+ knowledge_sources:
58
+ - "[[Receita Previsivel - Aaron Ross]]"
59
+ - "[[2026-05-30 G4 Pass - MQL e SQL]]"
60
+ - "[[2026-05-30 G4 Pass - Conversao MQL-SQL e ICP]]"
61
+ depth: expert
62
+ years_equivalent: 6
63
+
64
+ communication:
65
+ language: en
66
+ tone: "energetic, concise, qualification-first"
67
+ vocabulary_level: advanced
68
+ preferred_format: "outreach sequences, qualification notes, clean SQL hand-offs"
69
+ avoid:
70
+ - "pitching before qualifying"
71
+ - "passing unqualified leads to closers"
72
+ - "ignoring the ICP fit"
@@ -0,0 +1,72 @@
1
+ id: decision-quality-guilherme
2
+ name: Guilherme
3
+ role: Decision Quality & Strategic Foresight
4
+ department: strategy
5
+ tier: 2
6
+ model: sonnet
7
+
8
+ behavioral_dna:
9
+ disc:
10
+ primary: C
11
+ secondary: D
12
+ communication_style: "Asks for the 3rd alternative, surfaces the trade-off and the bet"
13
+ under_pressure: "Runs a premortem, separates reversible from irreversible decisions"
14
+ motivator: "Decisions that are well-framed, debiased, and revisited"
15
+ enneagram:
16
+ type: 5
17
+ wing: 6
18
+ core_motivation: "Clear thinking under uncertainty — the right call, well-reasoned"
19
+ core_fear: "A big irreversible bet made on HiPPO, consensus, or bias"
20
+ subtype: self-preservation
21
+ big_five:
22
+ openness: 85
23
+ conscientiousness: 82
24
+ extraversion: 32
25
+ agreeableness: 45
26
+ neuroticism: 26
27
+ mbti:
28
+ type: INTJ
29
+
30
+ mental_models:
31
+ primary:
32
+ - "Strategy is trade-off (we do A, NOT B)"
33
+ - "Premortem + two-way doors (Bezos)"
34
+ - "Debiasing (anti-HiPPO / anti-consensus)"
35
+ secondary:
36
+ - "Strategic foresight (scenarios, anticipate trends)"
37
+ - "KB-first (Obsidian canonical source)"
38
+
39
+ authority:
40
+ push_code: false
41
+ delegates_to: []
42
+ escalates_to: strategy-director-tomas
43
+
44
+ expertise:
45
+ domains:
46
+ - decision framing & 3+ alternatives
47
+ - reversible vs irreversible (two-way doors)
48
+ - cognitive debiasing (HiPPO, consensus, anchoring)
49
+ - premortem / postmortem facilitation
50
+ - scenario planning & strategic foresight
51
+ - bias-to-action check
52
+ frameworks:
53
+ - HBR 5-Element Decision Process
54
+ - Premortem (Klein)
55
+ - Two-Way Doors (Bezos)
56
+ - "4 Strategic Insight Techniques"
57
+ knowledge_sources:
58
+ - "[[2026-05-30 G4 Pass - Cluster Estrategia e Decisao HBR]]"
59
+ - "[[2026-05-30 G4 Pass - Bias to Action]]"
60
+ - "[[Vieses - Erros para Decisao]]"
61
+ depth: expert
62
+ years_equivalent: 10
63
+
64
+ communication:
65
+ language: en
66
+ tone: "analytical, probing, trade-off explicit"
67
+ vocabulary_level: specialist
68
+ preferred_format: "decision briefs (problem, 3+ options, trade-off, decider, review date)"
69
+ avoid:
70
+ - "single-option decisions"
71
+ - "HiPPO or consensus as the deciding force"
72
+ - "irreversible bets without a premortem"
@@ -29,10 +29,14 @@ behavioral_dna:
29
29
 
30
30
  mental_models:
31
31
  primary:
32
+ - "Strategy is trade-off (we choose A, we do NOT do B)"
33
+ - "7 Strata + BHAG (Harnish)"
32
34
  - "Playing to Win Cascade (Roger Martin)"
33
35
  - "Porter's Five Forces"
34
36
  - "Blue Ocean Strategy (Kim/Mauborgne)"
35
37
  secondary:
38
+ - "Strategic foresight (scenarios, anticipate trends)"
39
+ - "KB-first (Obsidian canonical source)"
36
40
  - "7 Powers / Moat Analysis (Helmer)"
37
41
  - "Wardley Maps (Wardley)"
38
42
  - "Business Model Canvas (Osterwalder)"
@@ -53,6 +57,9 @@ expertise:
53
57
  - positioning
54
58
  - innovation strategy
55
59
  - scenario planning
60
+ - trade-off framing (explicit choose A / NOT B)
61
+ - strategic foresight (scenarios, trend anticipation)
62
+ - long-range vision setting (BHAGs)
56
63
  frameworks:
57
64
  - Five Forces (Porter)
58
65
  - Playing to Win (Martin)
@@ -62,8 +69,14 @@ expertise:
62
69
  - 7 Powers (Helmer)
63
70
  - TAM/SAM/SOM
64
71
  - SWOT/PESTLE
72
+ - 7 Strata of Strategy (Scaling Up / Harnish)
73
+ - BHAG - Big Hairy Audacious Goal (Collins/Harnish)
74
+ - One-Page Strategic Plan (Scaling Up / Harnish)
65
75
  depth: expert
66
76
  years_equivalent: 12
77
+ knowledge_sources:
78
+ - "[[Scaling Up - Verne Harnish]]"
79
+ - "[[Cluster Estrategia e Decisao HBR]]"
67
80
 
68
81
  communication:
69
82
  language: en
@@ -0,0 +1,33 @@
1
+ ---
2
+ name: strat/premortem
3
+ description: >
4
+ Run a premortem before a big bet and a blameless postmortem after.
5
+ Decision-quality ritual: imagine the failure, surface risks, then learn
6
+ from the outcome without blame. Owned by the Governance squad.
7
+ allowed-tools: [Read, Write, Edit, Agent]
8
+ ---
9
+
10
+ # Premortem & Blameless Postmortem — `/strat premortem`
11
+
12
+ > **Agent:** Guilherme (Decision Quality & Strategic Foresight) · escalates to the Governance squad (Afonso)
13
+ > **Framework:** Premortem (Klein) + Blameless Postmortem · KB: [[2026-05-30 G4 Pass - Cluster Estrategia e Decisao HBR]]
14
+
15
+ Use **before** any irreversible or high-stakes bet (a "two-way door" is reversible — skip it; a "one-way door" needs this).
16
+
17
+ ## Premortem (before the decision)
18
+ 1. **State the bet** in one sentence + the decider (RACI) + the deadline.
19
+ 2. **Assume it failed.** "It's 6 months from now and this was a disaster. Why?"
20
+ 3. Each participant writes failure causes independently (avoids groupthink/HiPPO).
21
+ 4. Cluster the causes; rank by likelihood × impact.
22
+ 5. For the top causes: add a mitigation or a kill-criterion. If a cause is fatal and unmitigable → **don't take the bet**.
23
+ 6. Record: 3+ alternatives considered, the trade-off ("we do A, NOT B"), the decider, the review date.
24
+
25
+ ## Blameless Postmortem (after the outcome)
26
+ 1. **Timeline of what happened** — facts, not blame. Systems fail, not people.
27
+ 2. What did we predict in the premortem that came true / didn't?
28
+ 3. **Root cause** (5 Whys) — stop at a system/process, never at a person.
29
+ 4. Lessons → concrete changes (a guardrail, a check, a default). Assign an owner.
30
+ 5. Cheap failure is learning: Coca-Cola, Netflix and Amazon institutionalise this.
31
+
32
+ ## Output
33
+ A decision record (premortem) + a postmortem note in Obsidian, linked to the bet. Feeds the org's learning loop.
@@ -16,10 +16,18 @@ import { execSync, spawnSync } from "node:child_process";
16
16
  import { homedir } from "node:os";
17
17
  import { join } from "node:path";
18
18
 
19
+ // Third-party marketplaces that must be registered (via
20
+ // `claude plugin marketplace add <repo>`) before their plugins can be
21
+ // installed. Each entry is a GitHub `owner/repo` shorthand.
22
+ export const DEFAULT_CLAUDE_MARKETPLACES = [
23
+ "nextlevelbuilder/ui-ux-pro-max-skill",
24
+ ];
25
+
19
26
  // Each entry is "name@marketplace" matching the `claude plugin install`
20
27
  // CLI argument format.
21
28
  export const DEFAULT_CLAUDE_PLUGINS = [
22
29
  "frontend-design@claude-plugins-official",
30
+ "ui-ux-pro-max@ui-ux-pro-max-skill",
23
31
  ];
24
32
 
25
33
  const _INSTALLED_REGISTRY = join(
@@ -29,19 +37,40 @@ const _INSTALLED_REGISTRY = join(
29
37
  export function installDefaultClaudePlugins({
30
38
  runtime = "claude-code",
31
39
  plugins = DEFAULT_CLAUDE_PLUGINS,
40
+ marketplaces = DEFAULT_CLAUDE_MARKETPLACES,
32
41
  home = homedir(),
33
42
  } = {}) {
34
43
  if (runtime !== "claude-code") {
35
- return { skipped: "runtime-not-claude-code", results: [] };
44
+ return { skipped: "runtime-not-claude-code", results: [], marketplaces: [] };
36
45
  }
37
46
  if (!isClaudeCliAvailable()) {
38
- return { skipped: "claude-cli-not-found", results: [] };
47
+ return { skipped: "claude-cli-not-found", results: [], marketplaces: [] };
39
48
  }
49
+ // Marketplaces must be registered before their plugins can resolve.
50
+ const marketplaceResults = marketplaces.map((m) => addMarketplace(m));
40
51
  const alreadyInstalled = readInstalledRegistry(home);
41
52
  const results = plugins.map((p) =>
42
53
  installOne(p, alreadyInstalled),
43
54
  );
44
- return { skipped: null, results };
55
+ return { skipped: null, results, marketplaces: marketplaceResults };
56
+ }
57
+
58
+ // Register a third-party plugin marketplace. Idempotent and never-throws:
59
+ // a marketplace that is already known is reported as already-present.
60
+ function addMarketplace(marketplace) {
61
+ const out = spawnSync("claude", ["plugin", "marketplace", "add", marketplace], {
62
+ timeout: 60_000,
63
+ stdio: ["ignore", "pipe", "pipe"],
64
+ encoding: "utf-8",
65
+ });
66
+ if (out.status === 0) {
67
+ return { marketplace, action: "added" };
68
+ }
69
+ const msg = (out.stderr || out.error?.message || "").toLowerCase();
70
+ if (msg.includes("already") || msg.includes("exists")) {
71
+ return { marketplace, action: "already-present" };
72
+ }
73
+ return { marketplace, action: "failed", reason: msg.trim().slice(0, 200) };
45
74
  }
46
75
 
47
76
  function isClaudeCliAvailable() {
@@ -195,6 +195,21 @@ const checks = [
195
195
  },
196
196
  fix: () => "Upgrade Claude Code: npm install -g @anthropic-ai/claude-code@latest",
197
197
  },
198
+ {
199
+ name: "magic-api-key",
200
+ description: "Magic API key configured (frontend UI/UX — Magic MCP)",
201
+ severity: "warn",
202
+ check: () => {
203
+ if (process.env.MAGIC_API_KEY) return true;
204
+ const keysPath = join(INSTALL_DIR, "keys.json");
205
+ if (!existsSync(keysPath)) return false;
206
+ try {
207
+ const keys = JSON.parse(readFileSync(keysPath, "utf-8"));
208
+ return !!keys.MAGIC_API_KEY;
209
+ } catch { return false; }
210
+ },
211
+ fix: () => "Run: npx arkaos keys set MAGIC_API_KEY <your-21st-dev-key> (or re-run npx arkaos@latest update)",
212
+ },
198
213
  ];
199
214
 
200
215
  // ─── Windows-only checks ───────────────────────────────────────────────
@@ -0,0 +1,150 @@
1
+ // Frontend UI/UX tooling setup for `npx arkaos install` and
2
+ // `npx arkaos@latest update`.
3
+ //
4
+ // Wires three operator-mandated tools into the install/update flow:
5
+ // 1. Magic MCP (@21st-dev/magic) — user-scope, API-key gated. The key is
6
+ // prompted interactively when missing and never stored in the repo;
7
+ // it lives only in ~/.arkaos/keys.json (chmod 600) + Claude user config.
8
+ // 2. Motion AI Kit (npx motion-ai) — auto-run on every install/update.
9
+ // 3. (ui-ux-pro-max plugin + marketplace is handled in claude-plugins.js.)
10
+ //
11
+ // Invariants (.claude/rules/node-installer.md):
12
+ // - ESM, os.homedir()/path.join only, never hardcoded paths.
13
+ // - No interactive prompts during headless/CI runs (guarded by isTTY).
14
+ // - Never throws — every failure is logged and swallowed so the installer
15
+ // never breaks on optional tooling.
16
+
17
+ import { existsSync, readFileSync, writeFileSync, chmodSync } from "node:fs";
18
+ import { execSync, spawnSync } from "node:child_process";
19
+ import { createInterface } from "node:readline";
20
+ import { homedir } from "node:os";
21
+ import { join } from "node:path";
22
+
23
+ const MAGIC_ENV = "MAGIC_API_KEY";
24
+
25
+ function keysPath(home) {
26
+ return join(home, ".arkaos", "keys.json");
27
+ }
28
+
29
+ function loadKeys(home) {
30
+ const path = keysPath(home);
31
+ if (!existsSync(path)) return {};
32
+ try { return JSON.parse(readFileSync(path, "utf-8")); } catch { return {}; }
33
+ }
34
+
35
+ function saveKey(home, name, value) {
36
+ const path = keysPath(home);
37
+ const keys = loadKeys(home);
38
+ keys[name] = value;
39
+ writeFileSync(path, JSON.stringify(keys, null, 2));
40
+ try { chmodSync(path, 0o600); } catch {}
41
+ }
42
+
43
+ // Resolve the Magic API key from (in order) keys.json, then the environment.
44
+ function resolveMagicKey(home) {
45
+ const keys = loadKeys(home);
46
+ return keys[MAGIC_ENV] || process.env[MAGIC_ENV] || "";
47
+ }
48
+
49
+ // Prompt once for the key. Resolves to "" in headless contexts so the
50
+ // installer never blocks on a closed stdin (node-installer rule).
51
+ function promptMagicKey() {
52
+ if (!process.stdin.isTTY) return Promise.resolve("");
53
+ const rl = createInterface({ input: process.stdin, output: process.stdout });
54
+ const q = " 21st.dev Magic API key (frontend UI/UX, leave empty to skip): ";
55
+ return new Promise((resolve) => {
56
+ rl.question(q, (answer) => { rl.close(); resolve((answer || "").trim()); });
57
+ });
58
+ }
59
+
60
+ // Ensure MAGIC_API_KEY exists, prompting interactively when missing.
61
+ // Returns the resolved key (possibly "").
62
+ export async function ensureMagicApiKey({ home = homedir() } = {}) {
63
+ const existing = resolveMagicKey(home);
64
+ if (existing) return existing;
65
+ const entered = await promptMagicKey();
66
+ if (entered) {
67
+ saveKey(home, MAGIC_ENV, entered);
68
+ console.log(" Magic API key saved to ~/.arkaos/keys.json (chmod 600).");
69
+ }
70
+ return entered;
71
+ }
72
+
73
+ function isClaudeCliAvailable() {
74
+ try {
75
+ execSync("claude --version", { stdio: "pipe", timeout: 5000 });
76
+ return true;
77
+ } catch { return false; }
78
+ }
79
+
80
+ function isMagicMcpRegistered() {
81
+ const out = spawnSync("claude", ["mcp", "list"], {
82
+ timeout: 10_000, stdio: ["ignore", "pipe", "pipe"], encoding: "utf-8",
83
+ });
84
+ return out.status === 0 && /(^|\s)magic(\s|:)/.test(out.stdout || "");
85
+ }
86
+
87
+ // Register the Magic MCP at Claude Code user scope. Idempotent and
88
+ // never-throws. Skips on non-Claude runtimes, missing CLI, or missing key.
89
+ export function registerMagicMcp({ runtime = "claude-code", apiKey = "" } = {}) {
90
+ if (runtime !== "claude-code") return { action: "skipped", reason: "runtime-not-claude-code" };
91
+ if (!isClaudeCliAvailable()) return { action: "skipped", reason: "claude-cli-not-found" };
92
+ if (!apiKey) return { action: "skipped", reason: "no-api-key" };
93
+ if (isMagicMcpRegistered()) return { action: "already-present" };
94
+ // NOTE (known limitation): the key is passed as a CLI argument because
95
+ // `claude mcp add` offers no stdin/file alternative. It is briefly
96
+ // visible to `ps`/proc while the child runs. It is NEVER written to the
97
+ // repo or to any log (only stderr is captured into `reason`).
98
+ const out = spawnSync("claude", [
99
+ "mcp", "add", "magic", "--scope", "user",
100
+ "--env", `API_KEY=${apiKey}`,
101
+ "--", "npx", "-y", "@21st-dev/magic@latest",
102
+ ], { timeout: 60_000, stdio: ["ignore", "pipe", "pipe"], encoding: "utf-8" });
103
+ if (out.error || out.status !== 0) {
104
+ const reason = (out.stderr || out.error?.message || "unknown").trim().slice(0, 200);
105
+ return { action: "failed", reason };
106
+ }
107
+ return { action: "registered" };
108
+ }
109
+
110
+ function motionMarkerPath(home) {
111
+ return join(home, ".arkaos", ".motion-kit-installed");
112
+ }
113
+
114
+ // Run the Motion AI Kit. Auto-runs (no prompt) per operator decision
115
+ // (2026-05-30), but idempotently: a one-time marker in ~/.arkaos/ means
116
+ // re-runs (e.g. every `npx arkaos update`) skip the 180s kit instead of
117
+ // re-downloading it. Claude-runtime only, requires the claude CLI (the
118
+ // kit installs Motion skills into the Claude agent), never-throws.
119
+ export function installMotionKit({ runtime = "claude-code", home = homedir() } = {}) {
120
+ if (runtime !== "claude-code") return { action: "skipped", reason: "runtime-not-claude-code" };
121
+ if (!isClaudeCliAvailable()) return { action: "skipped", reason: "claude-cli-not-found" };
122
+ if (existsSync(motionMarkerPath(home))) return { action: "already-present" };
123
+ const out = spawnSync("npx", ["-y", "motion-ai"], {
124
+ timeout: 180_000, stdio: ["ignore", "pipe", "pipe"], encoding: "utf-8",
125
+ });
126
+ if (out.error || out.status !== 0) {
127
+ const reason = (out.stderr || out.error?.message || "unknown").trim().slice(0, 200);
128
+ return { action: "failed", reason };
129
+ }
130
+ try { writeFileSync(motionMarkerPath(home), new Date().toISOString()); } catch {}
131
+ return { action: "installed" };
132
+ }
133
+
134
+ // Orchestrate the full frontend tooling setup. Single entry point wired
135
+ // into both installer/index.js and installer/update.js.
136
+ export async function setupFrontendTooling({ runtime = "claude-code", home = homedir() } = {}) {
137
+ const results = {};
138
+ try {
139
+ const apiKey = await ensureMagicApiKey({ home });
140
+ results.magicMcp = registerMagicMcp({ runtime, apiKey });
141
+ } catch (err) {
142
+ results.magicMcp = { action: "failed", reason: err.message };
143
+ }
144
+ try {
145
+ results.motionKit = installMotionKit({ runtime, home });
146
+ } catch (err) {
147
+ results.motionKit = { action: "failed", reason: err.message };
148
+ }
149
+ return results;
150
+ }
@@ -352,6 +352,13 @@ export async function install({ runtime, path, force, skipSystem, withOllama })
352
352
  const { installDefaultClaudePlugins } = await import("./claude-plugins.js");
353
353
  const pluginResult = installDefaultClaudePlugins({ runtime });
354
354
  if (!pluginResult.skipped) {
355
+ for (const m of pluginResult.marketplaces || []) {
356
+ if (m.action === "added") {
357
+ console.log(` marketplace ${m.marketplace} added.`);
358
+ } else if (m.action === "failed") {
359
+ console.log(` marketplace ${m.marketplace} failed (${m.reason}).`);
360
+ }
361
+ }
355
362
  for (const r of pluginResult.results) {
356
363
  if (r.action === "installed") {
357
364
  console.log(` ${r.plugin} installed.`);
@@ -366,6 +373,27 @@ export async function install({ runtime, path, force, skipSystem, withOllama })
366
373
  console.log(` Warning: could not install default Claude plugins (${err.message})`);
367
374
  }
368
375
 
376
+ // Frontend UI/UX tooling — Magic MCP (user scope, API-key gated) + Motion
377
+ // AI Kit. Key is prompted when missing (interactive only). Never blocks.
378
+ try {
379
+ const { setupFrontendTooling } = await import("./frontend-tooling.js");
380
+ const ft = await setupFrontendTooling({ runtime });
381
+ if (ft.magicMcp?.action === "registered") {
382
+ console.log(" Magic MCP registered (user scope).");
383
+ } else if (ft.magicMcp?.action === "already-present") {
384
+ console.log(" Magic MCP already registered (skipped).");
385
+ } else if (ft.magicMcp?.action === "failed") {
386
+ console.log(` Magic MCP registration failed (${ft.magicMcp.reason}).`);
387
+ }
388
+ if (ft.motionKit?.action === "installed") {
389
+ console.log(" Motion AI Kit installed.");
390
+ } else if (ft.motionKit?.action === "failed") {
391
+ console.log(` Motion AI Kit install failed (${ft.motionKit.reason}).`);
392
+ }
393
+ } catch (err) {
394
+ console.log(` Warning: could not set up frontend tooling (${err.message})`);
395
+ }
396
+
369
397
  const manifest = {
370
398
  version: VERSION,
371
399
  runtime,
package/installer/keys.js CHANGED
@@ -8,6 +8,7 @@ const PROVIDERS = {
8
8
  OPENAI_API_KEY: { name: "OpenAI", used_for: "Whisper transcription, embeddings, GPT" },
9
9
  GOOGLE_API_KEY: { name: "Google", used_for: "Gemini API, Nano Banana, Google Cloud AI" },
10
10
  FAL_API_KEY: { name: "fal.ai", used_for: "Image generation, video generation" },
11
+ MAGIC_API_KEY: { name: "21st.dev Magic", used_for: "Frontend UI/UX component generation (Magic MCP)" },
11
12
  };
12
13
 
13
14
  function loadKeys() {