claude-code-arcane 2.2.0 → 2.4.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 +37 -0
- package/README.md +104 -55
- package/agents/career/career-strategist.md +88 -0
- package/agents/career/cv-reviewer.md +81 -0
- package/agents/career/hiring-manager.md +68 -0
- package/agents/career/mock-interviewer.md +76 -0
- package/agents/freelance/client-screener.md +84 -0
- package/agents/freelance/discovery-call.md +65 -0
- package/agents/freelance/pipeline-strategist.md +99 -0
- package/agents/freelance/proposal-reviewer.md +82 -0
- package/agents/game/ue-blueprint-specialist.md +125 -0
- package/agents/game/ue-gas-specialist.md +133 -0
- package/agents/game/ue-umg-specialist.md +131 -0
- package/dist/cli.js +57 -13
- package/docs/RELEASE-SETUP.md +1 -1
- package/docs/SKILLS-CATALOG.md +67 -4
- package/docs/USER-GUIDE.md +77 -72
- package/docs/agent-hierarchy.md +21 -1
- package/docs/presentations/build_arcane_deck.py +2 -2
- package/docs/presentations/build_arcane_deck_12.py +2 -2
- package/hooks/detect-unreal.sh +90 -0
- package/package.json +2 -2
- package/profiles/freelance.yaml +43 -0
- package/profiles/job-hunt.yaml +5 -2
- package/profiles/unreal-dev.yaml +97 -0
- package/rules/drafter-reviewer.md +16 -3
- package/rules/freelance-guardrails.md +53 -0
- package/rules/gamedev/unreal-code.md +125 -0
- package/skills/career-registry/SKILL.md +95 -0
- package/skills/career-registry/scripts/career_registry.py +488 -0
- package/skills/client-screen/SKILL.md +83 -0
- package/skills/client-screen/references/red-flags.md +95 -0
- package/skills/cover-letter/SKILL.md +4 -3
- package/skills/cv-tailor/SKILL.md +11 -2
- package/skills/freelance-deliver/SKILL.md +90 -0
- package/skills/freelance-hunt/SKILL.md +126 -0
- package/skills/freelance-hunt/references/templates/Connects.md +39 -0
- package/skills/freelance-hunt/references/templates/Contrato.md +60 -0
- package/skills/freelance-hunt/references/templates/Propuesta.md +66 -0
- package/skills/freelance-kickoff/SKILL.md +94 -0
- package/skills/freelance-pipeline/SKILL.md +109 -0
- package/skills/freelance-pipeline/scripts/import_history.py +425 -0
- package/skills/freelance-profile/SKILL.md +93 -0
- package/skills/freelance-proposal/SKILL.md +112 -0
- package/skills/freelance-scan/SKILL.md +196 -0
- package/skills/freelance-scan/references/dedup.md +35 -0
- package/skills/freelance-scan/references/platforms.md +167 -0
- package/skills/freelance-scan/scripts/freelance_search.py +1077 -0
- package/skills/install-mcp/SKILL.md +135 -46
- package/skills/install-mcp/references/unreal-operations.md +55 -0
- package/skills/interview-prep/SKILL.md +11 -3
- package/skills/job-aplicar/SKILL.md +5 -1
- package/skills/job-hunt/SKILL.md +17 -0
- package/skills/job-outcome/SKILL.md +15 -1
- package/skills/job-upskill/SKILL.md +10 -2
- package/skills/ue-actor-component-architecture/SKILL.md +509 -0
- package/skills/ue-actor-component-architecture/references/actor-lifecycle.md +301 -0
- package/skills/ue-actor-component-architecture/references/component-types.md +592 -0
- package/skills/ue-ai-navigation/SKILL.md +526 -0
- package/skills/ue-ai-navigation/references/behavior-tree-patterns.md +392 -0
- package/skills/ue-ai-navigation/references/behavior-tree-workflow.md +107 -0
- package/skills/ue-ai-navigation/references/custom-bttask.md +104 -0
- package/skills/ue-ai-navigation/references/eqs-reference.md +423 -0
- package/skills/ue-animation-system/SKILL.md +521 -0
- package/skills/ue-animation-system/references/anim-notify-reference.md +486 -0
- package/skills/ue-animation-system/references/locomotion-setup.md +550 -0
- package/skills/ue-async-threading/SKILL.md +433 -0
- package/skills/ue-async-threading/references/thread-safety-guide.md +213 -0
- package/skills/ue-async-threading/references/threading-patterns.md +345 -0
- package/skills/ue-audio-system/SKILL.md +527 -0
- package/skills/ue-audio-system/references/audio-setup-patterns.md +700 -0
- package/skills/ue-blueprints/SKILL.md +134 -0
- package/skills/ue-blueprints/references/communication.md +82 -0
- package/skills/ue-character-movement/SKILL.md +475 -0
- package/skills/ue-character-movement/references/cmc-extension-patterns.md +335 -0
- package/skills/ue-character-movement/references/movement-pipeline.md +189 -0
- package/skills/ue-cpp-foundations/SKILL.md +533 -0
- package/skills/ue-cpp-foundations/references/components-and-gc.md +107 -0
- package/skills/ue-cpp-foundations/references/container-patterns.md +544 -0
- package/skills/ue-cpp-foundations/references/delegate-patterns.md +497 -0
- package/skills/ue-cpp-foundations/references/gameplay-classes-cpp.md +136 -0
- package/skills/ue-cpp-foundations/references/property-specifiers.md +306 -0
- package/skills/ue-data-assets-tables/SKILL.md +527 -0
- package/skills/ue-data-assets-tables/references/asset-loading-patterns.md +306 -0
- package/skills/ue-data-assets-tables/references/data-driven-design.md +378 -0
- package/skills/ue-editor-tools/SKILL.md +523 -0
- package/skills/ue-editor-tools/references/detail-customization-patterns.md +395 -0
- package/skills/ue-editor-tools/references/editor-module-setup.md +480 -0
- package/skills/ue-game-features/SKILL.md +477 -0
- package/skills/ue-game-features/references/experience-system.md +222 -0
- package/skills/ue-game-features/references/game-feature-patterns.md +308 -0
- package/skills/ue-gameplay-abilities/SKILL.md +518 -0
- package/skills/ue-gameplay-abilities/references/ability-task-reference.md +391 -0
- package/skills/ue-gameplay-abilities/references/gameplay-effect-reference.md +397 -0
- package/skills/ue-gameplay-abilities/references/gas-setup-patterns.md +369 -0
- package/skills/ue-gameplay-framework/SKILL.md +466 -0
- package/skills/ue-gameplay-framework/references/framework-class-map.md +243 -0
- package/skills/ue-input-system/SKILL.md +394 -0
- package/skills/ue-input-system/references/cpp-setup.md +131 -0
- package/skills/ue-input-system/references/enhanced-input-workflow.md +117 -0
- package/skills/ue-input-system/references/input-action-reference.md +731 -0
- package/skills/ue-mass-entity/SKILL.md +476 -0
- package/skills/ue-mass-entity/references/mass-entity-patterns.md +319 -0
- package/skills/ue-mass-entity/references/mass-fragment-reference.md +119 -0
- package/skills/ue-materials-rendering/SKILL.md +526 -0
- package/skills/ue-materials-rendering/references/material-parameter-reference.md +216 -0
- package/skills/ue-materials-rendering/references/post-process-settings.md +383 -0
- package/skills/ue-module-build-system/SKILL.md +487 -0
- package/skills/ue-module-build-system/references/build-cs-reference.md +418 -0
- package/skills/ue-module-build-system/references/common-build-errors.md +381 -0
- package/skills/ue-naming-conventions/SKILL.md +142 -0
- package/skills/ue-naming-conventions/references/asset-name-modifiers.md +233 -0
- package/skills/ue-naming-conventions/references/content-structure.md +83 -0
- package/skills/ue-networking-replication/SKILL.md +452 -0
- package/skills/ue-networking-replication/references/replication-patterns.md +526 -0
- package/skills/ue-networking-replication/references/rpc-decision-guide.md +393 -0
- package/skills/ue-niagara-effects/SKILL.md +531 -0
- package/skills/ue-niagara-effects/references/niagara-data-interfaces.md +491 -0
- package/skills/ue-niagara-effects/references/niagara-parameter-types.md +153 -0
- package/skills/ue-niagara-effects/references/niagara-workflow.md +115 -0
- package/skills/ue-packaging/SKILL.md +116 -0
- package/skills/ue-physics-collision/SKILL.md +423 -0
- package/skills/ue-physics-collision/references/collision-channel-setup.md +218 -0
- package/skills/ue-physics-collision/references/trace-patterns.md +499 -0
- package/skills/ue-procedural-generation/SKILL.md +505 -0
- package/skills/ue-procedural-generation/references/pcg-node-reference.md +381 -0
- package/skills/ue-procedural-generation/references/procedural-mesh-patterns.md +940 -0
- package/skills/ue-project-context/SKILL.md +305 -0
- package/skills/ue-sequencer-cinematics/SKILL.md +506 -0
- package/skills/ue-sequencer-cinematics/references/sequencer-patterns.md +629 -0
- package/skills/ue-serialization-savegames/SKILL.md +524 -0
- package/skills/ue-serialization-savegames/references/save-system-architecture.md +705 -0
- package/skills/ue-state-trees/SKILL.md +489 -0
- package/skills/ue-state-trees/references/state-tree-mass-integration.md +184 -0
- package/skills/ue-state-trees/references/state-tree-patterns.md +321 -0
- package/skills/ue-testing-debugging/SKILL.md +520 -0
- package/skills/ue-testing-debugging/references/automation-test-patterns.md +387 -0
- package/skills/ue-testing-debugging/references/profiling-commands.md +357 -0
- package/skills/ue-ui-umg-slate/SKILL.md +431 -0
- package/skills/ue-ui-umg-slate/references/common-ui-setup.md +484 -0
- package/skills/ue-ui-umg-slate/references/widget-types.md +487 -0
- package/skills/ue-world-level-streaming/SKILL.md +518 -0
- package/skills/ue-world-level-streaming/references/streaming-patterns.md +414 -0
- package/templates/gamedev/unreal-project-context.md +107 -0
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
name: unreal-dev
|
|
2
|
+
description: "Programador Unreal Engine 5 — C++, Blueprints, GAS, replication, rendering, naming conventions, build y editor MCP"
|
|
3
|
+
type: base
|
|
4
|
+
|
|
5
|
+
skills:
|
|
6
|
+
# Foundation — read this first, every other ue-* skill depends on it
|
|
7
|
+
- ue-project-context
|
|
8
|
+
- ue-naming-conventions
|
|
9
|
+
# C++ & architecture
|
|
10
|
+
- ue-cpp-foundations
|
|
11
|
+
- ue-actor-component-architecture
|
|
12
|
+
- ue-gameplay-framework
|
|
13
|
+
- ue-module-build-system
|
|
14
|
+
- ue-async-threading
|
|
15
|
+
# Blueprints
|
|
16
|
+
- ue-blueprints
|
|
17
|
+
# Gameplay systems
|
|
18
|
+
- ue-gameplay-abilities
|
|
19
|
+
- ue-character-movement
|
|
20
|
+
- ue-animation-system
|
|
21
|
+
- ue-physics-collision
|
|
22
|
+
- ue-game-features
|
|
23
|
+
- ue-networking-replication
|
|
24
|
+
# AI & behaviour
|
|
25
|
+
- ue-ai-navigation
|
|
26
|
+
- ue-state-trees
|
|
27
|
+
- ue-mass-entity
|
|
28
|
+
# Rendering & VFX
|
|
29
|
+
- ue-materials-rendering
|
|
30
|
+
- ue-niagara-effects
|
|
31
|
+
# Audio & cinematics
|
|
32
|
+
- ue-audio-system
|
|
33
|
+
- ue-sequencer-cinematics
|
|
34
|
+
# World & data
|
|
35
|
+
- ue-world-level-streaming
|
|
36
|
+
- ue-procedural-generation
|
|
37
|
+
- ue-data-assets-tables
|
|
38
|
+
- ue-serialization-savegames
|
|
39
|
+
# UI & input
|
|
40
|
+
- ue-ui-umg-slate
|
|
41
|
+
- ue-input-system
|
|
42
|
+
# Tooling, build & QA
|
|
43
|
+
- ue-editor-tools
|
|
44
|
+
- ue-testing-debugging
|
|
45
|
+
- ue-packaging
|
|
46
|
+
# Cross-engine, reused from the shared library
|
|
47
|
+
# Unreal ships its own MCP as engine plugins; install-mcp only enables and connects it.
|
|
48
|
+
- install-mcp
|
|
49
|
+
- test-setup
|
|
50
|
+
- perf-profile
|
|
51
|
+
- optimize
|
|
52
|
+
- deps-audit
|
|
53
|
+
- env-sync
|
|
54
|
+
- security-audit
|
|
55
|
+
- release-checklist
|
|
56
|
+
- patch-notes
|
|
57
|
+
- onboard
|
|
58
|
+
- map-systems
|
|
59
|
+
- game-audit
|
|
60
|
+
- audit-game
|
|
61
|
+
- asset-audit
|
|
62
|
+
- accessibility
|
|
63
|
+
- balance-check
|
|
64
|
+
- consistency-check
|
|
65
|
+
- doc-gdd
|
|
66
|
+
- playtest-report
|
|
67
|
+
|
|
68
|
+
rules:
|
|
69
|
+
universal:
|
|
70
|
+
[]
|
|
71
|
+
gamedev:
|
|
72
|
+
- unreal-code
|
|
73
|
+
- gameplay-code
|
|
74
|
+
- engine-code
|
|
75
|
+
- shader-code
|
|
76
|
+
- network-code
|
|
77
|
+
- ui-code
|
|
78
|
+
- ai-code
|
|
79
|
+
|
|
80
|
+
agents:
|
|
81
|
+
- game
|
|
82
|
+
|
|
83
|
+
permissions:
|
|
84
|
+
allow:
|
|
85
|
+
- "Bash(*RunUAT*)"
|
|
86
|
+
- "Bash(*UnrealBuildTool*)"
|
|
87
|
+
- "Bash(*UnrealEditor-Cmd*)"
|
|
88
|
+
- "Bash(*GenerateProjectFiles*)"
|
|
89
|
+
- "Glob(Source/**)"
|
|
90
|
+
- "Glob(Plugins/**)"
|
|
91
|
+
- "Grep(Source/**)"
|
|
92
|
+
deny:
|
|
93
|
+
- "Write(Content/**)"
|
|
94
|
+
- "Edit(Content/**)"
|
|
95
|
+
- "Write(Binaries/**)"
|
|
96
|
+
- "Write(Intermediate/**)"
|
|
97
|
+
- "Write(DerivedDataCache/**)"
|
|
@@ -9,14 +9,19 @@ Las rutas son relativas al career workspace (`./career-workspace/` o env `CAREER
|
|
|
9
9
|
- Al terminar el borrador de un CV custom (flujo cv-tailor) o de una cover / mensaje de aplicación (flujo cover-letter) destinado a una postulación concreta.
|
|
10
10
|
- NO aplica a ediciones menores de un CV ya revisado (typos, cambiar una fecha) ni a los CVs base de `02-CVs/` fuera de una postulación.
|
|
11
11
|
|
|
12
|
+
Quién la ejecuta: `/job-aplicar` (paso 7, obligatorio), y `/cv-tailor` y `/cover-letter` cuando se corren sueltos. Los tres declaran `Task` en `allowed-tools` justamente para poder cumplirla - un skill sin `Task` no puede aplicar esta regla, y ahí la regla sería solo una intención.
|
|
13
|
+
|
|
12
14
|
## El paso reviewer
|
|
13
15
|
|
|
14
|
-
Lanzar UN agente
|
|
16
|
+
Lanzar UN agente **`cv-reviewer`** de contexto fresco vía el Agent tool. El agente ya trae la persona, el límite de lectura y el contrato de salida; el prompt solo tiene que aportar lo que el agente no puede saber:
|
|
15
17
|
|
|
16
18
|
1. El texto completo de la job description.
|
|
17
19
|
2. El borrador del CV y/o cover, verbatim.
|
|
18
|
-
3.
|
|
19
|
-
|
|
20
|
+
3. Cuál es el perfil usado, para que sepa qué archivo de `01-Perfiles/` puede leer.
|
|
21
|
+
|
|
22
|
+
Va inline en el prompt para que no dependa de leer archivos de la conversación.
|
|
23
|
+
|
|
24
|
+
Si el agente `cv-reviewer` no está instalado (perfil `+job-hunt` sin su directorio de agentes), usar un `general-purpose` y pasarle en el prompt las cuatro restricciones: lectura acotada a `01-Perfiles/<perfil usado>.md`, prohibido leer templates y el resto del workspace, research web breve de la empresa, y el contrato de salida de abajo.
|
|
20
25
|
|
|
21
26
|
El reviewer devuelve dos partes:
|
|
22
27
|
|
|
@@ -27,6 +32,14 @@ El reviewer devuelve dos partes:
|
|
|
27
32
|
- Bullets que se pueden reformular como logro medible
|
|
28
33
|
- Tono / estilo (registro, longitud, muletillas)
|
|
29
34
|
|
|
35
|
+
## Segunda lente (opcional): `hiring-manager`
|
|
36
|
+
|
|
37
|
+
`cv-reviewer` contesta "¿pasa el filtro?". Un CV puede pasar con match del 85% y morir igual en el escritorio de quien contrata, por una razón distinta: **no hay evidencia de que la persona ya hizo el trabajo**.
|
|
38
|
+
|
|
39
|
+
Cuándo vale el segundo agente: postulación que importa, rol senior, o racha de rechazos post-CV. Se lanza **en paralelo** con `cv-reviewer` (no en cadena: son lentes independientes y encadenarlos solo suma latencia). Devuelve veredicto, evidencia faltante y las 3 preguntas que haría, que además son material de `/interview-prep`.
|
|
40
|
+
|
|
41
|
+
No es obligatorio. Para una aplicación de rutina, `cv-reviewer` solo alcanza.
|
|
42
|
+
|
|
30
43
|
## Reglas de aplicación del feedback
|
|
31
44
|
|
|
32
45
|
- **Una sola ronda.** El drafter aplica la Parte A, incorpora de la Parte B lo que corresponda, y sigue. Sin ida y vuelta iterativo.
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# Freelance Guardrails (marketplaces y clientes directos)
|
|
2
|
+
|
|
3
|
+
Buscar empleo es gratis: aplicás a 40 puestos y solo perdés tiempo. Freelancear no. Cada propuesta cuesta algo, cada contrato malo toca tu reputación, y cada "¿me agregás esto rapidito?" sin cobrar sale de tu bolsillo.
|
|
4
|
+
|
|
5
|
+
Estas cuatro reglas existen porque los tres recursos que se gastan (plata, reputación, tiempo no facturado) no se recuperan.
|
|
6
|
+
|
|
7
|
+
**El costo de postularse tiene nombre distinto en cada plataforma** y las reglas valen igual: Connects en Upwork, bids en Freelancer.com, y en outreach directo son las horas que ponés en escribir la propuesta. Donde abajo diga Connects, leé "lo que te cuesta postularte".
|
|
8
|
+
|
|
9
|
+
Las rutas son relativas al career workspace (`./career-workspace/` o env `CAREER_WORKSPACE`).
|
|
10
|
+
|
|
11
|
+
## 1. Postularse cuesta plata: no se gasta sin screen
|
|
12
|
+
|
|
13
|
+
Nunca redactar una propuesta para una oferta cuyo cliente no pasó `/client-screen`, ni para una que quedó bajo el umbral de score.
|
|
14
|
+
|
|
15
|
+
Si el usuario quiere postularse igual a una que falló el screen, se puede - **pero se le dice qué falló y se registra en la nota**. Un pago sin verificar que nadie nombró es una postulación tirada, y peor: es la propuesta que sí te contestan y termina en disputa.
|
|
16
|
+
|
|
17
|
+
## 2. La reputación se protege rechazando
|
|
18
|
+
|
|
19
|
+
Ganar un contrato no siempre es bueno. Casi toda plataforma calcula un puntaje sobre contratos cerrados (en Upwork es el Job Success Score) donde un cliente insatisfecho pesa más que dos contentos, y con clientes directos el equivalente son las referencias que no vas a poder pedir. Un contrato con alcance difuso, presupuesto irrealista o cliente sin historial es **riesgo de reputación**, no una oportunidad.
|
|
20
|
+
|
|
21
|
+
Cuando el screen marca riesgo alto, la recomendación por defecto es no postularse. Decir "no" es una acción del pipeline, no una ausencia de acción.
|
|
22
|
+
|
|
23
|
+
## 3. Nada se cotiza abajo del piso
|
|
24
|
+
|
|
25
|
+
Todo bid pasa por el piso declarado en `01-Perfiles/` (tarifa mínima aceptable). El piso es **neto**, después de la comisión de la plataforma: si se queda un 10%, un piso de 40 USD/h exige bidear 45. Con cliente directo la comisión es cero, pero el piso sigue siendo neto de impuestos y de las horas no facturables.
|
|
26
|
+
|
|
27
|
+
Si el usuario todavía no fijó un piso, `/freelance-scan market` da la mediana de lo que cobran otros con su perfil. Es un punto de partida, no el piso: el piso lo define su costo de vida, no el mercado.
|
|
28
|
+
|
|
29
|
+
Alcance nuevo, precio nuevo. Ninguna propuesta ni contrato se amplía sin cotizarlo: si el trabajo extra no entra en un change order con número, no entra.
|
|
30
|
+
|
|
31
|
+
## 4. El envío siempre lo hace el usuario
|
|
32
|
+
|
|
33
|
+
Ninguna skill de este perfil envía una propuesta, acepta un contrato ni gasta el presupuesto de postulaciones. Se redacta, se revisa, se muestra, y el usuario copia y manda.
|
|
34
|
+
|
|
35
|
+
Esto no es prudencia nuestra: **la API de Upwork no tiene mutation para postularse ni para gastar Connects**, justamente para frenar bots de auto-bidding, y las demás plataformas prohíben el envío automatizado en sus términos. Ninguna skill debe pretender lo contrario, y una que lo intentara estaría violando los ToS además de esta regla.
|
|
36
|
+
|
|
37
|
+
El corolario para las **fuentes**: ninguna skill del perfil puede depender de credenciales que cada usuario tenga que conseguir por su cuenta. Este perfil lo instala cualquiera, y una fuente con API key aprobada a mano funciona para uno y está rota para el resto. Las fuentes automáticas son públicas y sin key (ver `skills/freelance-scan/references/platforms.md`); lo demás se pega a mano.
|
|
38
|
+
|
|
39
|
+
## La estructura no la sostiene este archivo
|
|
40
|
+
|
|
41
|
+
Una regla sin columna derecha es una intención.
|
|
42
|
+
|
|
43
|
+
| Regla | Qué la hace cumplir |
|
|
44
|
+
|---|---|
|
|
45
|
+
| Screen antes de gastar en postularse | `/freelance-proposal` exige la nota de screen; sin ella, pregunta y no redacta |
|
|
46
|
+
| Rechazar por riesgo de reputación | `/client-screen` emite veredicto explícito; el agente `client-screener` es adversarial por diseño |
|
|
47
|
+
| Piso de tarifa | `/freelance-proposal` lee el piso del perfil y falla ruidoso si el bid queda abajo; `/freelance-scan market` da la referencia de mercado |
|
|
48
|
+
| Alcance nuevo, precio nuevo | `/freelance-pipeline` detecta drift de alcance en contratos activos y pide change order |
|
|
49
|
+
| Envío manual | Ningún script del perfil escribe a una plataforma: `freelance_search.py` solo lee, y no hay otro |
|
|
50
|
+
|
|
51
|
+
## Registro
|
|
52
|
+
|
|
53
|
+
Toda decisión de no postularse se registra igual que una postulación: nota en `03-Aplicaciones/` con `estado: descartado` y el motivo en `## Notas`. Los descartes son la mitad de los datos que `/freelance-pipeline` necesita para decirte si tu criterio de selección funciona.
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
---
|
|
2
|
+
paths:
|
|
3
|
+
- "Source/**"
|
|
4
|
+
- "Plugins/**/Source/**"
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Unreal Engine C++ Rules
|
|
8
|
+
|
|
9
|
+
- Every UObject reference held by another UObject must be a `TObjectPtr<>` marked `UPROPERTY()` — an unmarked pointer is invisible to the GC and becomes a dangling pointer
|
|
10
|
+
- Never `new`/`delete` a UObject — use `NewObject<>()` or `CreateDefaultSubobject<>()`; use `TSharedPtr`/`TUniquePtr`/`TWeakPtr` only for non-UObject types
|
|
11
|
+
- Follow engine naming: `U` for UObject, `A` for AActor, `F` for structs, `E` for enums, `I` for interfaces, `T` for templates
|
|
12
|
+
- Restrict every identifier to `[A-Za-z0-9_]` — no whitespace, no symbols, no Unicode. This applies to type names, asset references and paths alike; non-ASCII identifiers break cooking, batch tools and source control in ways that surface far from the cause
|
|
13
|
+
- Use `FName` for identifiers and lookups, `FText` for anything shown to a player, `FString` only for manipulation — never build display strings by concatenating `FString` for localized UI
|
|
14
|
+
- Use `TArray`/`TMap`/`TSet`, not STL containers, in any reflected or engine-facing code
|
|
15
|
+
- `Tick` is opt-in, not default: disable it (`PrimaryActorTick.bCanEverTick = false`) and use timers, delegates or events instead. Ticking work multiplied across instances is a measured cost, not an assumption
|
|
16
|
+
- ZERO allocations in hot paths (tick, animation, physics, rendering) — pre-allocate, pool and reuse
|
|
17
|
+
- Always call `Super::` in overridden engine functions (`BeginPlay`, `EndPlay`, `Tick`, `GetLifetimeReplicatedProps`, `PostInitializeComponents`)
|
|
18
|
+
- Every replicated `UPROPERTY(Replicated)` must appear in `GetLifetimeReplicatedProps` with a `DOREPLIFETIME` entry, and every Server RPC must validate its input — never trust the client
|
|
19
|
+
- Use soft references (`TSoftObjectPtr`, `TSoftClassPtr`) plus the Asset Manager for assets that are not always needed; a hard reference pulls the whole asset tree into memory
|
|
20
|
+
- No synchronous load of large assets on the game thread during gameplay — use `StreamableManager` / async loading
|
|
21
|
+
- UObject access happens on the game thread only; async completion paths must handle their owner being destroyed mid-flight
|
|
22
|
+
- Editor-only code lives in an editor module or behind `WITH_EDITOR`, and never ships in a runtime target
|
|
23
|
+
- Profile with Unreal Insights and `stat` commands before AND after every optimization — document the measured numbers
|
|
24
|
+
- Blueprint Nativization was removed in UE5; never propose it as an optimization
|
|
25
|
+
|
|
26
|
+
## Examples
|
|
27
|
+
|
|
28
|
+
**Correct** (GC-visible reference, no tick, validated RPC):
|
|
29
|
+
|
|
30
|
+
```cpp
|
|
31
|
+
UCLASS()
|
|
32
|
+
class AGate : public AActor
|
|
33
|
+
{
|
|
34
|
+
GENERATED_BODY()
|
|
35
|
+
|
|
36
|
+
public:
|
|
37
|
+
AGate()
|
|
38
|
+
{
|
|
39
|
+
PrimaryActorTick.bCanEverTick = false; // event-driven, nothing to tick
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
protected:
|
|
43
|
+
virtual void BeginPlay() override
|
|
44
|
+
{
|
|
45
|
+
Super::BeginPlay(); // never skip Super
|
|
46
|
+
OnActorBeginOverlap.AddDynamic(this, &AGate::HandleOverlap);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
UFUNCTION(Server, Reliable, WithValidation)
|
|
50
|
+
void ServerRequestOpen();
|
|
51
|
+
|
|
52
|
+
private:
|
|
53
|
+
// TObjectPtr + UPROPERTY: the GC can see and keep this alive.
|
|
54
|
+
UPROPERTY(VisibleAnywhere)
|
|
55
|
+
TObjectPtr<UStaticMeshComponent> Frame;
|
|
56
|
+
|
|
57
|
+
// Soft reference: the VFX only loads when the gate actually opens.
|
|
58
|
+
UPROPERTY(EditDefaultsOnly)
|
|
59
|
+
TSoftObjectPtr<UNiagaraSystem> OpenEffect;
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
bool AGate::ServerRequestOpen_Validate()
|
|
63
|
+
{
|
|
64
|
+
return true;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
void AGate::ServerRequestOpen_Implementation()
|
|
68
|
+
{
|
|
69
|
+
// Server re-checks authority and state; the client's word is not enough.
|
|
70
|
+
if (!HasAuthority() || bIsLocked)
|
|
71
|
+
{
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
OpenInternal();
|
|
75
|
+
}
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
**Incorrect** (invisible to GC, needless tick, trusted client, hot-path allocation):
|
|
79
|
+
|
|
80
|
+
```cpp
|
|
81
|
+
UCLASS()
|
|
82
|
+
class AGate : public AActor
|
|
83
|
+
{
|
|
84
|
+
GENERATED_BODY()
|
|
85
|
+
|
|
86
|
+
// VIOLATION: raw pointer with no UPROPERTY — GC cannot see it, this will dangle
|
|
87
|
+
UStaticMeshComponent* Frame;
|
|
88
|
+
|
|
89
|
+
// VIOLATION: hard reference, loads the VFX and its dependencies with this actor
|
|
90
|
+
UPROPERTY()
|
|
91
|
+
UNiagaraSystem* OpenEffect;
|
|
92
|
+
|
|
93
|
+
virtual void BeginPlay() override
|
|
94
|
+
{
|
|
95
|
+
// VIOLATION: missing Super::BeginPlay()
|
|
96
|
+
Frame = new UStaticMeshComponent(); // VIOLATION: never new a UObject
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
virtual void Tick(float DeltaTime) override
|
|
100
|
+
{
|
|
101
|
+
// VIOLATION: allocates every frame
|
|
102
|
+
TArray<AActor*> Nearby;
|
|
103
|
+
UGameplayStatics::GetAllActorsOfClass(GetWorld(), APawn::StaticClass(), Nearby);
|
|
104
|
+
|
|
105
|
+
// VIOLATION: string comparison in a hot path — use FName or a tag
|
|
106
|
+
for (AActor* A : Nearby)
|
|
107
|
+
{
|
|
108
|
+
if (A->GetName() == TEXT("BP_Player_C_0"))
|
|
109
|
+
{
|
|
110
|
+
OpenInternal();
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
UFUNCTION(Server, Unreliable)
|
|
116
|
+
void ServerRequestOpen(bool bClientSaysUnlocked)
|
|
117
|
+
{
|
|
118
|
+
// VIOLATION: trusts a client-supplied authority decision
|
|
119
|
+
if (bClientSaysUnlocked)
|
|
120
|
+
{
|
|
121
|
+
OpenInternal();
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
};
|
|
125
|
+
```
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: career-registry
|
|
3
|
+
description: "Traceability across the whole career workspace: check whether you already applied somewhere before spending another application, export everything to CSV, and audit the registry for gaps and drift. Covers job applications, freelance proposals and contracts. Triggers: ya me postule a, ya aplique aca, exportar postulaciones a csv, registro de aplicaciones, trazabilidad, historial de postulaciones, cuantas mande, planilla de postulaciones, auditar el registro."
|
|
4
|
+
argument-hint: "[check <empresa|url> | export | stats | audit]"
|
|
5
|
+
category: "career"
|
|
6
|
+
user-invocable: true
|
|
7
|
+
allowed-tools: Read, Glob, Grep, Bash, Write, Edit
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Career Registry - Trazabilidad y registro
|
|
11
|
+
|
|
12
|
+
Contestás la pregunta que grepear a mano contesta mal: **¿ya me postulé acá?** Y das el registro completo en CSV para mirarlo en una planilla.
|
|
13
|
+
|
|
14
|
+
Sirve a los dos perfiles: `+job-hunt` (empleo) y `+freelance` (proyectos). Rutas relativas al career workspace (`--workspace`, env `CAREER_WORKSPACE`, o `./career-workspace/`).
|
|
15
|
+
|
|
16
|
+
Modo: `$ARGUMENTS`
|
|
17
|
+
|
|
18
|
+
## La regla que sostiene todo esto
|
|
19
|
+
|
|
20
|
+
**Las notas son la fuente de verdad. El CSV se deriva de ellas, siempre.**
|
|
21
|
+
|
|
22
|
+
No hay una segunda base que mantener sincronizada, y no la va a haber: una segunda base diverge en dos semanas y después nadie sabe cuál miente. Es el mismo flujo unidireccional que el dedup de `/job-scrape` (`seen_jobs` → nota → vista, nunca de vuelta).
|
|
23
|
+
|
|
24
|
+
Consecuencia práctica: si el CSV está mal, se arregla la nota, no el CSV. Y si el usuario pide "guardame el CSV para editarlo a mano", avisale que en la próxima corrida se pisa.
|
|
25
|
+
|
|
26
|
+
## Los cuatro modos
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
python .claude/skills/career-registry/scripts/career_registry.py check "Acme"
|
|
30
|
+
python .claude/skills/career-registry/scripts/career_registry.py check "https://www.linkedin.com/jobs/view/123"
|
|
31
|
+
python .claude/skills/career-registry/scripts/career_registry.py export --csv registro.csv
|
|
32
|
+
python .claude/skills/career-registry/scripts/career_registry.py stats
|
|
33
|
+
python .claude/skills/career-registry/scripts/career_registry.py audit
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
### `check` - antes de gastar otra postulación
|
|
37
|
+
|
|
38
|
+
Busca por **tres claves** porque el usuario pega cualquiera de las tres: nombre de la contraparte, URL de la oferta, o título de la nota.
|
|
39
|
+
|
|
40
|
+
Es tolerante donde importa: `acme` encuentra a "Acme Inc" (ignora sufijos legales), `tecnologia latam` encuentra a "Tecnología Latam SA" (ignora acentos), y una URL con `?utm_source=...` distinto encuentra la misma oferta (canoniza el link, igual que el dedup).
|
|
41
|
+
|
|
42
|
+
Devuelve un veredicto de tres valores, y la diferencia entre los dos primeros importa:
|
|
43
|
+
|
|
44
|
+
| Veredicto | Qué significa |
|
|
45
|
+
|---|---|
|
|
46
|
+
| `YA TE POSTULASTE` | Hay una nota en estado enviado. No repitas |
|
|
47
|
+
| `YA LO VISTE, NO TE POSTULASTE` | Hay nota o entrada de dedup, pero nunca se envió. Vale revisarla antes de descartarla de nuevo |
|
|
48
|
+
| `SIN REGISTRO` | Nunca apareció |
|
|
49
|
+
|
|
50
|
+
Cuándo correrlo: **antes de `/client-screen` o `/job-aplicar`**, cuando el nombre suena conocido. Un screen sobre algo que ya descartaste hace tres meses es trabajo repetido, y peor, te hace repetir el descarte sin recordar por qué.
|
|
51
|
+
|
|
52
|
+
### `export` - el CSV
|
|
53
|
+
|
|
54
|
+
Una fila por nota, con `tipo` discriminando empleo / freelance / contrato. Columnas: contraparte, título, estado, si está abierta, plataforma, `match_score`, riesgo del cliente, perfil usado, bid o monto, costo de postularse, fechas, **días sin movimiento**, link y la ruta de la nota.
|
|
55
|
+
|
|
56
|
+
Sin `--csv` va a stdout; con `--csv <archivo>` lo escribe en UTF-8 con BOM para que Excel no rompa los acentos. `--tipo` filtra a un solo tipo.
|
|
57
|
+
|
|
58
|
+
`dias_sin_movimiento` es la columna más útil de la planilla: ordenando por ahí aparece lo que quedó colgado.
|
|
59
|
+
|
|
60
|
+
### `stats` - conteos
|
|
61
|
+
|
|
62
|
+
Total y abiertas por tipo, desglose por estado, cuántas se enviaron y el costo de postulaciones registrado.
|
|
63
|
+
|
|
64
|
+
Trae `muestra_suficiente_para_tasas`: **con menos de 10 enviadas es `false`, y ahí no hay que calcular tasas de conversión**. Diez rechazos no son un patrón, y tratarlos como tal manda al usuario a arreglar lo que no estaba roto.
|
|
65
|
+
|
|
66
|
+
### `audit` - las divergencias
|
|
67
|
+
|
|
68
|
+
Lo que hace que la trazabilidad sea real y no una intención:
|
|
69
|
+
|
|
70
|
+
- Notas sin `estado` o sin contraparte
|
|
71
|
+
- Enviadas sin fecha de envío (rompe cualquier cálculo de tiempos)
|
|
72
|
+
- **Abiertas frenadas hace 21+ días** - candidatas a follow-up con `/cold-outreach` o a cerrar como `sin_respuesta`
|
|
73
|
+
- Posibles duplicados: misma contraparte, mismo título, dos notas
|
|
74
|
+
- **Contratos con horas reales arriba de lo estimado**, con el exceso en horas y en porcentaje. Cada uno es trabajo regalado si no hubo change order
|
|
75
|
+
- Punteros del dedup que apuntan a notas que ya no existen
|
|
76
|
+
|
|
77
|
+
## Proceso
|
|
78
|
+
|
|
79
|
+
1. Correr el modo pedido. Si el workspace no existe, el script lo dice y sugiere `/freelance-hunt setup` o `/job-hunt setup`.
|
|
80
|
+
2. **Mostrar el resultado en el chat, no solo el JSON crudo.** Para `check`, el veredicto y una línea por coincidencia con su estado. Para `audit`, agrupado por severidad: primero lo que cuesta plata (horas de más, enviadas sin fecha), después lo cosmético.
|
|
81
|
+
3. Para cada hallazgo de `audit`, ofrecer la acción concreta: follow-up, cerrar como `sin_respuesta`, change order, o completar el campo que falta.
|
|
82
|
+
4. Los arreglos se hacen **en la nota** con approval del usuario, una por una. Nunca en masa.
|
|
83
|
+
|
|
84
|
+
## Reglas
|
|
85
|
+
|
|
86
|
+
- **Nunca editar el CSV como si fuera la fuente de verdad.** Se regenera; los cambios van a la nota.
|
|
87
|
+
- **No editar notas en masa.** Cada arreglo se muestra y se aprueba.
|
|
88
|
+
- Nunca inventar un dato que falta: si una nota no tiene fecha de envío, se pregunta o se deja el hueco reportado.
|
|
89
|
+
- No cambiar `estado`: eso lo hace `/job-outcome`, que es el único que mueve el pipeline.
|
|
90
|
+
- El CSV puede tener nombres de clientes y montos: **no commitearlo a un remoto sin confirmación explícita**.
|
|
91
|
+
- Sin guiones largos en el texto agregado a las notas.
|
|
92
|
+
|
|
93
|
+
## Handoff
|
|
94
|
+
|
|
95
|
+
Pedí aprobación (approval) antes de escribir el CSV o tocar una nota. Registro COMPLETE cuando el modo corrió y el usuario sabe qué hacer con cada hallazgo. Según el caso, el siguiente paso es `/cold-outreach` (follow-up de lo frenado), `/job-outcome` (cerrar lo que no va a responder), `/contract-and-proposal-writer` (change order de las horas de más) o `/freelance-pipeline` (si hay 10+ resueltas y querés el diagnóstico del embudo).
|