@nio-cli/cli 0.1.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 (196) hide show
  1. package/README.md +280 -0
  2. package/dist/adapters/supabase/allocation-gateway.js +236 -0
  3. package/dist/adapters/supabase/allocation-gateway.js.map +1 -0
  4. package/dist/adapters/supabase/analytics-gateway.js +18 -0
  5. package/dist/adapters/supabase/analytics-gateway.js.map +1 -0
  6. package/dist/adapters/supabase/client.js +96 -0
  7. package/dist/adapters/supabase/client.js.map +1 -0
  8. package/dist/adapters/supabase/context-gateway.js +23 -0
  9. package/dist/adapters/supabase/context-gateway.js.map +1 -0
  10. package/dist/adapters/supabase/gateway.js +18 -0
  11. package/dist/adapters/supabase/gateway.js.map +1 -0
  12. package/dist/adapters/supabase/task-gateway.js +450 -0
  13. package/dist/adapters/supabase/task-gateway.js.map +1 -0
  14. package/dist/auth.js +118 -0
  15. package/dist/auth.js.map +1 -0
  16. package/dist/brand.js +91 -0
  17. package/dist/brand.js.map +1 -0
  18. package/dist/cli/commands/auth.js +128 -0
  19. package/dist/cli/commands/auth.js.map +1 -0
  20. package/dist/cli/commands/clean.js +120 -0
  21. package/dist/cli/commands/clean.js.map +1 -0
  22. package/dist/cli/commands/completion.js +114 -0
  23. package/dist/cli/commands/completion.js.map +1 -0
  24. package/dist/cli/commands/exec.js +59 -0
  25. package/dist/cli/commands/exec.js.map +1 -0
  26. package/dist/cli/commands/init/auth-step.js +49 -0
  27. package/dist/cli/commands/init/auth-step.js.map +1 -0
  28. package/dist/cli/commands/init/clients-step.js +76 -0
  29. package/dist/cli/commands/init/clients-step.js.map +1 -0
  30. package/dist/cli/commands/init/context-step.js +71 -0
  31. package/dist/cli/commands/init/context-step.js.map +1 -0
  32. package/dist/cli/commands/init/index.js +76 -0
  33. package/dist/cli/commands/init/index.js.map +1 -0
  34. package/dist/cli/commands/init/project-step.js +105 -0
  35. package/dist/cli/commands/init/project-step.js.map +1 -0
  36. package/dist/cli/commands/init/provision-step.js +103 -0
  37. package/dist/cli/commands/init/provision-step.js.map +1 -0
  38. package/dist/cli/commands/plan.js +45 -0
  39. package/dist/cli/commands/plan.js.map +1 -0
  40. package/dist/cli/commands/skills.js +23 -0
  41. package/dist/cli/commands/skills.js.map +1 -0
  42. package/dist/cli/commands/sync.js +296 -0
  43. package/dist/cli/commands/sync.js.map +1 -0
  44. package/dist/cli/commands/validate-plan.js +42 -0
  45. package/dist/cli/commands/validate-plan.js.map +1 -0
  46. package/dist/cli/copy/auth.json +6 -0
  47. package/dist/cli/copy/flows.json +6 -0
  48. package/dist/cli/copy/init.json +19 -0
  49. package/dist/cli/copy/sync.json +3 -0
  50. package/dist/cli/copy.js +23 -0
  51. package/dist/cli/copy.js.map +1 -0
  52. package/dist/cli/flows/clients.js +130 -0
  53. package/dist/cli/flows/clients.js.map +1 -0
  54. package/dist/cli/flows/completion.js +63 -0
  55. package/dist/cli/flows/completion.js.map +1 -0
  56. package/dist/cli/flows/dependencies.js +114 -0
  57. package/dist/cli/flows/dependencies.js.map +1 -0
  58. package/dist/cli/flows/sections.js +85 -0
  59. package/dist/cli/flows/sections.js.map +1 -0
  60. package/dist/cli/flows/user-config.js +37 -0
  61. package/dist/cli/flows/user-config.js.map +1 -0
  62. package/dist/cli/ui/render.js +237 -0
  63. package/dist/cli/ui/render.js.map +1 -0
  64. package/dist/cli/ui/report.js +117 -0
  65. package/dist/cli/ui/report.js.map +1 -0
  66. package/dist/cli.js +36 -0
  67. package/dist/cli.js.map +1 -0
  68. package/dist/config.js +280 -0
  69. package/dist/config.js.map +1 -0
  70. package/dist/constants.js +9 -0
  71. package/dist/constants.js.map +1 -0
  72. package/dist/core/ports.js +2 -0
  73. package/dist/core/ports.js.map +1 -0
  74. package/dist/core/types.js +7 -0
  75. package/dist/core/types.js.map +1 -0
  76. package/dist/database.types.js +11 -0
  77. package/dist/database.types.js.map +1 -0
  78. package/dist/lib/active-project.js +28 -0
  79. package/dist/lib/active-project.js.map +1 -0
  80. package/dist/lib/autopull.js +13 -0
  81. package/dist/lib/autopull.js.map +1 -0
  82. package/dist/lib/client-configs.js +191 -0
  83. package/dist/lib/client-configs.js.map +1 -0
  84. package/dist/lib/client-install.js +40 -0
  85. package/dist/lib/client-install.js.map +1 -0
  86. package/dist/lib/colors.js +93 -0
  87. package/dist/lib/colors.js.map +1 -0
  88. package/dist/lib/cowork-extension.js +143 -0
  89. package/dist/lib/cowork-extension.js.map +1 -0
  90. package/dist/lib/dependencies.js +145 -0
  91. package/dist/lib/dependencies.js.map +1 -0
  92. package/dist/lib/dependency-install.js +163 -0
  93. package/dist/lib/dependency-install.js.map +1 -0
  94. package/dist/lib/duration.js +5 -0
  95. package/dist/lib/duration.js.map +1 -0
  96. package/dist/lib/exec-delegate.js +167 -0
  97. package/dist/lib/exec-delegate.js.map +1 -0
  98. package/dist/lib/exec-engines.js +72 -0
  99. package/dist/lib/exec-engines.js.map +1 -0
  100. package/dist/lib/file-merge.js +33 -0
  101. package/dist/lib/file-merge.js.map +1 -0
  102. package/dist/lib/harness.js +90 -0
  103. package/dist/lib/harness.js.map +1 -0
  104. package/dist/lib/hooks.js +217 -0
  105. package/dist/lib/hooks.js.map +1 -0
  106. package/dist/lib/patterns.js +61 -0
  107. package/dist/lib/patterns.js.map +1 -0
  108. package/dist/lib/plan-delegate.js +106 -0
  109. package/dist/lib/plan-delegate.js.map +1 -0
  110. package/dist/lib/project-context.js +151 -0
  111. package/dist/lib/project-context.js.map +1 -0
  112. package/dist/lib/prompts.js +69 -0
  113. package/dist/lib/prompts.js.map +1 -0
  114. package/dist/lib/provision-apply.js +220 -0
  115. package/dist/lib/provision-apply.js.map +1 -0
  116. package/dist/lib/provision-collect.js +47 -0
  117. package/dist/lib/provision-collect.js.map +1 -0
  118. package/dist/lib/provision.js +45 -0
  119. package/dist/lib/provision.js.map +1 -0
  120. package/dist/lib/require-config.js +32 -0
  121. package/dist/lib/require-config.js.map +1 -0
  122. package/dist/lib/rules.js +99 -0
  123. package/dist/lib/rules.js.map +1 -0
  124. package/dist/lib/sections.js +89 -0
  125. package/dist/lib/sections.js.map +1 -0
  126. package/dist/lib/skill-serve.js +129 -0
  127. package/dist/lib/skill-serve.js.map +1 -0
  128. package/dist/lib/skills-cache.js +99 -0
  129. package/dist/lib/skills-cache.js.map +1 -0
  130. package/dist/lib/skills.js +236 -0
  131. package/dist/lib/skills.js.map +1 -0
  132. package/dist/lib/targets.js +151 -0
  133. package/dist/lib/targets.js.map +1 -0
  134. package/dist/lib/task-history.js +15 -0
  135. package/dist/lib/task-history.js.map +1 -0
  136. package/dist/lib/telemetry.js +51 -0
  137. package/dist/lib/telemetry.js.map +1 -0
  138. package/dist/lib/tool-result.js +12 -0
  139. package/dist/lib/tool-result.js.map +1 -0
  140. package/dist/lib/validate-plan-delegate.js +107 -0
  141. package/dist/lib/validate-plan-delegate.js.map +1 -0
  142. package/dist/lib/version-check.js +89 -0
  143. package/dist/lib/version-check.js.map +1 -0
  144. package/dist/matrix-logo.js +122 -0
  145. package/dist/matrix-logo.js.map +1 -0
  146. package/dist/mcp-server.js +189 -0
  147. package/dist/mcp-server.js.map +1 -0
  148. package/dist/session-factory.js +19 -0
  149. package/dist/session-factory.js.map +1 -0
  150. package/dist/spinner.js +12 -0
  151. package/dist/spinner.js.map +1 -0
  152. package/dist/tools/comment-task.js +72 -0
  153. package/dist/tools/comment-task.js.map +1 -0
  154. package/dist/tools/create-task.js +129 -0
  155. package/dist/tools/create-task.js.map +1 -0
  156. package/dist/tools/delegate-exec.js +63 -0
  157. package/dist/tools/delegate-exec.js.map +1 -0
  158. package/dist/tools/end-allocation.js +38 -0
  159. package/dist/tools/end-allocation.js.map +1 -0
  160. package/dist/tools/end-task-allocation.js +37 -0
  161. package/dist/tools/end-task-allocation.js.map +1 -0
  162. package/dist/tools/exec-status.js +43 -0
  163. package/dist/tools/exec-status.js.map +1 -0
  164. package/dist/tools/get-active-allocation.js +69 -0
  165. package/dist/tools/get-active-allocation.js.map +1 -0
  166. package/dist/tools/get-context.js +48 -0
  167. package/dist/tools/get-context.js.map +1 -0
  168. package/dist/tools/get-task.js +137 -0
  169. package/dist/tools/get-task.js.map +1 -0
  170. package/dist/tools/index.js +44 -0
  171. package/dist/tools/index.js.map +1 -0
  172. package/dist/tools/list-my-allocations.js +71 -0
  173. package/dist/tools/list-my-allocations.js.map +1 -0
  174. package/dist/tools/list-projects.js +38 -0
  175. package/dist/tools/list-projects.js.map +1 -0
  176. package/dist/tools/list-tasks.js +93 -0
  177. package/dist/tools/list-tasks.js.map +1 -0
  178. package/dist/tools/move-task.js +82 -0
  179. package/dist/tools/move-task.js.map +1 -0
  180. package/dist/tools/plan.js +56 -0
  181. package/dist/tools/plan.js.map +1 -0
  182. package/dist/tools/record-delivery.js +71 -0
  183. package/dist/tools/record-delivery.js.map +1 -0
  184. package/dist/tools/set-project.js +52 -0
  185. package/dist/tools/set-project.js.map +1 -0
  186. package/dist/tools/start-allocation.js +32 -0
  187. package/dist/tools/start-allocation.js.map +1 -0
  188. package/dist/tools/start-task-allocation.js +75 -0
  189. package/dist/tools/start-task-allocation.js.map +1 -0
  190. package/dist/tools/update-task.js +139 -0
  191. package/dist/tools/update-task.js.map +1 -0
  192. package/dist/tools/validate-plan.js +58 -0
  193. package/dist/tools/validate-plan.js.map +1 -0
  194. package/dist/version.js +16 -0
  195. package/dist/version.js.map +1 -0
  196. package/package.json +64 -0
@@ -0,0 +1,129 @@
1
+ import { readSkillFiles, toSkillDocs } from './skills.js';
2
+ import { brand } from '../brand.js';
3
+ /**
4
+ * Camada de **serviço** do pacote de skills pro servidor MCP: expõe os docs como
5
+ * resources (leitura sob demanda) e como prompts (slash/commands no Cowork e Codex).
6
+ * Só o `mcp-server.ts` importa isto — o CLI nunca precisa.
7
+ */
8
+ export const SKILLS_URI_PREFIX = `${brand.name}://skills/`;
9
+ let cache = null;
10
+ /** Carrega o pacote de skills, memoizado (não muda enquanto o processo roda). */
11
+ export function loadSkills(dir) {
12
+ if (cache && !dir)
13
+ return cache;
14
+ const files = readSkillFiles(dir);
15
+ const loaded = {
16
+ docs: toSkillDocs(files),
17
+ rawByPath: new Map(files.map((f) => [f.path, f.raw])),
18
+ };
19
+ if (!dir)
20
+ cache = loaded;
21
+ return loaded;
22
+ }
23
+ /** Limpa o cache (testes / dir custom). */
24
+ export function clearSkillsCache() {
25
+ cache = null;
26
+ }
27
+ /**
28
+ * Nome do resource em estilo caminho — agrupa a listagem por tipo/skill (como o
29
+ * conector do Figma), em vez de despejar títulos soltos. Skills e commands viram
30
+ * `skill/<id>` / `command/<id>`; arquivos de apoio (templates, *-PATTERN) aninham
31
+ * sob a skill dona (`skill/init-sdd/templates/spec`); docs soltos viram `doc/<path>`.
32
+ */
33
+ function resourceName(doc, skillFolders) {
34
+ if (doc.type === 'command')
35
+ return `command/${doc.id}`;
36
+ if (doc.type === 'agent')
37
+ return `agent/${doc.id}`;
38
+ if (doc.type === 'dependency')
39
+ return `dependency/${doc.id}`;
40
+ if (doc.type === 'skill')
41
+ return `skill/${doc.id}`;
42
+ // doc: aninha sob a skill dona, se estiver dentro da pasta de uma.
43
+ for (const [folder, id] of skillFolders) {
44
+ if (doc.path.startsWith(`${folder}/`)) {
45
+ const sub = doc.path.slice(folder.length + 1).replace(/\.md$/i, '');
46
+ return `skill/${id}/${sub}`;
47
+ }
48
+ }
49
+ return `doc/${doc.path.replace(/\.md$/i, '')}`;
50
+ }
51
+ export function skillResourceDescriptors(docs) {
52
+ // Pasta (dir do SKILL.md) → id, pra aninhar os arquivos de apoio sob a skill.
53
+ const skillFolders = new Map();
54
+ for (const d of docs) {
55
+ if (d.type === 'skill')
56
+ skillFolders.set(d.path.slice(0, d.path.lastIndexOf('/')), d.id);
57
+ }
58
+ return docs
59
+ // `command`/`skill` já são servidos como **prompts** — não repetir como resource
60
+ // (senão o Cowork lista cada um duas vezes). Aqui ficam só os arquivos de apoio
61
+ // (templates/patterns), agents e dependencies.
62
+ .filter((d) => d.type !== 'command' && d.type !== 'skill')
63
+ .map((d) => ({
64
+ uri: `${SKILLS_URI_PREFIX}${d.path}`,
65
+ name: resourceName(d, skillFolders),
66
+ description: d.description || d.title,
67
+ mimeType: 'text/markdown',
68
+ }))
69
+ .sort((a, b) => a.name.localeCompare(b.name));
70
+ }
71
+ /** Lê um resource pela URI, a partir dos docs + os markdowns crus por path. */
72
+ export function readSkillResource(uri, docs, rawByPath) {
73
+ if (!uri.startsWith(SKILLS_URI_PREFIX))
74
+ throw new Error(`URI fora do pacote de skills: ${uri}`);
75
+ const rel = uri.slice(SKILLS_URI_PREFIX.length);
76
+ const doc = docs.find((d) => d.path === rel);
77
+ if (!doc)
78
+ throw new Error(`Recurso não encontrado: ${uri}`);
79
+ return { uri, mimeType: 'text/markdown', text: rawByPath.get(rel) ?? doc.content };
80
+ }
81
+ /** Só `command` e `skill` viram prompts (docs/agents/dependencies não). */
82
+ function isPromptable(type) {
83
+ return type === 'command' || type === 'skill';
84
+ }
85
+ export function skillPromptDescriptors(docs) {
86
+ return docs
87
+ .filter((d) => isPromptable(d.type))
88
+ .map((d) => ({
89
+ name: d.id,
90
+ description: `[${d.type}] ${d.description || d.title}`.slice(0, 200),
91
+ arguments: [
92
+ {
93
+ name: 'args',
94
+ description: d.frontmatter['argument-hint'] || 'Argumentos opcionais passados ao prompt.',
95
+ required: false,
96
+ },
97
+ ],
98
+ }));
99
+ }
100
+ /** Monta o texto de um prompt: corpo do doc com `$ARGUMENTS` substituído. */
101
+ export function buildSkillPrompt(name, args, docs) {
102
+ const doc = docs.find((d) => d.id === name && isPromptable(d.type));
103
+ if (!doc)
104
+ throw new Error(`Prompt desconhecido: ${name}`);
105
+ let text = doc.content.split('$ARGUMENTS').join(args?.args ?? '');
106
+ // Cowork/Codex servem a skill como **prompt** — não têm o filesystem dela. Então os
107
+ // arquivos de apoio (`templates/*`, `*-PATTERN.md`, `STANDARDS.md`) que o corpo
108
+ // referencia por path relativo não existem lá. Inline-os pra a skill ficar
109
+ // auto-contida (no Claude Code isso não roda — lá os arquivos são nativos).
110
+ if (doc.type === 'skill') {
111
+ const folder = doc.path.slice(0, doc.path.lastIndexOf('/'));
112
+ const companions = docs
113
+ .filter((d) => d.type === 'doc' && d.path.startsWith(`${folder}/`))
114
+ .sort((a, b) => a.path.localeCompare(b.path));
115
+ if (companions.length > 0) {
116
+ const blocks = companions
117
+ .map((comp) => {
118
+ const rel = comp.path.slice(folder.length + 1);
119
+ return `\n\n---\n\n### Arquivo de apoio da skill: \`${rel}\`\n\n${comp.content.trim()}`;
120
+ })
121
+ .join('');
122
+ text +=
123
+ `\n\n<!-- Arquivos de apoio inline: o Cowork/Codex não têm o filesystem da ` +
124
+ `skill; use estes no lugar das referências por path relativo acima. -->${blocks}`;
125
+ }
126
+ }
127
+ return { description: doc.description || doc.title, text };
128
+ }
129
+ //# sourceMappingURL=skill-serve.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skill-serve.js","sourceRoot":"","sources":["../../src/lib/skill-serve.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,99 @@
1
+ import { existsSync, mkdirSync, rmSync, cpSync, readdirSync, readFileSync, writeFileSync, } from 'node:fs';
2
+ import { tmpdir } from 'node:os';
3
+ import { join } from 'node:path';
4
+ import AdmZip from 'adm-zip';
5
+ import { brand, env, homePath } from '../brand.js';
6
+ /**
7
+ * Skills como repo aberto (não pacote npm): o CLI baixa o zipball do GitHub pro
8
+ * cache local (`~/.nio/skills`) e lê de lá — `skillsDir()` resolve pra cá sem
9
+ * checkout, e `nio sync` atualiza o cache sem republicar o CLI.
10
+ */
11
+ const DEFAULT_REPO = brand.skillsRepo;
12
+ const DEFAULT_REF = brand.skillsRef;
13
+ /** `owner/repo` do repo de skills. Sobrescrevível via `NIO_SKILLS_REPO`. */
14
+ export function skillsRepo() {
15
+ return env('SKILLS_REPO') || DEFAULT_REPO;
16
+ }
17
+ /** Branch/tag a baixar. Sobrescrevível via `NIO_SKILLS_REF`. */
18
+ export function skillsRef() {
19
+ return env('SKILLS_REF') || DEFAULT_REF;
20
+ }
21
+ /** Raiz do cache local (o conteúdo do repo: `commands/`, `skills/`, `hooks/`, …). */
22
+ export function skillsCacheDir() {
23
+ return homePath('skills');
24
+ }
25
+ const MARKER = `${brand.homeDirName}-skills.json`;
26
+ /** Metadados do último fetch (repo/ref/quando). `null` se o cache não existe. */
27
+ export function cacheMeta() {
28
+ const p = join(skillsCacheDir(), MARKER);
29
+ if (!existsSync(p))
30
+ return null;
31
+ try {
32
+ return JSON.parse(readFileSync(p, 'utf8'));
33
+ }
34
+ catch {
35
+ return null;
36
+ }
37
+ }
38
+ /** O cache existe e parece válido (tem ao menos `skills/` ou `commands/`)? */
39
+ export function skillsCached() {
40
+ const dir = skillsCacheDir();
41
+ return existsSync(join(dir, 'skills')) || existsSync(join(dir, 'commands'));
42
+ }
43
+ /**
44
+ * Baixa o repo de skills (zipball do GitHub) pro cache local. Sem `git` — usa
45
+ * `fetch` (Node 20+) + `adm-zip`. Idempotente: com `force=false` e cache presente,
46
+ * não toca a rede. Se o download falhar mas houver cache antigo, segue com ele.
47
+ */
48
+ /** Timeout do download — sem isto o `fetch` pode pendurar no connect pra sempre. */
49
+ const DEFAULT_TIMEOUT_MS = 20_000;
50
+ export async function fetchSkills(opts = {}) {
51
+ const dir = skillsCacheDir();
52
+ const repo = skillsRepo();
53
+ const ref = skillsRef();
54
+ if (!opts.force && skillsCached()) {
55
+ return { status: 'cached', dir, repo, ref };
56
+ }
57
+ const url = `https://codeload.github.com/${repo}/zip/refs/heads/${ref}`;
58
+ const staging = join(tmpdir(), `${brand.name}-skills-${process.pid}-${Date.now()}`);
59
+ const timeoutMs = opts.timeoutMs ?? DEFAULT_TIMEOUT_MS;
60
+ const ac = new AbortController();
61
+ const timer = setTimeout(() => ac.abort(), timeoutMs);
62
+ try {
63
+ const res = await fetch(url, { signal: ac.signal });
64
+ if (!res.ok)
65
+ throw new Error(`HTTP ${res.status} ao baixar ${url}`);
66
+ const buf = Buffer.from(await res.arrayBuffer());
67
+ // O zipball tem um único dir raiz (`<repo>-<ref>/`); extrai e mira nele.
68
+ rmSync(staging, { recursive: true, force: true });
69
+ mkdirSync(staging, { recursive: true });
70
+ new AdmZip(buf).extractAllTo(staging, true);
71
+ const dirs = readdirSync(staging, { withFileTypes: true }).filter((e) => e.isDirectory());
72
+ const root = dirs.length === 1 ? join(staging, dirs[0].name) : staging;
73
+ // Substitui o cache pelo conteúdo baixado.
74
+ rmSync(dir, { recursive: true, force: true });
75
+ mkdirSync(dir, { recursive: true });
76
+ cpSync(root, dir, { recursive: true });
77
+ const meta = { repo, ref, fetchedAt: new Date().toISOString() };
78
+ writeFileSync(join(dir, MARKER), JSON.stringify(meta, null, 2) + '\n', 'utf8');
79
+ return { status: 'fetched', dir, repo, ref };
80
+ }
81
+ catch (err) {
82
+ const msg = ac.signal.aborted
83
+ ? `timeout após ${timeoutMs}ms baixando ${url}`
84
+ : err.message;
85
+ if (skillsCached()) {
86
+ return { status: 'cached', dir, repo, ref, error: msg };
87
+ }
88
+ return { status: 'failed', dir, repo, ref, error: msg };
89
+ }
90
+ finally {
91
+ clearTimeout(timer);
92
+ rmSync(staging, { recursive: true, force: true });
93
+ }
94
+ }
95
+ /** Garante que o cache exista (baixa só se ausente). Best-effort pro runtime do MCP. */
96
+ export async function ensureSkillsCache() {
97
+ return fetchSkills({ force: false });
98
+ }
99
+ //# sourceMappingURL=skills-cache.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skills-cache.js","sourceRoot":"","sources":["../../src/lib/skills-cache.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,UAAU,EACV,SAAS,EACT,MAAM,EACN,MAAM,EACN,WAAW,EACX,YAAY,EACZ,aAAa,GACd,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,MAAM,MAAM,SAAS,CAAC;AAC7B,OAAO,EAAE,KAAK,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAEnD;;;;GAIG;AAEH,MAAM,YAAY,GAAG,KAAK,CAAC,UAAU,CAAC;AACtC,MAAM,WAAW,GAAG,KAAK,CAAC,SAAS,CAAC;AAEpC,4EAA4E;AAC5E,MAAM,UAAU,UAAU;IACxB,OAAO,GAAG,CAAC,aAAa,CAAC,IAAI,YAAY,CAAC;AAC5C,CAAC;AAED,gEAAgE;AAChE,MAAM,UAAU,SAAS;IACvB,OAAO,GAAG,CAAC,YAAY,CAAC,IAAI,WAAW,CAAC;AAC1C,CAAC;AAED,qFAAqF;AACrF,MAAM,UAAU,cAAc;IAC5B,OAAO,QAAQ,CAAC,QAAQ,CAAC,CAAC;AAC5B,CAAC;AAED,MAAM,MAAM,GAAG,GAAG,KAAK,CAAC,WAAW,cAAc,CAAC;AAQlD,iFAAiF;AACjF,MAAM,UAAU,SAAS;IACvB,MAAM,CAAC,GAAG,IAAI,CAAC,cAAc,EAAE,EAAE,MAAM,CAAC,CAAC;IACzC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC;QAAE,OAAO,IAAI,CAAC;IAChC,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC,EAAE,MAAM,CAAC,CAAc,CAAC;IAC1D,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,8EAA8E;AAC9E,MAAM,UAAU,YAAY;IAC1B,MAAM,GAAG,GAAG,cAAc,EAAE,CAAC;IAC7B,OAAO,UAAU,CAAC,IAAI,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC,IAAI,UAAU,CAAC,IAAI,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC,CAAC;AAC9E,CAAC;AAYD;;;;GAIG;AACH,oFAAoF;AACpF,MAAM,kBAAkB,GAAG,MAAM,CAAC;AAElC,MAAM,CAAC,KAAK,UAAU,WAAW,CAC/B,OAAgD,EAAE;IAElD,MAAM,GAAG,GAAG,cAAc,EAAE,CAAC;IAC7B,MAAM,IAAI,GAAG,UAAU,EAAE,CAAC;IAC1B,MAAM,GAAG,GAAG,SAAS,EAAE,CAAC;IAExB,IAAI,CAAC,IAAI,CAAC,KAAK,IAAI,YAAY,EAAE,EAAE,CAAC;QAClC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC;IAC9C,CAAC;IAED,MAAM,GAAG,GAAG,+BAA+B,IAAI,mBAAmB,GAAG,EAAE,CAAC;IACxE,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,EAAE,EAAE,GAAG,KAAK,CAAC,IAAI,WAAW,OAAO,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;IACpF,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,IAAI,kBAAkB,CAAC;IACvD,MAAM,EAAE,GAAG,IAAI,eAAe,EAAE,CAAC;IACjC,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,KAAK,EAAE,EAAE,SAAS,CAAC,CAAC;IACtD,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE,EAAE,MAAM,EAAE,EAAE,CAAC,MAAM,EAAE,CAAC,CAAC;QACpD,IAAI,CAAC,GAAG,CAAC,EAAE;YAAE,MAAM,IAAI,KAAK,CAAC,QAAQ,GAAG,CAAC,MAAM,cAAc,GAAG,EAAE,CAAC,CAAC;QACpE,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,WAAW,EAAE,CAAC,CAAC;QAEjD,yEAAyE;QACzE,MAAM,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QAClD,SAAS,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACxC,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,YAAY,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;QAC5C,MAAM,IAAI,GAAG,WAAW,CAAC,OAAO,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC;QAC1F,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;QAEvE,2CAA2C;QAC3C,MAAM,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QAC9C,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACpC,MAAM,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAEvC,MAAM,IAAI,GAAc,EAAE,IAAI,EAAE,GAAG,EAAE,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,EAAE,CAAC;QAC3E,aAAa,CAAC,IAAI,CAAC,GAAG,EAAE,MAAM,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,EAAE,MAAM,CAAC,CAAC;QAE/E,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC;IAC/C,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,GAAG,GAAG,EAAE,CAAC,MAAM,CAAC,OAAO;YAC3B,CAAC,CAAC,gBAAgB,SAAS,eAAe,GAAG,EAAE;YAC/C,CAAC,CAAE,GAAa,CAAC,OAAO,CAAC;QAC3B,IAAI,YAAY,EAAE,EAAE,CAAC;YACnB,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC;QAC1D,CAAC;QACD,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC;IAC1D,CAAC;YAAS,CAAC;QACT,YAAY,CAAC,KAAK,CAAC,CAAC;QACpB,MAAM,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IACpD,CAAC;AACH,CAAC;AAED,wFAAwF;AACxF,MAAM,CAAC,KAAK,UAAU,iBAAiB;IACrC,OAAO,WAAW,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC;AACvC,CAAC"}
@@ -0,0 +1,236 @@
1
+ import { existsSync, readFileSync, readdirSync } from 'node:fs';
2
+ import { createRequire } from 'node:module';
3
+ import { join, relative, sep, dirname } from 'node:path';
4
+ import { skillsCacheDir, skillsCached } from './skills-cache.js';
5
+ import { includePath } from './sections.js';
6
+ import { brand, env } from '../brand.js';
7
+ /**
8
+ * Diretório do conteúdo das skills. Resolve em ordem: `NIO_SKILLS_DIR`
9
+ * (checkout local), `@nio-cli/skills` via require.resolve (dev legado), ou o
10
+ * cache `~/.nio/skills` populado por `nio sync`/`init` (fluxo padrão).
11
+ */
12
+ export function skillsDir() {
13
+ const override = env('SKILLS_DIR');
14
+ if (override && existsSync(override))
15
+ return override;
16
+ try {
17
+ const require = createRequire(import.meta.url);
18
+ return dirname(require.resolve(`${brand.skillsPackage}/package.json`));
19
+ }
20
+ catch {
21
+ /* pacote ausente (modelo repo-aberto) → cai pro cache local */
22
+ }
23
+ if (skillsCached())
24
+ return skillsCacheDir();
25
+ throw new Error(`Conteúdo de skills não encontrado. Rode \`${brand.name} sync\` pra baixar o repo ` +
26
+ '(ou defina NIO_SKILLS_DIR apontando pra um checkout local).');
27
+ }
28
+ function listMarkdown(dir) {
29
+ const out = [];
30
+ const walk = (abs) => {
31
+ for (const entry of readdirSync(abs, { withFileTypes: true })) {
32
+ if (entry.name.startsWith('.'))
33
+ continue;
34
+ const childAbs = join(abs, entry.name);
35
+ if (entry.isDirectory())
36
+ walk(childAbs);
37
+ else if (entry.isFile() &&
38
+ entry.name.toLowerCase().endsWith('.md') &&
39
+ entry.name.toLowerCase() !== 'readme.md')
40
+ out.push(relative(dir, childAbs).split(sep).join('/'));
41
+ }
42
+ };
43
+ walk(dir);
44
+ return out;
45
+ }
46
+ /**
47
+ * Coleta as linhas indentadas/vazias seguintes (bloco YAML folded `>` ou literal `|`)
48
+ * a partir de `lines[i + 1]`. Retorna o valor já juntado e o novo índice do cursor
49
+ * (última linha consumida) pro chamador continuar o loop dali.
50
+ */
51
+ function collectBlockValue(lines, i, folded) {
52
+ const collected = [];
53
+ while (i + 1 < lines.length && (lines[i + 1].trim() === '' || /^\s+\S/.test(lines[i + 1]))) {
54
+ collected.push(lines[++i].trim());
55
+ }
56
+ const value = folded
57
+ ? collected.join(' ').replace(/\s+/g, ' ').trim()
58
+ : collected.join('\n').trim();
59
+ return { value, nextIndex: i };
60
+ }
61
+ /** Valor entre aspas simples/duplas → sem as aspas. Sem aspas → devolve como veio. */
62
+ function unquote(value) {
63
+ if ((value.startsWith('"') && value.endsWith('"')) ||
64
+ (value.startsWith("'") && value.endsWith("'"))) {
65
+ return value.slice(1, -1);
66
+ }
67
+ return value;
68
+ }
69
+ /**
70
+ * Parser de frontmatter minimalista: `key: value` de uma linha, mais blocos
71
+ * folded (`>`) e literal (`|`). Suficiente pros metadados (não é YAML completo).
72
+ */
73
+ function parseFrontmatter(raw) {
74
+ const fm = {};
75
+ const match = /^---\r?\n([\s\S]*?)\r?\n---\r?\n?/.exec(raw);
76
+ if (!match)
77
+ return { frontmatter: fm, body: raw };
78
+ const lines = match[1].split(/\r?\n/);
79
+ for (let i = 0; i < lines.length; i++) {
80
+ const m = /^([A-Za-z0-9_-]+):\s*(.*)$/.exec(lines[i]);
81
+ if (!m)
82
+ continue;
83
+ const key = m[1];
84
+ const value = m[2].trim();
85
+ if (/^[|>][+-]?$/.test(value)) {
86
+ const block = collectBlockValue(lines, i, value[0] === '>');
87
+ fm[key] = block.value;
88
+ i = block.nextIndex;
89
+ continue;
90
+ }
91
+ fm[key] = unquote(value);
92
+ }
93
+ return { frontmatter: fm, body: raw.slice(match[0].length) };
94
+ }
95
+ /** Clientes de IA reconhecidos pra visibilidade de docs. */
96
+ export const KNOWN_CLIENTS = ['claude-code', 'codex', 'cowork'];
97
+ const KNOWN_CLIENTS_SET = new Set(KNOWN_CLIENTS);
98
+ /**
99
+ * Parseia o campo `clients:` do frontmatter (lista separada por vírgula/espaço)
100
+ * num conjunto normalizado. Vazio/ausente/sem valor válido → `null` (= todos).
101
+ */
102
+ export function parseClients(value) {
103
+ if (!value)
104
+ return null;
105
+ const list = value
106
+ .split(/[,\s]+/)
107
+ .map((s) => s.trim().toLowerCase())
108
+ .filter((s) => KNOWN_CLIENTS_SET.has(s));
109
+ return list.length > 0 ? [...new Set(list)] : null;
110
+ }
111
+ /** Um doc é visível pra um surface se não restringe clientes ou inclui aquele. */
112
+ export function docForSurface(doc, surface) {
113
+ if (!surface)
114
+ return true;
115
+ return !doc.clients || doc.clients.includes(surface);
116
+ }
117
+ /** Recorta a lista de docs pros visíveis num surface. */
118
+ export function filterSkillsForSurface(docs, surface) {
119
+ if (!surface)
120
+ return docs;
121
+ return docs.filter((d) => docForSurface(d, surface));
122
+ }
123
+ /**
124
+ * Filtra docs crus (relPath+conteúdo) pros visíveis num surface. Docs sem
125
+ * frontmatter de doc (ex.: scripts soltos) são mantidos por padrão.
126
+ */
127
+ export function filterDocsForSurface(docs, surface) {
128
+ if (!surface)
129
+ return docs;
130
+ const parsed = toSkillDocs(docs.map((d) => ({ path: d.relPath, raw: d.content.toString('utf8') })));
131
+ const hidden = new Set(parsed.filter((n) => !docForSurface(n, surface)).map((n) => n.path));
132
+ return docs.filter((d) => !hidden.has(d.relPath));
133
+ }
134
+ function typeForPath(relPath) {
135
+ const parts = relPath.split('/');
136
+ const top = parts[0];
137
+ const base = parts[parts.length - 1].toLowerCase();
138
+ if (top === 'commands')
139
+ return 'command';
140
+ // Só `SKILL.md` é a skill; arquivos de apoio (STANDARDS.md, etc.) são `doc`.
141
+ if (top === 'skills')
142
+ return base === 'skill.md' ? 'skill' : 'doc';
143
+ if (top === 'agents')
144
+ return 'agent';
145
+ if (top === 'dependencies')
146
+ return 'dependency';
147
+ return 'doc';
148
+ }
149
+ /** Id de invocação: skill = nome da pasta (SKILL.md); o resto = basename sem `.md`. */
150
+ function idForPath(relPath) {
151
+ const parts = relPath.split('/');
152
+ const base = parts[parts.length - 1];
153
+ if (base.toLowerCase() === 'skill.md' && parts.length >= 2)
154
+ return parts[parts.length - 2];
155
+ return base.replace(/\.md$/i, '');
156
+ }
157
+ function humanize(id) {
158
+ return id.replace(/[-_]/g, ' ').replace(/\b\w/g, (c) => c.toUpperCase());
159
+ }
160
+ /**
161
+ * "Kinds" do pacote que viram docs. `rules/`, `hooks/`, `index.md`, `README.md`,
162
+ * `scripts/` etc. são deliberadamente ignorados — o CLI não lida com eles aqui.
163
+ */
164
+ const SKILL_KINDS = ['commands', 'skills', 'agents', 'dependencies'];
165
+ /** Lê os `.md` dos kinds do pacote (`@nio-cli/skills`) como RawDoc[]. */
166
+ export function readSkillFiles(dir = skillsDir()) {
167
+ if (!existsSync(dir)) {
168
+ throw new Error(`Pacote de skills não encontrado em ${dir}. Instale/publique ${brand.skillsPackage}.`);
169
+ }
170
+ const docs = [];
171
+ for (const kind of SKILL_KINDS) {
172
+ const kindDir = join(dir, kind);
173
+ if (!existsSync(kindDir))
174
+ continue;
175
+ for (const rel of listMarkdown(kindDir)) {
176
+ docs.push({ path: `${kind}/${rel}`, raw: readFileSync(join(kindDir, rel), 'utf-8') });
177
+ }
178
+ }
179
+ return docs;
180
+ }
181
+ /** Constrói os docs a partir de arquivos crus (frontmatter + corpo). */
182
+ export function toSkillDocs(files) {
183
+ return files
184
+ .map(({ path: relPath, raw }) => {
185
+ const { frontmatter, body } = parseFrontmatter(raw);
186
+ const id = idForPath(relPath);
187
+ return {
188
+ id,
189
+ uid: frontmatter.id ? String(frontmatter.id).trim() : null,
190
+ title: frontmatter.title || frontmatter.name || humanize(id),
191
+ type: typeForPath(relPath),
192
+ path: relPath,
193
+ description: frontmatter.description ?? '',
194
+ frontmatter,
195
+ content: body.trim(),
196
+ clients: parseClients(frontmatter.clients),
197
+ };
198
+ })
199
+ .sort((a, b) => a.path.localeCompare(b.path));
200
+ }
201
+ export function readSkillDocs(dir = skillsDir()) {
202
+ return toSkillDocs(readSkillFiles(dir));
203
+ }
204
+ /**
205
+ * Docs `dependency` do pacote — libs externas que a CLI oferece instalar no fim do
206
+ * `sync`/`init`. Escopadas pela **seleção** (role/área/stack, `general` em cascata):
207
+ * `dev/general` sempre, mais as da área/stack escolhidos. Sem seleção → todas.
208
+ * Best-effort: `[]` se o pacote não estiver disponível.
209
+ */
210
+ export function readDependencies(selection, dir = skillsDir()) {
211
+ try {
212
+ let deps = readSkillDocs(dir).filter((d) => d.type === 'dependency');
213
+ if (selection)
214
+ deps = deps.filter((d) => includePath(d.path, selection));
215
+ return deps.sort((a, b) => a.title.localeCompare(b.title));
216
+ }
217
+ catch {
218
+ return [];
219
+ }
220
+ }
221
+ /**
222
+ * Mapa `nome de invocação → id sequencial (frontmatter)`, pra telemetria estável.
223
+ * Best-effort: mapa vazio se o `@nio-cli/skills` não estiver disponível.
224
+ */
225
+ export function skillIdMap(dir = skillsDir()) {
226
+ const map = new Map();
227
+ try {
228
+ for (const d of readSkillDocs(dir))
229
+ map.set(d.id, d.uid);
230
+ }
231
+ catch {
232
+ /* @nio-cli/skills ausente → telemetria sem ids */
233
+ }
234
+ return map;
235
+ }
236
+ //# sourceMappingURL=skills.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skills.js","sourceRoot":"","sources":["../../src/lib/skills.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,151 @@
1
+ import { existsSync } from 'node:fs';
2
+ import { homedir } from 'node:os';
3
+ import { join } from 'node:path';
4
+ import { toSkillDocs } from './skills.js';
5
+ import { readJson, readToml } from './file-merge.js';
6
+ import { brand } from '../brand.js';
7
+ export const claudeTarget = {
8
+ id: 'claude',
9
+ label: 'Claude Code (~/.claude)',
10
+ surface: 'claude-code',
11
+ targetDir: () => join(homedir(), '.claude'),
12
+ mapDocs: (docs) => docs,
13
+ };
14
+ /**
15
+ * Texto que substitui `$ARGUMENTS` na tradução pro Codex. Skills do Codex são
16
+ * selecionadas por descrição e dirigidas por linguagem natural — não há
17
+ * substituição de slash-args como no caminho de command/prompt do Claude.
18
+ */
19
+ const ARGS_REWORD = 'the arguments the user provided';
20
+ /** Escapa uma descrição pra uma linha de YAML entre aspas duplas. */
21
+ function yamlQuote(value) {
22
+ const oneLine = value.replace(/\r?\n/g, ' ').replace(/\s+/g, ' ').trim();
23
+ return `"${oneLine.replace(/\\/g, '\\\\').replace(/"/g, '\\"')}"`;
24
+ }
25
+ /** Renderiza o SKILL.md de um node no formato Agent Skills (name + description). */
26
+ export function toCodexSkillContent(node) {
27
+ const description = node.frontmatter.description || node.description || node.title;
28
+ const frontmatter = `---\nname: ${node.id}\ndescription: ${yamlQuote(description)}\n---\n`;
29
+ let body = node.content;
30
+ if (body.includes('$ARGUMENTS')) {
31
+ body = body.split('$ARGUMENTS').join(ARGS_REWORD);
32
+ }
33
+ // `argument-hint` não existe em skills — dobra num aviso de entrada esperada.
34
+ const hint = node.frontmatter['argument-hint'];
35
+ const inputLine = hint ? `**Expected input:** ${hint}\n\n` : '';
36
+ return `${frontmatter}\n${inputLine}${body.trim()}\n`;
37
+ }
38
+ /**
39
+ * Renderiza um custom prompt do Codex (`~/.codex/prompts/<id>.md`). Diferente da skill,
40
+ * o Codex expande `$ARGUMENTS`/`$1..$9` aqui, então preservamos os placeholders.
41
+ */
42
+ export function toCodexPromptContent(node) {
43
+ const description = node.frontmatter.description || node.description || node.title;
44
+ const hint = node.frontmatter['argument-hint'];
45
+ const fmLines = [`description: ${yamlQuote(description)}`];
46
+ if (hint)
47
+ fmLines.push(`argument-hint: ${yamlQuote(hint)}`);
48
+ const frontmatter = `---\n${fmLines.join('\n')}\n---\n`;
49
+ // Corpo original, com `$ARGUMENTS`/`$1` intactos (o Codex substitui na invocação).
50
+ return `${frontmatter}\n${node.content.trim()}\n`;
51
+ }
52
+ /**
53
+ * Traduz os docs crus pro layout do Codex em dual-write: cada `command`/`skill` vira
54
+ * uma skill (`skills/<id>/SKILL.md`) E um custom prompt (`prompts/<id>.md`). Os
55
+ * arquivos de apoio de uma skill (`templates/*.md`, `*-PATTERN.md`, `STANDARDS.md` —
56
+ * type `doc`, vizinhos do `SKILL.md`) são carregados pra dentro de `skills/<id>/`
57
+ * preservando o path relativo, pra que o SKILL.md traduzido consiga referenciá-los
58
+ * exatamente como no Claude. `agent` e `doc` fora de uma skill são ignorados.
59
+ */
60
+ export function toCodexDocs(docs) {
61
+ const nodes = toSkillDocs(docs.map((d) => ({ path: d.relPath, raw: d.content.toString('utf8') })));
62
+ const rawByPath = new Map(docs.map((d) => [d.relPath, d.content]));
63
+ // Pasta da skill (dir do SKILL.md) -> id, pra rotear os arquivos de apoio.
64
+ const skillFolders = new Map();
65
+ for (const node of nodes) {
66
+ if (node.type === 'skill') {
67
+ skillFolders.set(node.path.slice(0, node.path.lastIndexOf('/')), node.id);
68
+ }
69
+ }
70
+ const out = [];
71
+ const seen = new Map(); // id -> path de origem (guarda de colisão)
72
+ for (const node of nodes) {
73
+ if (node.type === 'command' || node.type === 'skill') {
74
+ const prev = seen.get(node.id);
75
+ if (prev) {
76
+ throw new Error(`Tradução Codex: id duplicado "${node.id}" (${prev} e ${node.path}). ` +
77
+ `O id precisa ser único — renomeie um deles.`);
78
+ }
79
+ seen.set(node.id, node.path);
80
+ out.push({
81
+ relPath: `skills/${node.id}/SKILL.md`,
82
+ content: Buffer.from(toCodexSkillContent(node), 'utf8'),
83
+ });
84
+ out.push({
85
+ relPath: `prompts/${node.id}.md`,
86
+ content: Buffer.from(toCodexPromptContent(node), 'utf8'),
87
+ });
88
+ continue;
89
+ }
90
+ // Arquivo de apoio de uma skill: carrega verbatim pro dir da skill traduzida,
91
+ // mantendo o path relativo (ex.: `templates/spec.md`, `SPEC-PATTERN.md`).
92
+ if (node.type === 'doc') {
93
+ for (const [folder, id] of skillFolders) {
94
+ if (!node.path.startsWith(`${folder}/`))
95
+ continue;
96
+ const rel = node.path.slice(folder.length + 1);
97
+ const raw = rawByPath.get(node.path);
98
+ if (raw)
99
+ out.push({ relPath: `skills/${id}/${rel}`, content: raw });
100
+ break;
101
+ }
102
+ }
103
+ }
104
+ return out;
105
+ }
106
+ export const codexTarget = {
107
+ id: 'codex',
108
+ label: 'Codex CLI (~/.codex)',
109
+ surface: 'codex',
110
+ targetDir: () => join(homedir(), '.codex'),
111
+ mapDocs: (docs) => toCodexDocs(docs),
112
+ };
113
+ export const ALL_TARGETS = [claudeTarget, codexTarget];
114
+ function claudeConfigured() {
115
+ const path = join(homedir(), '.claude', 'settings.json');
116
+ if (!existsSync(path))
117
+ return false;
118
+ try {
119
+ const json = (readJson(path) ?? {});
120
+ return Boolean(json.mcpServers?.[brand.mcpServerKey]);
121
+ }
122
+ catch {
123
+ return false;
124
+ }
125
+ }
126
+ function codexConfigured() {
127
+ const path = join(homedir(), '.codex', 'config.toml');
128
+ if (!existsSync(path))
129
+ return false;
130
+ try {
131
+ const toml = (readToml(path) ?? {});
132
+ return Boolean(toml.mcp_servers?.[brand.mcpServerKey]);
133
+ }
134
+ catch {
135
+ return false;
136
+ }
137
+ }
138
+ /**
139
+ * Alvos que já têm o servidor `nio` configurado (~/.claude/settings.json,
140
+ * ~/.codex/config.toml). Base do auto-detect de `sync`: provisiona pra cada
141
+ * cliente que o worker de fato usa, sem flags.
142
+ */
143
+ export function detectConfiguredTargets() {
144
+ const targets = [];
145
+ if (claudeConfigured())
146
+ targets.push(claudeTarget);
147
+ if (codexConfigured())
148
+ targets.push(codexTarget);
149
+ return targets;
150
+ }
151
+ //# sourceMappingURL=targets.js.map