claude-code-arcane 2.9.8 → 2.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +26 -0
- package/README.md +40 -38
- package/agents/business/business-ops-lead.md +1 -14
- package/agents/game/gameplay-programmer.md +3 -4
- package/agents/game/technical-artist.md +3 -4
- package/dist/cli.js +105 -39
- package/docs/USER-GUIDE.md +24 -22
- package/docs/coordination-rules.md +1 -1
- package/docs/directory-structure.md +93 -122
- package/package.json +1 -1
- package/profiles/ai.yaml +3 -0
- package/profiles/android-native.yaml +2 -0
- package/profiles/backend-go.yaml +1 -8
- package/profiles/backend-ts.yaml +2 -8
- package/profiles/backend-typescript.yaml +51 -0
- package/profiles/flutter.yaml +2 -0
- package/profiles/frontend-react-vite.yaml +39 -0
- package/profiles/frontend.yaml +2 -0
- package/profiles/integrations.yaml +6 -1
- package/profiles/ios-native.yaml +2 -0
- package/profiles/mobile-android-kotlin.yaml +36 -0
- package/profiles/mobile-flutter.yaml +37 -0
- package/profiles/mobile-ios-swift.yaml +37 -0
- package/profiles/mobile-react-native.yaml +39 -0
- package/profiles/mobile.yaml +2 -0
- package/rules/gamedev/engine-code.md +1 -1
- package/rules/gamedev/shader-code.md +1 -2
- package/rules/gamedev/vn-code.md +3 -2
- package/rules/implementation-workflow.md +1 -1
- package/rules/{ai-code.md → llm-code.md} +5 -5
- package/skills/agent-designer/README.md +2 -1
- package/skills/agent-designer/agent_evaluator.py +0 -5
- package/skills/ai-sdk-setup/SKILL.md +4 -4
- package/skills/arcane-add/SKILL.md +1 -1
- package/skills/arcane-list/SKILL.md +3 -3
- package/skills/arcane-status/SKILL.md +1 -1
- package/skills/architecture-decision/SKILL.md +3 -4
- package/skills/architecture-review/SKILL.md +1 -1
- package/skills/asset-audit/SKILL.md +0 -1
- package/skills/balance-check/SKILL.md +1 -1
- package/skills/brainstorm/SKILL.md +3 -3
- package/skills/brainstorm/references/next-steps-pipeline.md +8 -9
- package/skills/consistency-check/SKILL.md +2 -2
- package/skills/design-system/SKILL.md +1 -1
- package/skills/design-system/references/post-design-validation.md +2 -3
- package/skills/freelance-kickoff/SKILL.md +1 -1
- package/skills/frontend-dev/SKILL.md +27 -28
- package/skills/frontend-dev/references/asset-prompt-guide.md +1 -1
- package/skills/frontend-dev/references/motion-recipes.md +1 -1
- package/skills/help/SKILL.md +1 -2
- package/skills/hotfix/SKILL.md +2 -2
- package/skills/milestone-review/SKILL.md +1 -1
- package/skills/patch-notes/SKILL.md +1 -1
- package/skills/playtest-report/SKILL.md +2 -3
- package/skills/playwright-pro/CLAUDE.md +2 -2
- package/skills/playwright-pro/SKILL.md +13 -9
- package/skills/playwright-pro/agents/migration-planner.md +2 -2
- package/skills/playwright-pro/agents/test-architect.md +1 -2
- package/skills/playwright-pro/agents/test-debugger.md +1 -1
- package/skills/playwright-pro/hooks/detect-playwright.sh +1 -1
- package/skills/playwright-pro/skills/browserstack/SKILL.md +5 -5
- package/skills/playwright-pro/skills/migrate/SKILL.md +1 -1
- package/skills/playwright-pro/skills/report/SKILL.md +2 -2
- package/skills/playwright-pro/skills/testrail/SKILL.md +5 -5
- package/skills/playwright-pro/templates/README.md +2 -2
- package/skills/prototype/SKILL.md +1 -1
- package/skills/quick-design/SKILL.md +1 -1
- package/skills/release-checklist/SKILL.md +0 -1
- package/skills/security-audit/SKILL.md +1 -1
- package/skills/self-improving-agent/CLAUDE.md +12 -12
- package/skills/self-improving-agent/SKILL.md +16 -12
- package/skills/self-improving-agent/agents/memory-analyst.md +1 -1
- package/skills/self-improving-agent/hooks/error-capture.sh +2 -2
- package/skills/self-improving-agent/reference/memory-architecture.md +2 -2
- package/skills/self-improving-agent/reference/promotion-rules.md +3 -3
- package/skills/self-improving-agent/reference/rules-directory-patterns.md +1 -1
- package/skills/self-improving-agent/settings.json +5 -5
- package/skills/self-improving-agent/skills/extract/SKILL.md +7 -7
- package/skills/self-improving-agent/skills/promote/SKILL.md +5 -5
- package/skills/self-improving-agent/skills/remember/SKILL.md +9 -9
- package/skills/self-improving-agent/skills/review/SKILL.md +7 -7
- package/skills/self-improving-agent/skills/status/SKILL.md +8 -8
- package/skills/senior-ml-engineer/references/llm_integration_guide.md +14 -31
- package/skills/senior-prompt-engineer/SKILL.md +10 -10
- package/skills/senior-prompt-engineer/references/prompt_engineering_patterns.md +1 -1
- package/skills/senior-prompt-engineer/scripts/agent_orchestrator.py +43 -40
- package/skills/senior-prompt-engineer/scripts/prompt_optimizer.py +23 -66
- package/skills/shader-dev/reference/fluid-simulation.md +4 -4
- package/skills/shader-dev/reference/simulation-physics.md +6 -6
- package/skills/shader-dev/reference/voxel-rendering.md +1 -1
- package/skills/shader-dev/techniques/ambient-occlusion.md +1 -1
- package/skills/shader-dev/techniques/analytic-ray-tracing.md +2 -2
- package/skills/shader-dev/techniques/domain-warping.md +2 -2
- package/skills/shader-dev/techniques/fluid-simulation.md +45 -45
- package/skills/shader-dev/techniques/multipass-buffer.md +24 -24
- package/skills/shader-dev/techniques/normal-estimation.md +1 -1
- package/skills/shader-dev/techniques/particle-system.md +16 -16
- package/skills/shader-dev/techniques/polar-uv-manipulation.md +1 -1
- package/skills/shader-dev/techniques/post-processing.md +7 -7
- package/skills/shader-dev/techniques/sdf-3d.md +1 -1
- package/skills/shader-dev/techniques/simulation-physics.md +24 -24
- package/skills/shader-dev/techniques/sound-synthesis.md +2 -2
- package/skills/shader-dev/techniques/voronoi-cellular-noise.md +1 -1
- package/skills/shader-dev/techniques/voxel-rendering.md +60 -60
- package/skills/smoke-check/SKILL.md +1 -1
- package/skills/sprint-plan/SKILL.md +1 -2
- package/skills/start/SKILL.md +7 -7
- package/skills/story-done/SKILL.md +1 -1
- package/skills/test-helpers/SKILL.md +7 -2
- package/skills/test-setup/SKILL.md +1 -1
- package/skills/ue-actor-component-architecture/SKILL.md +0 -1
- package/skills/ue-ai-navigation/SKILL.md +0 -1
- package/skills/ue-animation-system/SKILL.md +0 -1
- package/skills/ue-async-threading/SKILL.md +0 -1
- package/skills/ue-audio-system/SKILL.md +0 -1
- package/skills/ue-blueprints/SKILL.md +0 -1
- package/skills/ue-character-movement/SKILL.md +0 -1
- package/skills/ue-cpp-foundations/SKILL.md +0 -1
- package/skills/ue-data-assets-tables/SKILL.md +0 -1
- package/skills/ue-editor-tools/SKILL.md +0 -1
- package/skills/ue-game-features/SKILL.md +0 -1
- package/skills/ue-gameplay-abilities/SKILL.md +0 -1
- package/skills/ue-gameplay-framework/SKILL.md +0 -1
- package/skills/ue-input-system/SKILL.md +0 -1
- package/skills/ue-mass-entity/SKILL.md +0 -1
- package/skills/ue-materials-rendering/SKILL.md +0 -1
- package/skills/ue-module-build-system/SKILL.md +0 -1
- package/skills/ue-naming-conventions/SKILL.md +0 -1
- package/skills/ue-networking-replication/SKILL.md +0 -1
- package/skills/ue-niagara-effects/SKILL.md +0 -1
- package/skills/ue-packaging/SKILL.md +0 -1
- package/skills/ue-physics-collision/SKILL.md +0 -1
- package/skills/ue-procedural-generation/SKILL.md +0 -1
- package/skills/ue-project-context/SKILL.md +0 -1
- package/skills/ue-sequencer-cinematics/SKILL.md +0 -1
- package/skills/ue-serialization-savegames/SKILL.md +0 -1
- package/skills/ue-state-trees/SKILL.md +0 -1
- package/skills/ue-testing-debugging/SKILL.md +0 -1
- package/skills/ue-ui-umg-slate/SKILL.md +0 -1
- package/skills/ue-world-level-streaming/SKILL.md +0 -1
- package/skills/ux-review/SKILL.md +1 -1
- package/docs/RELEASE-SETUP.md +0 -99
- package/docs/presentations/arcane-overview-12.pptx +0 -0
- package/docs/presentations/arcane-overview.pptx +0 -0
- package/docs/presentations/build_arcane_deck.py +0 -310
- package/docs/presentations/build_arcane_deck_12.py +0 -399
- package/docs/trusted-publishing-setup.md +0 -163
|
@@ -1,399 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
"""Genera la presentacion DETALLADA de Claude Code Arcane (12 slides, 16:9)."""
|
|
3
|
-
import os
|
|
4
|
-
from pptx import Presentation
|
|
5
|
-
from pptx.util import Inches, Pt
|
|
6
|
-
from pptx.dml.color import RGBColor
|
|
7
|
-
from pptx.enum.text import PP_ALIGN, MSO_ANCHOR
|
|
8
|
-
from pptx.enum.shapes import MSO_SHAPE
|
|
9
|
-
|
|
10
|
-
# ---------- Tema (paleta Arcane: indigo profundo + cian) ----------
|
|
11
|
-
BG = RGBColor(0x1E, 0x1B, 0x4B)
|
|
12
|
-
PANEL = RGBColor(0x2A, 0x25, 0x60)
|
|
13
|
-
PANEL2 = RGBColor(0x31, 0x2E, 0x81)
|
|
14
|
-
VIOLET = RGBColor(0x5B, 0x4F, 0xE8)
|
|
15
|
-
CYAN = RGBColor(0x22, 0xD3, 0xEE)
|
|
16
|
-
WHITE = RGBColor(0xF8, 0xFA, 0xFC)
|
|
17
|
-
LIGHT = RGBColor(0xE5, 0xE7, 0xEB)
|
|
18
|
-
MUTED = RGBColor(0x9C, 0xA3, 0xC4)
|
|
19
|
-
GREEN = RGBColor(0x34, 0xD3, 0x99)
|
|
20
|
-
AMBER = RGBColor(0xFB, 0xBF, 0x24)
|
|
21
|
-
PINK = RGBColor(0xF4, 0x72, 0xB6)
|
|
22
|
-
CODEBG = RGBColor(0x14, 0x11, 0x33)
|
|
23
|
-
FONT = "Calibri"
|
|
24
|
-
MONO = "Consolas"
|
|
25
|
-
|
|
26
|
-
prs = Presentation()
|
|
27
|
-
prs.slide_width = Inches(13.333)
|
|
28
|
-
prs.slide_height = Inches(7.5)
|
|
29
|
-
BLANK = prs.slide_layouts[6]
|
|
30
|
-
SW, SH = prs.slide_width, prs.slide_height
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
def slide():
|
|
34
|
-
s = prs.slides.add_slide(BLANK)
|
|
35
|
-
r = s.shapes.add_shape(MSO_SHAPE.RECTANGLE, 0, 0, SW, SH)
|
|
36
|
-
r.fill.solid(); r.fill.fore_color.rgb = BG
|
|
37
|
-
r.line.fill.background(); r.shadow.inherit = False
|
|
38
|
-
return s
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
def rect(s, x, y, w, h, color, line=None, radius=False, line_w=1.0):
|
|
42
|
-
shp = MSO_SHAPE.ROUNDED_RECTANGLE if radius else MSO_SHAPE.RECTANGLE
|
|
43
|
-
sp = s.shapes.add_shape(shp, Inches(x), Inches(y), Inches(w), Inches(h))
|
|
44
|
-
if color is None:
|
|
45
|
-
sp.fill.background()
|
|
46
|
-
else:
|
|
47
|
-
sp.fill.solid(); sp.fill.fore_color.rgb = color
|
|
48
|
-
if line is None:
|
|
49
|
-
sp.line.fill.background()
|
|
50
|
-
else:
|
|
51
|
-
sp.line.color.rgb = line; sp.line.width = Pt(line_w)
|
|
52
|
-
sp.shadow.inherit = False
|
|
53
|
-
return sp
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
def txt(s, x, y, w, h, runs, align=PP_ALIGN.LEFT, anchor=MSO_ANCHOR.TOP,
|
|
57
|
-
space_after=4, line_spacing=1.0, font=FONT):
|
|
58
|
-
tb = s.shapes.add_textbox(Inches(x), Inches(y), Inches(w), Inches(h))
|
|
59
|
-
tf = tb.text_frame; tf.word_wrap = True
|
|
60
|
-
tf.vertical_anchor = anchor
|
|
61
|
-
for i, para in enumerate(runs):
|
|
62
|
-
p = tf.paragraphs[0] if i == 0 else tf.add_paragraph()
|
|
63
|
-
p.alignment = align
|
|
64
|
-
p.space_after = Pt(space_after); p.space_before = Pt(0)
|
|
65
|
-
p.line_spacing = line_spacing
|
|
66
|
-
for (t, sz, col, bold) in para:
|
|
67
|
-
r = p.add_run(); r.text = t
|
|
68
|
-
r.font.size = Pt(sz); r.font.color.rgb = col
|
|
69
|
-
r.font.bold = bold; r.font.name = font
|
|
70
|
-
return tb
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
def badge(s, n):
|
|
74
|
-
c = s.shapes.add_shape(MSO_SHAPE.OVAL, Inches(12.55), Inches(6.85), Inches(0.42), Inches(0.42))
|
|
75
|
-
c.fill.solid(); c.fill.fore_color.rgb = VIOLET; c.line.fill.background(); c.shadow.inherit = False
|
|
76
|
-
tf = c.text_frame
|
|
77
|
-
p = tf.paragraphs[0]; p.alignment = PP_ALIGN.CENTER
|
|
78
|
-
r = p.add_run(); r.text = str(n)
|
|
79
|
-
r.font.size = Pt(12); r.font.bold = True; r.font.color.rgb = WHITE; r.font.name = FONT
|
|
80
|
-
tf.vertical_anchor = MSO_ANCHOR.MIDDLE
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
def footer(s):
|
|
84
|
-
txt(s, 0.55, 7.02, 6, 0.35, [[("Claude Code Arcane", 9, MUTED, False)]])
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
def kicker(s, text, color=CYAN):
|
|
88
|
-
rect(s, 0.55, 0.55, 0.12, 0.5, color)
|
|
89
|
-
txt(s, 0.8, 0.5, 11.5, 0.45, [[(text, 12.5, color, True)]])
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
def title(s, text, y=0.92, size=32):
|
|
93
|
-
txt(s, 0.78, y, 11.9, 0.9, [[(text, size, WHITE, True)]])
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
def chrome(s, n, kick, ttl, color=CYAN, tsize=32):
|
|
97
|
-
kicker(s, kick, color)
|
|
98
|
-
title(s, ttl, size=tsize)
|
|
99
|
-
badge(s, n); footer(s)
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
# ================= SLIDE 1 — Portada =================
|
|
103
|
-
s = slide()
|
|
104
|
-
rect(s, 0, 0, 0.25, 7.5, VIOLET)
|
|
105
|
-
rect(s, 0.25, 0, 0.08, 7.5, CYAN)
|
|
106
|
-
txt(s, 1.0, 1.55, 11.5, 0.6, [[("CLAUDE CODE", 20, CYAN, True)]])
|
|
107
|
-
txt(s, 1.0, 2.0, 11.5, 1.4, [[("Arcane", 84, WHITE, True)]])
|
|
108
|
-
txt(s, 1.05, 3.42, 11, 0.6, [[("Un gestor de paquetes de configuracion para Claude Code", 21, LIGHT, False)]])
|
|
109
|
-
txt(s, 1.05, 4.0, 11, 0.5, [[("Skills, agentes, hooks y reglas — instalados selectivamente por stack.", 14, MUTED, False)]])
|
|
110
|
-
metrics = [("322", "Skills"), ("86", "Agentes"), ("29", "Profiles"), ("19", "Rules"), ("16", "Hooks")]
|
|
111
|
-
mx, mw, gap = 1.0, 2.12, 0.18
|
|
112
|
-
for i, (num, lbl) in enumerate(metrics):
|
|
113
|
-
x = mx + i * (mw + gap)
|
|
114
|
-
rect(s, x, 4.95, mw, 1.4, PANEL, radius=True)
|
|
115
|
-
rect(s, x, 4.95, 0.09, 1.4, CYAN if i % 2 else VIOLET)
|
|
116
|
-
txt(s, x, 5.12, mw, 0.7, [[(num, 40, WHITE, True)]], align=PP_ALIGN.CENTER)
|
|
117
|
-
txt(s, x, 5.88, mw, 0.4, [[(lbl.upper(), 12, CYAN, True)]], align=PP_ALIGN.CENTER)
|
|
118
|
-
txt(s, 1.0, 6.7, 11, 0.4, [[("Presentacion tecnica + de negocio · Educabot", 12, MUTED, False)]])
|
|
119
|
-
|
|
120
|
-
# ================= SLIDE 2 — Indice / recorrido =================
|
|
121
|
-
s = slide()
|
|
122
|
-
chrome(s, 2, "RECORRIDO", "Que vamos a ver")
|
|
123
|
-
items = [
|
|
124
|
-
("01", "El problema", "Por que la config de Claude no escala"),
|
|
125
|
-
("02", "La idea", "npm, pero para capacidades de IA"),
|
|
126
|
-
("03", "Arquitectura", "Como instala, mergea y deduplica"),
|
|
127
|
-
("04", "Las 4 piezas", "Skills, Agents, Hooks, Rules"),
|
|
128
|
-
("05", "Anatomia de una skill", "Frontmatter + markdown"),
|
|
129
|
-
("06", "Profiles", "El sistema de combinacion LEGO"),
|
|
130
|
-
("07", "Mecanismos avanzados", "Distribucion, update, worktrees"),
|
|
131
|
-
("08", "Calidad", "Testing automatizado de skills"),
|
|
132
|
-
("09", "Por que gana", "vs. las alternativas"),
|
|
133
|
-
("10", "Trade-offs y cierre", "Honesto + casos reales"),
|
|
134
|
-
]
|
|
135
|
-
positions = [(0.78, 2.0 + (i % 5) * 0.95, 0 if i < 5 else 1) for i in range(10)]
|
|
136
|
-
for (num, h, d), i in zip(items, range(10)):
|
|
137
|
-
col = 0 if i < 5 else 1
|
|
138
|
-
x = 0.78 + col * 6.15
|
|
139
|
-
y = 2.0 + (i % 5) * 0.95
|
|
140
|
-
rect(s, x, y, 5.85, 0.82, PANEL, radius=True)
|
|
141
|
-
txt(s, x + 0.25, y, 0.9, 0.82, [[(num, 22, VIOLET, True)]], anchor=MSO_ANCHOR.MIDDLE)
|
|
142
|
-
txt(s, x + 1.15, y + 0.1, 4.5, 0.4, [[(h, 14.5, CYAN, True)]])
|
|
143
|
-
txt(s, x + 1.15, y + 0.45, 4.6, 0.35, [[(d, 11, MUTED, False)]])
|
|
144
|
-
|
|
145
|
-
# ================= SLIDE 3 — El problema =================
|
|
146
|
-
s = slide()
|
|
147
|
-
chrome(s, 3, "POR QUE EXISTE", "El problema que resuelve")
|
|
148
|
-
problems = [
|
|
149
|
-
("Configuracion manual", "Copiar .claude/ a mano en cada proyecto: repetitivo y diverge con el tiempo."),
|
|
150
|
-
("Todo-o-nada", "Un mega-repo cargaria las 322 skills en CADA proyecto: mas tokens, mas ruido, mas latencia."),
|
|
151
|
-
("Sin estandarizacion", "Cada dev configura su Claude distinto. No hay fuente de verdad compartida."),
|
|
152
|
-
("Sin actualizacion", "Una mejora en una skill nunca llega a los proyectos que ya la copiaron."),
|
|
153
|
-
]
|
|
154
|
-
y = 2.0
|
|
155
|
-
for h, d in problems:
|
|
156
|
-
rect(s, 0.78, y, 11.7, 0.95, PANEL, radius=True)
|
|
157
|
-
rect(s, 0.78, y, 0.1, 0.95, VIOLET)
|
|
158
|
-
txt(s, 1.05, y + 0.1, 3.4, 0.75, [[(h, 16, CYAN, True)]], anchor=MSO_ANCHOR.MIDDLE)
|
|
159
|
-
txt(s, 4.5, y + 0.1, 7.8, 0.75, [[(d, 13, LIGHT, False)]], anchor=MSO_ANCHOR.MIDDLE)
|
|
160
|
-
y += 1.08
|
|
161
|
-
txt(s, 0.78, 6.55, 11.8, 0.5,
|
|
162
|
-
[[("Falta una forma modular, versionada y compartible de configurar Claude Code.", 15, WHITE, True)]])
|
|
163
|
-
|
|
164
|
-
# ================= SLIDE 4 — La idea central =================
|
|
165
|
-
s = slide()
|
|
166
|
-
chrome(s, 4, "LA IDEA CENTRAL", "npm, pero para las capacidades de Claude Code")
|
|
167
|
-
txt(s, 0.78, 1.95, 11.7, 0.9,
|
|
168
|
-
[[("En vez de instalar librerias de codigo, instalas ", 16, LIGHT, False),
|
|
169
|
-
("capacidades", 16, CYAN, True),
|
|
170
|
-
(": hacer commits, disenar APIs, correr un sprint, auditar seguridad — adaptadas a tu stack.", 16, LIGHT, False)]],
|
|
171
|
-
line_spacing=1.12)
|
|
172
|
-
rect(s, 0.78, 3.05, 11.7, 1.45, CODEBG, radius=True, line=VIOLET, line_w=1.5)
|
|
173
|
-
txt(s, 1.1, 3.22, 11, 0.35, [[("terminal", 11, MUTED, False)]], font=MONO)
|
|
174
|
-
txt(s, 1.1, 3.62, 11, 0.7,
|
|
175
|
-
[[("$ ", 24, CYAN, True), ("npx claude-code-arcane install ", 24, WHITE, True),
|
|
176
|
-
("backend-ts", 24, GREEN, True), ("+agile", 24, AMBER, True), ("+testing", 24, AMBER, True)]], font=MONO)
|
|
177
|
-
cols = [("backend-ts", "base", GREEN), ("+agile", "addon", AMBER), ("+testing", "addon", AMBER)]
|
|
178
|
-
cx = 0.78
|
|
179
|
-
for name, kind, col in cols:
|
|
180
|
-
rect(s, cx, 4.75, 3.0, 1.05, PANEL, radius=True)
|
|
181
|
-
txt(s, cx, 4.9, 3.0, 0.5, [[(name, 17, col, True)]], align=PP_ALIGN.CENTER)
|
|
182
|
-
txt(s, cx, 5.4, 3.0, 0.35, [[(kind.upper(), 11, MUTED, True)]], align=PP_ALIGN.CENTER)
|
|
183
|
-
cx += 3.25
|
|
184
|
-
txt(s, 0.78, 6.05, 11.7, 0.5, [[("base + addon + addon -> solo lo que ESE proyecto necesita.", 15, WHITE, True)]])
|
|
185
|
-
|
|
186
|
-
# ================= SLIDE 5 — Como funciona =================
|
|
187
|
-
s = slide()
|
|
188
|
-
chrome(s, 5, "ARQUITECTURA", "Como funciona la instalacion")
|
|
189
|
-
steps = [
|
|
190
|
-
("1", "Resuelve el contenido", "GitHub -> cache local -> bundled (funciona offline)"),
|
|
191
|
-
("2", "Carga core.yaml siempre", "21 skills base + 15 hooks + permisos de seguridad"),
|
|
192
|
-
("3", "Mergea los profiles", "Combina los profiles pedidos con el separador +"),
|
|
193
|
-
("4", "Deduplica", "Un skill repetido en varios profiles se copia una sola vez"),
|
|
194
|
-
("5", "Genera .claude/", "settings.json + manifest + skills, agents, rules, hooks, docs"),
|
|
195
|
-
]
|
|
196
|
-
y = 1.95
|
|
197
|
-
for num, h, d in steps:
|
|
198
|
-
rect(s, 0.78, y, 11.7, 0.82, PANEL, radius=True)
|
|
199
|
-
c = s.shapes.add_shape(MSO_SHAPE.OVAL, Inches(0.98), Inches(y + 0.16), Inches(0.5), Inches(0.5))
|
|
200
|
-
c.fill.solid(); c.fill.fore_color.rgb = VIOLET; c.line.fill.background(); c.shadow.inherit = False
|
|
201
|
-
ctf = c.text_frame; ctf.vertical_anchor = MSO_ANCHOR.MIDDLE
|
|
202
|
-
cp = ctf.paragraphs[0]; cp.alignment = PP_ALIGN.CENTER
|
|
203
|
-
cr = cp.add_run(); cr.text = num; cr.font.size = Pt(20); cr.font.bold = True
|
|
204
|
-
cr.font.color.rgb = WHITE; cr.font.name = FONT
|
|
205
|
-
txt(s, 1.75, y + 0.04, 4.0, 0.74, [[(h, 15.5, CYAN, True)]], anchor=MSO_ANCHOR.MIDDLE)
|
|
206
|
-
txt(s, 5.9, y + 0.04, 6.4, 0.74, [[(d, 12.5, LIGHT, False)]], anchor=MSO_ANCHOR.MIDDLE)
|
|
207
|
-
y += 0.93
|
|
208
|
-
txt(s, 0.78, 6.6, 11.7, 0.4,
|
|
209
|
-
[[("Resultado: el .claude/ del proyecto contiene exactamente lo necesario — nada mas.", 13, MUTED, True)]])
|
|
210
|
-
|
|
211
|
-
# ================= SLIDE 6 — 4 piezas =================
|
|
212
|
-
s = slide()
|
|
213
|
-
chrome(s, 6, "SEPARACION DE RESPONSABILIDADES", "Cuatro piezas, cuatro responsabilidades")
|
|
214
|
-
cards = [
|
|
215
|
-
("Skills", "Acciones que Claude ejecuta", "/commit · /code-review · /sprint-plan", CYAN),
|
|
216
|
-
("Agents", "Personas que Claude adopta", "backend-architect · game-designer", VIOLET),
|
|
217
|
-
("Hooks", "Automatizacion invisible (eventos)", "valida commits · escanea secrets", GREEN),
|
|
218
|
-
("Rules", "Estandares que Claude obedece", "\"Clean architecture en backend\"", AMBER),
|
|
219
|
-
]
|
|
220
|
-
positions = [(0.78, 1.95), (6.93, 1.95), (0.78, 4.15), (6.93, 4.15)]
|
|
221
|
-
cw, ch = 5.6, 2.0
|
|
222
|
-
for (name, what, ex, col), (x, y) in zip(cards, positions):
|
|
223
|
-
rect(s, x, y, cw, ch, PANEL, radius=True)
|
|
224
|
-
rect(s, x, y, cw, 0.12, col)
|
|
225
|
-
txt(s, x + 0.3, y + 0.22, cw - 0.6, 0.5, [[(name, 23, col, True)]])
|
|
226
|
-
txt(s, x + 0.3, y + 0.82, cw - 0.6, 0.5, [[(what, 14, LIGHT, False)]])
|
|
227
|
-
txt(s, x + 0.3, y + 1.35, cw - 0.6, 0.5, [[(ex, 12, MUTED, True)]])
|
|
228
|
-
txt(s, 0.78, 6.45, 11.7, 0.5,
|
|
229
|
-
[[("Todo en Markdown + YAML: legible, diffeable en git, editable por cualquiera.", 14, WHITE, True)]])
|
|
230
|
-
|
|
231
|
-
# ================= SLIDE 7 — Anatomia de una skill =================
|
|
232
|
-
s = slide()
|
|
233
|
-
chrome(s, 7, "DEEP DIVE", "Anatomia de una skill")
|
|
234
|
-
# bloque de codigo
|
|
235
|
-
rect(s, 0.78, 1.95, 6.7, 4.55, CODEBG, radius=True, line=VIOLET, line_w=1.2)
|
|
236
|
-
txt(s, 1.0, 2.1, 6.3, 0.35, [[("skills/commit/SKILL.md", 11, MUTED, False)]], font=MONO)
|
|
237
|
-
code = [
|
|
238
|
-
[("---", 12.5, MUTED, False)],
|
|
239
|
-
[("name:", 12.5, PINK, True), (" commit", 12.5, LIGHT, False)],
|
|
240
|
-
[("description:", 12.5, PINK, True), (" \"Crea un commit", 12.5, GREEN, False)],
|
|
241
|
-
[(" siguiendo conventional commits...\"", 12.5, GREEN, False)],
|
|
242
|
-
[("category:", 12.5, PINK, True), (" workflow", 12.5, LIGHT, False)],
|
|
243
|
-
[("user-invocable:", 12.5, PINK, True), (" true", 12.5, AMBER, False)],
|
|
244
|
-
[("allowed-tools:", 12.5, PINK, True), (" Read, Bash", 12.5, LIGHT, False)],
|
|
245
|
-
[("model:", 12.5, PINK, True), (" haiku", 12.5, LIGHT, False), (" # opcional", 11, MUTED, False)],
|
|
246
|
-
[("---", 12.5, MUTED, False)],
|
|
247
|
-
[("", 6, MUTED, False)],
|
|
248
|
-
[("Review staged & unstaged changes", 12.5, CYAN, False)],
|
|
249
|
-
[("with git diff, suggest type/scope,", 12.5, CYAN, False)],
|
|
250
|
-
[("write a concise message...", 12.5, CYAN, False)],
|
|
251
|
-
]
|
|
252
|
-
txt(s, 1.0, 2.5, 6.3, 3.9, code, space_after=2, font=MONO)
|
|
253
|
-
# explicacion lado derecho
|
|
254
|
-
rect(s, 7.75, 1.95, 4.72, 4.55, PANEL, radius=True)
|
|
255
|
-
txt(s, 8.0, 2.15, 4.3, 0.4, [[("Dos partes:", 16, WHITE, True)]])
|
|
256
|
-
fields = [
|
|
257
|
-
("Frontmatter (YAML)", "Metadatos: nombre, tools permitidas, si es invocable, modelo a usar, agente asociado."),
|
|
258
|
-
("Cuerpo (Markdown)", "Las instrucciones en lenguaje natural que Claude sigue al invocar la skill."),
|
|
259
|
-
]
|
|
260
|
-
y = 2.7
|
|
261
|
-
for h, d in fields:
|
|
262
|
-
txt(s, 8.0, y, 4.3, 0.4, [[(h, 13.5, CYAN, True)]])
|
|
263
|
-
txt(s, 8.0, y + 0.38, 4.3, 0.9, [[(d, 12, LIGHT, False)]], line_spacing=1.05)
|
|
264
|
-
y += 1.5
|
|
265
|
-
txt(s, 8.0, 5.75, 4.3, 0.7,
|
|
266
|
-
[[("1 skill = 1 carpeta con un SKILL.md. Sin build, sin compilar.", 12.5, MUTED, True)]], line_spacing=1.05)
|
|
267
|
-
|
|
268
|
-
# ================= SLIDE 8 — Profiles =================
|
|
269
|
-
s = slide()
|
|
270
|
-
chrome(s, 8, "EL SISTEMA LEGO", "Profiles: combinar por stack")
|
|
271
|
-
txt(s, 0.78, 1.85, 11.7, 0.5,
|
|
272
|
-
[[("Cada profile es un YAML que agrupa skills, agentes, reglas y permisos. Se combinan con ", 13.5, LIGHT, False),
|
|
273
|
-
("+", 14, AMBER, True), (".", 13.5, LIGHT, False)]])
|
|
274
|
-
# bases
|
|
275
|
-
rect(s, 0.78, 2.5, 5.7, 3.0, PANEL, radius=True)
|
|
276
|
-
txt(s, 1.0, 2.65, 5.3, 0.4, [[("BASE (elegis uno)", 13, GREEN, True)]])
|
|
277
|
-
bases = [("unity-dev", "25"), ("backend-ts", "33"), ("backend-go", "19"),
|
|
278
|
-
("frontend", "14"), ("mobile", "12"), ("flutter / ios / android", "8")]
|
|
279
|
-
y = 3.15
|
|
280
|
-
for name, n in bases:
|
|
281
|
-
txt(s, 1.0, y, 4.2, 0.35, [[(name, 13, LIGHT, False)]])
|
|
282
|
-
txt(s, 5.3, y, 0.9, 0.35, [[(n, 13, CYAN, True)]], align=PP_ALIGN.RIGHT)
|
|
283
|
-
y += 0.37
|
|
284
|
-
# addons
|
|
285
|
-
rect(s, 6.63, 2.5, 5.85, 3.0, PANEL, radius=True)
|
|
286
|
-
txt(s, 6.85, 2.65, 5.4, 0.4, [[("ADDONS (combinas con +)", 13, AMBER, True)]])
|
|
287
|
-
addons = [("+agile", "10"), ("+testing", "11"), ("+infra", "17"),
|
|
288
|
-
("+security", "5"), ("+marketing", "44"), ("+clevel / +regulatory", "28 / 13")]
|
|
289
|
-
y = 3.15
|
|
290
|
-
for name, n in addons:
|
|
291
|
-
txt(s, 6.85, y, 4.4, 0.35, [[(name, 13, LIGHT, False)]])
|
|
292
|
-
txt(s, 11.3, y, 0.9, 0.35, [[(n, 13, CYAN, True)]], align=PP_ALIGN.RIGHT)
|
|
293
|
-
y += 0.37
|
|
294
|
-
rect(s, 0.78, 5.7, 11.7, 0.85, PANEL2, radius=True)
|
|
295
|
-
txt(s, 1.0, 5.78, 11.3, 0.7,
|
|
296
|
-
[[("+ core (siempre): 21 skills universales + 15 hooks + seguridad. ", 13, WHITE, True),
|
|
297
|
-
("Profiles combinados nunca duplican un skill.", 13, CYAN, True)]],
|
|
298
|
-
anchor=MSO_ANCHOR.MIDDLE, line_spacing=1.05)
|
|
299
|
-
|
|
300
|
-
# ================= SLIDE 9 — Mecanismos avanzados =================
|
|
301
|
-
s = slide()
|
|
302
|
-
chrome(s, 9, "PRODUCTION-GRADE", "Mecanismos que lo elevan")
|
|
303
|
-
feats = [
|
|
304
|
-
("Distribucion hibrida", "Resuelve el contenido en cadena: GitHub -> cache local -> bundled en npm. Funciona incluso sin conexion.", CYAN),
|
|
305
|
-
("Smart update (3-way merge)", "Compara base / tu version / upstream. Actualiza lo no tocado, preserva tus cambios, avisa conflictos.", VIOLET),
|
|
306
|
-
("Worktree-aware", "En git worktrees comparte hooks/ y docs/ (symlink), pero copia skills/ por rama (pueden divergir).", GREEN),
|
|
307
|
-
("Auto-release", "semantic-release lee los conventional commits: fix -> patch, feat -> minor. Publica a npm solo.", AMBER),
|
|
308
|
-
]
|
|
309
|
-
positions = [(0.78, 1.95), (6.93, 1.95), (0.78, 4.3), (6.93, 4.3)]
|
|
310
|
-
cw, ch = 5.6, 2.15
|
|
311
|
-
for (h, d, col), (x, y) in zip(feats, positions):
|
|
312
|
-
rect(s, x, y, cw, ch, PANEL, radius=True)
|
|
313
|
-
rect(s, x, y, 0.1, ch, col)
|
|
314
|
-
txt(s, x + 0.32, y + 0.22, cw - 0.6, 0.5, [[(h, 17, col, True)]])
|
|
315
|
-
txt(s, x + 0.32, y + 0.78, cw - 0.62, 1.2, [[(d, 12.5, LIGHT, False)]], line_spacing=1.1)
|
|
316
|
-
|
|
317
|
-
# ================= SLIDE 10 — Calidad / testing =================
|
|
318
|
-
s = slide()
|
|
319
|
-
chrome(s, 10, "CONFIABILIDAD", "Las skills se testean")
|
|
320
|
-
txt(s, 0.78, 1.9, 11.7, 0.5,
|
|
321
|
-
[[("322 prompts hay que mantenerlos con calidad. Arcane trae un framework de QA self-contained: ", 13.5, LIGHT, False),
|
|
322
|
-
("skills-selftest/", 13.5, CYAN, True)]])
|
|
323
|
-
cards = [
|
|
324
|
-
("/skill-test static", "Chequeo estructural: frontmatter valido, paths, tools declaradas.", GREEN),
|
|
325
|
-
("/skill-test spec", "Evaluacion de comportamiento contra casos de prueba esperados.", CYAN),
|
|
326
|
-
("/skill-test audit", "Reporte de cobertura: que skills tienen specs y cuales faltan.", VIOLET),
|
|
327
|
-
("/skill-improve", "Loop test -> diagnostica -> arregla -> re-testea -> mantiene o revierte.", AMBER),
|
|
328
|
-
]
|
|
329
|
-
y = 2.55
|
|
330
|
-
for h, d, col in cards:
|
|
331
|
-
rect(s, 0.78, y, 11.7, 0.85, PANEL, radius=True)
|
|
332
|
-
rect(s, 0.78, y, 0.1, 0.85, col)
|
|
333
|
-
txt(s, 1.05, y + 0.08, 3.6, 0.7, [[(h, 15, col, True)]], anchor=MSO_ANCHOR.MIDDLE, font=MONO)
|
|
334
|
-
txt(s, 4.9, y + 0.08, 7.4, 0.7, [[(d, 12.5, LIGHT, False)]], anchor=MSO_ANCHOR.MIDDLE)
|
|
335
|
-
y += 0.98
|
|
336
|
-
txt(s, 0.78, 6.5, 11.7, 0.4,
|
|
337
|
-
[[("catalog.yaml = registro maestro · quality-rubric.md = criterios pass/fail por categoria.", 12.5, MUTED, True)]])
|
|
338
|
-
|
|
339
|
-
# ================= SLIDE 11 — Por que gana =================
|
|
340
|
-
s = slide()
|
|
341
|
-
chrome(s, 11, "DIFERENCIADORES", "Por que Arcane gana")
|
|
342
|
-
rect(s, 0.78, 1.95, 5.7, 0.52, PANEL2, radius=True)
|
|
343
|
-
rect(s, 6.63, 1.95, 5.85, 0.52, PANEL2, radius=True)
|
|
344
|
-
txt(s, 1.0, 1.98, 5.3, 0.45, [[("ALTERNATIVA", 12.5, MUTED, True)]], anchor=MSO_ANCHOR.MIDDLE)
|
|
345
|
-
txt(s, 6.85, 1.98, 5.4, 0.45, [[("COMO GANA ARCANE", 12.5, CYAN, True)]], anchor=MSO_ANCHOR.MIDDLE)
|
|
346
|
-
rows = [
|
|
347
|
-
("Config a mano", "Un comando, versionado, reproducible"),
|
|
348
|
-
("Mega-repo monolitico", "Selectivo por profile + dedup (menos tokens)"),
|
|
349
|
-
("Copiar config entre proyectos", "Smart update con three-way merge"),
|
|
350
|
-
("Claude \"vanilla\"", "Hooks + rules + 86 agentes especializados"),
|
|
351
|
-
]
|
|
352
|
-
y = 2.58
|
|
353
|
-
for a, b in rows:
|
|
354
|
-
rect(s, 0.78, y, 5.7, 0.68, PANEL, radius=True)
|
|
355
|
-
rect(s, 6.63, y, 5.85, 0.68, PANEL, radius=True)
|
|
356
|
-
txt(s, 1.0, y + 0.04, 5.3, 0.6, [[(a, 13.5, LIGHT, False)]], anchor=MSO_ANCHOR.MIDDLE)
|
|
357
|
-
txt(s, 6.85, y + 0.04, 5.4, 0.6, [[(b, 13, WHITE, True)]], anchor=MSO_ANCHOR.MIDDLE)
|
|
358
|
-
y += 0.78
|
|
359
|
-
rect(s, 0.78, y + 0.05, 11.7, 0.68, VIOLET, radius=True)
|
|
360
|
-
txt(s, 0.78, y + 0.08, 11.7, 0.6,
|
|
361
|
-
[[("Configuracion de IA tratada como software: versionada, modular, testeable y distribuida.", 13.5, WHITE, True)]],
|
|
362
|
-
align=PP_ALIGN.CENTER, anchor=MSO_ANCHOR.MIDDLE)
|
|
363
|
-
|
|
364
|
-
# ================= SLIDE 12 — Trade-offs + cierre =================
|
|
365
|
-
s = slide()
|
|
366
|
-
chrome(s, 12, "BALANCE Y CIERRE", "Trade-offs honestos")
|
|
367
|
-
# pros
|
|
368
|
-
rect(s, 0.78, 1.95, 5.7, 3.05, PANEL, radius=True)
|
|
369
|
-
rect(s, 0.78, 1.95, 5.7, 0.55, RGBColor(0x14, 0x3D, 0x2E), radius=True)
|
|
370
|
-
txt(s, 1.02, 1.98, 5.3, 0.5, [[("FORTALEZAS", 14, GREEN, True)]], anchor=MSO_ANCHOR.MIDDLE)
|
|
371
|
-
pros = ["Eficiencia de tokens", "Un comando, cero friccion",
|
|
372
|
-
"Reproducible (manifest)", "Estandarizacion de equipo",
|
|
373
|
-
"Auto-update sin pisar cambios", "Testeable (skills-selftest)"]
|
|
374
|
-
y = 2.62
|
|
375
|
-
for p in pros:
|
|
376
|
-
txt(s, 1.02, y, 5.3, 0.4, [[("+ ", 13, GREEN, True), (p, 12.5, LIGHT, False)]])
|
|
377
|
-
y += 0.39
|
|
378
|
-
# contras
|
|
379
|
-
rect(s, 6.63, 1.95, 5.85, 3.05, PANEL, radius=True)
|
|
380
|
-
rect(s, 6.63, 1.95, 5.85, 0.55, RGBColor(0x4A, 0x39, 0x12), radius=True)
|
|
381
|
-
txt(s, 6.87, 1.98, 5.4, 0.5, [[("COSTOS", 14, AMBER, True)]], anchor=MSO_ANCHOR.MIDDLE)
|
|
382
|
-
cons = ["Mantener 322 skills con calidad", "Skills = prompts -> no deterministas",
|
|
383
|
-
"Depende de la API de Claude Code", "Curva: saber que profiles combinar"]
|
|
384
|
-
y = 2.62
|
|
385
|
-
for c in cons:
|
|
386
|
-
txt(s, 6.87, y, 5.5, 0.5, [[("! ", 13, AMBER, True), (c, 12.5, LIGHT, False)]])
|
|
387
|
-
y += 0.52
|
|
388
|
-
# CTA
|
|
389
|
-
rect(s, 0.78, 5.25, 11.7, 1.45, VIOLET, radius=True)
|
|
390
|
-
txt(s, 0.78, 5.4, 11.7, 0.5,
|
|
391
|
-
[[("Configuracion de IA, modular y versionada — un comando para empezar.", 17, WHITE, True)]],
|
|
392
|
-
align=PP_ALIGN.CENTER)
|
|
393
|
-
txt(s, 0.78, 5.95, 11.7, 0.5, [[("npx claude-code-arcane install backend-ts+agile", 21, WHITE, True)]],
|
|
394
|
-
align=PP_ALIGN.CENTER, font=MONO)
|
|
395
|
-
|
|
396
|
-
out = os.path.join(os.path.dirname(os.path.abspath(__file__)), "arcane-overview-12.pptx")
|
|
397
|
-
prs.save(out)
|
|
398
|
-
print("OK ->", out)
|
|
399
|
-
print("Slides:", len(prs.slides._sldIdLst))
|
|
@@ -1,163 +0,0 @@
|
|
|
1
|
-
# Migración a Trusted Publishing (OIDC) — guía futura
|
|
2
|
-
|
|
3
|
-
> **Estado actual (jun 2026):** el paquete se publica con un **token `NPM_TOKEN`** (Classic Automation, saltea 2FA) cargado como secret en GitHub Actions. Funciona y es estable. Este documento describe cómo migrar a **Trusted Publishing (OIDC)** cuando convenga.
|
|
4
|
-
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
## 1. Qué es y por qué migrar
|
|
8
|
-
|
|
9
|
-
**Trusted Publishing** usa **OpenID Connect (OIDC)**: GitHub Actions se autentica contra npm con una **identidad efímera por run** (un id-token de corta vida), en vez de un token de larga duración guardado como secret.
|
|
10
|
-
|
|
11
|
-
| | Token (actual) | Trusted Publishing (OIDC) |
|
|
12
|
-
|---|---|---|
|
|
13
|
-
| Secret de larga vida | Sí (`NPM_TOKEN`) | **No** |
|
|
14
|
-
| Expira / hay que rotar | Sí (vence **2026-09-01**) | **No** |
|
|
15
|
-
| Riesgo si se filtra | Alto (válido hasta expirar) | Bajo (token efímero por run) |
|
|
16
|
-
| Provenance / attestations | Manual | **Automático** |
|
|
17
|
-
| Mantenimiento | Rotar token periódicamente | Cero |
|
|
18
|
-
|
|
19
|
-
**Motivo principal para migrar:** eliminar la rotación del token y el riesgo de que un release falle sin aviso cuando el token expire.
|
|
20
|
-
|
|
21
|
-
---
|
|
22
|
-
|
|
23
|
-
## 2. ⚠️ Por qué HOY (jun 2026) no se hizo
|
|
24
|
-
|
|
25
|
-
El setup actual está varias piezas por debajo de lo que OIDC requiere. **Verificar y resolver estos puntos ANTES de migrar:**
|
|
26
|
-
|
|
27
|
-
| Requisito OIDC | Estado al jun-2026 | Acción |
|
|
28
|
-
|---|---|---|
|
|
29
|
-
| `@semantic-release/npm` **≥ 13.1.0** (soporte OIDC, oct-2025) | **12.0.2** (bundleado por `semantic-release@24.2.9`) — **no soporta OIDC** | Forzar upgrade del plugin |
|
|
30
|
-
| **npm ≥ 11.5.1** en el CI | Node 22 trae **npm 10.x** | Agregar step que actualice npm |
|
|
31
|
-
| `permissions: id-token: write` en el job | No está | Editar `release.yml` |
|
|
32
|
-
| Trusted publisher configurado en npm | No está | Configurar en la web de npm |
|
|
33
|
-
| Paquete ya existe en npm | ✅ (`claude-code-arcane@1.0.0`) | OK — OIDC **no** permite el *primer* publish, pero ya está hecho |
|
|
34
|
-
|
|
35
|
-
**Bugs conocidos a revisar antes de migrar** (pueden estar resueltos en versiones nuevas):
|
|
36
|
-
- [semantic-release/npm#1069](https://github.com/semantic-release/npm/issues/1069) — `ENONPMTOKEN` aún pide token en `verifyConditions` (reportado ene-2026).
|
|
37
|
-
- [semantic-release/npm#1023](https://github.com/semantic-release/npm/issues/1023) — falla el primer publish desde maintenance branch.
|
|
38
|
-
|
|
39
|
-
> Antes de empezar, chequear que estos issues estén cerrados o tengan workaround claro.
|
|
40
|
-
|
|
41
|
-
---
|
|
42
|
-
|
|
43
|
-
## 3. Setup paso a paso
|
|
44
|
-
|
|
45
|
-
### Paso 1 — Actualizar dependencias
|
|
46
|
-
|
|
47
|
-
Asegurar `@semantic-release/npm` ≥ 13.1.0. Como `semantic-release@24.x` puede seguir bundleando una versión vieja, declararlo como dependencia directa:
|
|
48
|
-
|
|
49
|
-
```bash
|
|
50
|
-
npm install -D @semantic-release/npm@latest semantic-release@latest
|
|
51
|
-
```
|
|
52
|
-
|
|
53
|
-
Verificar que quedó ≥ 13.1.0:
|
|
54
|
-
|
|
55
|
-
```bash
|
|
56
|
-
npm ls @semantic-release/npm
|
|
57
|
-
```
|
|
58
|
-
|
|
59
|
-
### Paso 2 — Editar `.github/workflows/release.yml`
|
|
60
|
-
|
|
61
|
-
Dos cambios: **(a)** agregar el permiso `id-token: write`, **(b)** actualizar npm a ≥ 11.5.1 antes del release.
|
|
62
|
-
|
|
63
|
-
```yaml
|
|
64
|
-
name: Release
|
|
65
|
-
|
|
66
|
-
on:
|
|
67
|
-
push:
|
|
68
|
-
branches: [main]
|
|
69
|
-
|
|
70
|
-
permissions:
|
|
71
|
-
contents: write
|
|
72
|
-
issues: write
|
|
73
|
-
pull-requests: write
|
|
74
|
-
id-token: write # ← NUEVO: habilita OIDC
|
|
75
|
-
|
|
76
|
-
jobs:
|
|
77
|
-
release:
|
|
78
|
-
runs-on: ubuntu-latest
|
|
79
|
-
steps:
|
|
80
|
-
- uses: actions/checkout@v4
|
|
81
|
-
with:
|
|
82
|
-
fetch-depth: 0
|
|
83
|
-
persist-credentials: false
|
|
84
|
-
- uses: actions/setup-node@v4
|
|
85
|
-
with:
|
|
86
|
-
node-version: 22
|
|
87
|
-
cache: 'npm'
|
|
88
|
-
- run: npm install -g npm@latest # ← NUEVO: npm >= 11.5.1 para OIDC
|
|
89
|
-
- run: npm ci
|
|
90
|
-
- run: npm run build
|
|
91
|
-
- run: npm test
|
|
92
|
-
- name: Release
|
|
93
|
-
env:
|
|
94
|
-
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
95
|
-
# NPM_TOKEN ya NO es necesario una vez que OIDC funcione.
|
|
96
|
-
# Dejarlo como fallback durante la transición; quitarlo al confirmar.
|
|
97
|
-
run: npx semantic-release
|
|
98
|
-
```
|
|
99
|
-
|
|
100
|
-
> **Importante:** durante la transición, **no borrar** el secret `NPM_TOKEN` todavía. Token y OIDC pueden coexistir; el token queda como red de seguridad.
|
|
101
|
-
|
|
102
|
-
### Paso 3 — Configurar el Trusted Publisher en npm
|
|
103
|
-
|
|
104
|
-
1. Ir a [npmjs.com](https://www.npmjs.com) → paquete **claude-code-arcane** → **Settings**.
|
|
105
|
-
2. Sección **Trusted Publishers** (o *Publishing access*).
|
|
106
|
-
3. **Add trusted publisher** → GitHub Actions:
|
|
107
|
-
- **Organization / user:** `SebastianLuser`
|
|
108
|
-
- **Repository:** `claude-code-arcane`
|
|
109
|
-
- **Workflow filename:** `release.yml`
|
|
110
|
-
- **Environment:** (dejar vacío salvo que el job use un `environment:`)
|
|
111
|
-
4. Guardar.
|
|
112
|
-
|
|
113
|
-
### Paso 4 — Release de prueba (additive, sin riesgo)
|
|
114
|
-
|
|
115
|
-
Con el token todavía presente como fallback:
|
|
116
|
-
|
|
117
|
-
```bash
|
|
118
|
-
git commit --allow-empty -m "fix: test trusted publishing via OIDC"
|
|
119
|
-
git push origin main
|
|
120
|
-
```
|
|
121
|
-
|
|
122
|
-
Revisar el log del step **Release** en Actions:
|
|
123
|
-
- ✅ Si publica vía OIDC (suele loguear `provenance` / autenticación OIDC) → migración OK.
|
|
124
|
-
- ❌ Si falla pidiendo token (`ENONPMTOKEN`) → el soporte aún tiene asperezas; **revertir** y seguir con token.
|
|
125
|
-
|
|
126
|
-
### Paso 5 — Quitar el token (solo si el Paso 4 fue verde)
|
|
127
|
-
|
|
128
|
-
1. En GitHub → Settings → Secrets → borrar `NPM_TOKEN`.
|
|
129
|
-
2. En npm → Access Tokens → borrar el token de automatización.
|
|
130
|
-
3. Commit confirmando que ya no se usa el token.
|
|
131
|
-
|
|
132
|
-
---
|
|
133
|
-
|
|
134
|
-
## 4. Rollback
|
|
135
|
-
|
|
136
|
-
Si algo falla después de migrar:
|
|
137
|
-
|
|
138
|
-
1. Recargar el secret `NPM_TOKEN` (regenerar token Classic Automation en npm).
|
|
139
|
-
2. Revertir los cambios del `release.yml` (`git revert` del commit de migración).
|
|
140
|
-
3. El release vuelve a funcionar con token como antes.
|
|
141
|
-
|
|
142
|
-
---
|
|
143
|
-
|
|
144
|
-
## 5. Checklist rápido
|
|
145
|
-
|
|
146
|
-
- [ ] `@semantic-release/npm` ≥ 13.1.0 instalado y verificado
|
|
147
|
-
- [ ] Issues #1069 / #1023 cerrados o con workaround
|
|
148
|
-
- [ ] `id-token: write` agregado al workflow
|
|
149
|
-
- [ ] Step `npm install -g npm@latest` agregado
|
|
150
|
-
- [ ] Trusted publisher configurado en npm (repo + `release.yml`)
|
|
151
|
-
- [ ] Release de prueba publicó vía OIDC (con token aún presente)
|
|
152
|
-
- [ ] Token `NPM_TOKEN` eliminado de GitHub y npm
|
|
153
|
-
- [ ] Documentado el cambio en CHANGELOG / README
|
|
154
|
-
|
|
155
|
-
---
|
|
156
|
-
|
|
157
|
-
## Referencias
|
|
158
|
-
|
|
159
|
-
- [npm trusted publishing GA — GitHub Changelog](https://github.blog/changelog/2025-07-31-npm-trusted-publishing-with-oidc-is-generally-available/)
|
|
160
|
-
- [Trusted publishing for npm packages — npm Docs](https://docs.npmjs.com/trusted-publishers/)
|
|
161
|
-
- [@semantic-release/npm releases (v13.1.0 = soporte OIDC)](https://github.com/semantic-release/npm/releases)
|
|
162
|
-
- [Issue #1069 — ENONPMTOKEN con OIDC](https://github.com/semantic-release/npm/issues/1069)
|
|
163
|
-
- [Issue #1023 — primer publish desde maintenance branch](https://github.com/semantic-release/npm/issues/1023)
|