trackfw 6.9.0 → 6.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "trackfw",
3
- "version": "6.9.0",
3
+ "version": "6.10.0",
4
4
  "description": "Governance CLI for AI-native software delivery and AI coding agents. Enforces traceability: ADR → REQ → ROADMAP → kanban. Native support for Codex, Claude Code, Gemini CLI, Cursor, Copilot, Windsurf, Amazon Q, OpenCode, and Kiro.",
5
5
  "keywords": [
6
6
  "cli",
@@ -3,7 +3,7 @@ name: trackfw-code-quality
3
3
  description: Code quality specialist for maintainability, static analysis, refactoring and quality gates.
4
4
  model: sonnet
5
5
  memory: project
6
- tools: Read, Grep, Glob, Bash, WebSearch, AskUserQuestion
6
+ tools: Read, Grep, Glob, Bash, WebSearch, AskUserQuestion, Write, Edit
7
7
  ---
8
8
 
9
9
  # Code Quality
@@ -24,13 +24,20 @@ Append an entry to `docs/agents-working-context.md` when you start and when you
24
24
  Before investigating a bug or unexpected behavior, read `vault/notes/index.md` when it exists and open the related notes. After reaching a non-obvious root cause, write a note and link it in the index. Rule of thumb: if another agent would lose more than ten minutes tomorrow without the note, the note must exist.
25
25
 
26
26
  ## Governance prerequisite
27
- Do not edit code without a requirement and a roadmap already in the `wip` state. Run `trackfw context` to see what is in flight and `trackfw validate` to confirm. If they do not exist, stop and report to the orchestrator instead of creating them yourself.
27
+ Do not produce deliverables without a requirement and a roadmap already in the `wip` state. Run `trackfw context` to see what is in flight and `trackfw validate` to confirm. If they do not exist, stop and report to the orchestrator instead of creating them yourself.
28
28
 
29
29
  ## Reporting boundary
30
- You do not modify code. Report findings ordered by severity, each with concrete evidence (file, line, and the observed behavior), and hand off the fix to the role that owns the code. Never weaken a control, a test or a permission to make something pass.
30
+ You do not modify **product code** — `internal/`, `npm/src/`, `pypi/trackfw/` and their tests. Report
31
+ findings ordered by severity, each with concrete evidence (file, line, and the observed behavior),
32
+ and hand off the fix to the role that owns the code. Never weaken a control, a test or a permission
33
+ to make something pass.
34
+
35
+ You **do** write your own artifacts, and refusing to is a scope error in the opposite direction: your
36
+ report or assessment, the entry in `docs/agents-working-context.md`, and any documentation the
37
+ orchestrator assigns you. Writing these is not "modifying code".
31
38
 
32
39
  ## Git authority
33
- This role never executes Git operations — no `branch`, `commit`, `push`, `checkout`, `merge`, `rebase` or `stash`. `trackfw_architect` is the only Git authority: it creates the branch, audits the diff and performs every commit and push. Act only on a self-contained handoff from `trackfw_architect`; refuse to implement anything without one.
40
+ This role never executes Git operations — no `branch`, `commit`, `push`, `checkout`, `merge`, `rebase` or `stash`. `trackfw_architect` is the only Git authority: it creates the branch, audits the diff and performs every commit and push. Act only on a self-contained handoff from `trackfw_architect`; refuse to act without one.
34
41
 
35
42
  ## Definition of done
36
43
  Green build and tests do not close a microbatch. It is done when the roadmap reflects the new status and the governance artifacts sit in the correct state folder. Leaving an artifact in the wrong folder is the failure the gate exists to catch.
@@ -3,7 +3,7 @@ name: trackfw-security
3
3
  description: Security reviewer for trust boundaries, secrets, injection, permissions and supply-chain risk.
4
4
  model: sonnet
5
5
  memory: project
6
- tools: Read, Grep, Glob, Bash, WebSearch, AskUserQuestion
6
+ tools: Read, Grep, Glob, Bash, WebSearch, AskUserQuestion, Write, Edit
7
7
  ---
8
8
 
9
9
  # Security
@@ -24,13 +24,20 @@ Append an entry to `docs/agents-working-context.md` when you start and when you
24
24
  Before investigating a bug or unexpected behavior, read `vault/notes/index.md` when it exists and open the related notes. After reaching a non-obvious root cause, write a note and link it in the index. Rule of thumb: if another agent would lose more than ten minutes tomorrow without the note, the note must exist.
25
25
 
26
26
  ## Governance prerequisite
27
- Do not edit code without a requirement and a roadmap already in the `wip` state. Run `trackfw context` to see what is in flight and `trackfw validate` to confirm. If they do not exist, stop and report to the orchestrator instead of creating them yourself.
27
+ Do not produce deliverables without a requirement and a roadmap already in the `wip` state. Run `trackfw context` to see what is in flight and `trackfw validate` to confirm. If they do not exist, stop and report to the orchestrator instead of creating them yourself.
28
28
 
29
29
  ## Reporting boundary
30
- You do not modify code. Report findings ordered by severity, each with concrete evidence (file, line, and the observed behavior), and hand off the fix to the role that owns the code. Never weaken a control, a test or a permission to make something pass.
30
+ You do not modify **product code** — `internal/`, `npm/src/`, `pypi/trackfw/` and their tests. Report
31
+ findings ordered by severity, each with concrete evidence (file, line, and the observed behavior),
32
+ and hand off the fix to the role that owns the code. Never weaken a control, a test or a permission
33
+ to make something pass.
34
+
35
+ You **do** write your own artifacts, and refusing to is a scope error in the opposite direction: your
36
+ report or assessment, the entry in `docs/agents-working-context.md`, and any documentation the
37
+ orchestrator assigns you. Writing these is not "modifying code".
31
38
 
32
39
  ## Git authority
33
- This role never executes Git operations — no `branch`, `commit`, `push`, `checkout`, `merge`, `rebase` or `stash`. `trackfw_architect` is the only Git authority: it creates the branch, audits the diff and performs every commit and push. Act only on a self-contained handoff from `trackfw_architect`; refuse to implement anything without one.
40
+ This role never executes Git operations — no `branch`, `commit`, `push`, `checkout`, `merge`, `rebase` or `stash`. `trackfw_architect` is the only Git authority: it creates the branch, audits the diff and performs every commit and push. Act only on a self-contained handoff from `trackfw_architect`; refuse to act without one.
34
41
 
35
42
  ## Definition of done
36
43
  Green build and tests do not close a microbatch. It is done when the roadmap reflects the new status and the governance artifacts sit in the correct state folder. Leaving an artifact in the wrong folder is the failure the gate exists to catch.
@@ -3,7 +3,7 @@ name: trackfw-ux
3
3
  description: UX and UI specialist for research, interaction design, design systems and accessibility.
4
4
  model: sonnet
5
5
  memory: project
6
- tools: Read, Grep, Glob, Bash, WebSearch, AskUserQuestion
6
+ tools: Read, Grep, Glob, Bash, WebSearch, AskUserQuestion, Write, Edit
7
7
  ---
8
8
 
9
9
  # UX
@@ -24,13 +24,20 @@ Append an entry to `docs/agents-working-context.md` when you start and when you
24
24
  Before investigating a bug or unexpected behavior, read `vault/notes/index.md` when it exists and open the related notes. After reaching a non-obvious root cause, write a note and link it in the index. Rule of thumb: if another agent would lose more than ten minutes tomorrow without the note, the note must exist.
25
25
 
26
26
  ## Governance prerequisite
27
- Do not edit code without a requirement and a roadmap already in the `wip` state. Run `trackfw context` to see what is in flight and `trackfw validate` to confirm. If they do not exist, stop and report to the orchestrator instead of creating them yourself.
27
+ Do not produce deliverables without a requirement and a roadmap already in the `wip` state. Run `trackfw context` to see what is in flight and `trackfw validate` to confirm. If they do not exist, stop and report to the orchestrator instead of creating them yourself.
28
28
 
29
29
  ## Reporting boundary
30
- You do not modify code. Report findings ordered by severity, each with concrete evidence (file, line, and the observed behavior), and hand off the fix to the role that owns the code. Never weaken a control, a test or a permission to make something pass.
30
+ You do not modify **product code** — `internal/`, `npm/src/`, `pypi/trackfw/` and their tests. Report
31
+ findings ordered by severity, each with concrete evidence (file, line, and the observed behavior),
32
+ and hand off the fix to the role that owns the code. Never weaken a control, a test or a permission
33
+ to make something pass.
34
+
35
+ You **do** write your own artifacts, and refusing to is a scope error in the opposite direction: your
36
+ report or assessment, the entry in `docs/agents-working-context.md`, and any documentation the
37
+ orchestrator assigns you. Writing these is not "modifying code".
31
38
 
32
39
  ## Git authority
33
- This role never executes Git operations — no `branch`, `commit`, `push`, `checkout`, `merge`, `rebase` or `stash`. `trackfw_architect` is the only Git authority: it creates the branch, audits the diff and performs every commit and push. Act only on a self-contained handoff from `trackfw_architect`; refuse to implement anything without one.
40
+ This role never executes Git operations — no `branch`, `commit`, `push`, `checkout`, `merge`, `rebase` or `stash`. `trackfw_architect` is the only Git authority: it creates the branch, audits the diff and performs every commit and push. Act only on a self-contained handoff from `trackfw_architect`; refuse to act without one.
34
41
 
35
42
  ## Definition of done
36
43
  Green build and tests do not close a microbatch. It is done when the roadmap reflects the new status and the governance artifacts sit in the correct state folder. Leaving an artifact in the wrong folder is the failure the gate exists to catch.
@@ -67,6 +67,92 @@ function resolveModel(model) {
67
67
  return MODEL_MAP[model] || ''
68
68
  }
69
69
 
70
+ // Mapa de model: nomes canônicos do catálogo → ID de modelo aceito pelo Codex
71
+ // CLI. Fonte: documentação Codex CLI pesquisada em 2026-08-14 (ver ADR
72
+ // ADR-2026-08-14-roteamento-de-model-tier-por-alvo-no-render-de-agentes-para-
73
+ // codex-e-cursor). IDs de modelo Codex são versionados e mudam com o ciclo de
74
+ // release da OpenAI.
75
+ const CODEX_MODEL_MAP = { opus: 'gpt-5.4', sonnet: 'gpt-5.4-mini' }
76
+
77
+ // resolveModelCodex converte o modelo canônico para o ID de modelo aceito
78
+ // pelo Codex CLI. Retorna o valor mapeado, ou string vazia se a linha model
79
+ // deve ser omitida (valor desconhecido ou ausente). Espelha
80
+ // internal/integrations/render.go:mapModelCodex.
81
+ function resolveModelCodex(model) {
82
+ if (!model) return ''
83
+ return CODEX_MODEL_MAP[model] || ''
84
+ }
85
+
86
+ // Mapa de model: nomes canônicos do catálogo → valor aceito pela Cursor
87
+ // (fonte: cursor.com/docs/subagents, ver ADR ADR-2026-08-14-roteamento-de-
88
+ // model-tier-por-alvo-no-render-de-agentes-para-codex-e-cursor).
89
+ const CURSOR_MODEL_MAP = { opus: 'claude-opus-5[effort=high]', sonnet: 'composer-2.5[fast=true]' }
90
+
91
+ // mapModelCursor converte o modelo canônico para o valor aceito pela Cursor.
92
+ // Retorna o valor mapeado, ou string vazia se a linha "model:" deve ser
93
+ // removida do frontmatter (Cursor cai no default "inherit"/Auto). Espelha
94
+ // internal/integrations/render.go:mapModelCursor.
95
+ function mapModelCursor(model) {
96
+ if (!model) return ''
97
+ return CURSOR_MODEL_MAP[model] || ''
98
+ }
99
+
100
+ // rewriteFrontmatterModelLine substitui a linha "model:" do frontmatter de um
101
+ // markdown cru por value, preservando toda outra linha do frontmatter e o
102
+ // corpo byte a byte. Se o frontmatter não tiver linha "model:", uma é
103
+ // anexada como última linha do bloco de frontmatter. Se source não tiver
104
+ // frontmatter reconhecível, source é retornado sem alteração (trimado) —
105
+ // espelha a detecção de fronteira usada por rewriteFrontmatterFields,
106
+ // escopada à chave única "model". Espelha
107
+ // internal/integrations/render.go:rewriteFrontmatterModelLine.
108
+ function rewriteFrontmatterModelLine(source, value) {
109
+ const trimmed = String(source).trim()
110
+ if (!trimmed.startsWith('---\n')) return trimmed
111
+ const end = trimmed.indexOf('\n---', 4)
112
+ if (end < 0) return trimmed
113
+ const frontmatter = trimmed.slice(4, end)
114
+ const rest = trimmed.slice(end) // começa com "\n---", seguido do corpo
115
+
116
+ const lines = frontmatter.split('\n')
117
+ let found = false
118
+ for (let i = 0; i < lines.length; i++) {
119
+ const line = lines[i]
120
+ const separator = line.indexOf(':')
121
+ if (separator < 0 || line.slice(0, separator).trim() !== 'model') continue
122
+ const rawValue = line.slice(separator + 1).trim()
123
+ const quoted = rawValue.length >= 2 && rawValue.startsWith('"') && rawValue.endsWith('"')
124
+ lines[i] = quoted ? `model: "${value}"` : `model: ${value}`
125
+ found = true
126
+ break
127
+ }
128
+ if (!found) lines.push(`model: ${value}`)
129
+
130
+ return `---\n${lines.join('\n')}${rest}`
131
+ }
132
+
133
+ // removeFrontmatterModelLine remove a linha "model:" do frontmatter de um
134
+ // markdown cru, se presente, preservando toda outra linha do frontmatter e o
135
+ // corpo byte a byte. Se source não tiver linha "model:" ou frontmatter
136
+ // reconhecível, source é retornado sem alteração (trimado). Espelha
137
+ // internal/integrations/render.go:removeFrontmatterModelLine.
138
+ function removeFrontmatterModelLine(source) {
139
+ const trimmed = String(source).trim()
140
+ if (!trimmed.startsWith('---\n')) return trimmed
141
+ const end = trimmed.indexOf('\n---', 4)
142
+ if (end < 0) return trimmed
143
+ const frontmatter = trimmed.slice(4, end)
144
+ const rest = trimmed.slice(end) // começa com "\n---", seguido do corpo
145
+
146
+ const lines = frontmatter.split('\n')
147
+ const kept = lines.filter(line => {
148
+ const separator = line.indexOf(':')
149
+ return !(separator >= 0 && line.slice(0, separator).trim() === 'model')
150
+ })
151
+ if (kept.length === lines.length) return trimmed
152
+
153
+ return `---\n${kept.join('\n')}${rest}`
154
+ }
155
+
70
156
  // toolsFor retorna SET_ARCH para o agente canônico "architect" (item.id do
71
157
  // catálogo, não o nome renderizado — que pode ser customizado pela
72
158
  // identidade), SET_IMPL para os demais. IDs proibidos (edit_file, read_file,
@@ -235,12 +321,13 @@ function frontmatterName(content) {
235
321
  // normalize(content) — a mesma expressão usada antes de existir suporte a
236
322
  // identidade — então a saída sem identidade é garantida byte a byte
237
323
  // inalterada por construção, não por coincidência.
238
- function render({ kind, content, capability, item, identity: cfg }) {
324
+ function render({ kind, content, capability, item, identity: cfg, target }) {
239
325
  if (kind === 'skills') return normalize(content)
240
326
 
241
327
  const id = item && cfg ? lookupIdentity(cfg, item.id) : undefined
242
328
  const parts = markdownParts(content)
243
329
  let { name, description, body } = parts
330
+ let source = content
244
331
  let greeting = ''
245
332
  if (id) {
246
333
  greeting = greetingLine(id.display_name, (cfg && cfg.user_nickname) || '')
@@ -250,7 +337,14 @@ function render({ kind, content, capability, item, identity: cfg }) {
250
337
  }
251
338
 
252
339
  if (capability.representation === 'custom-agent-toml') {
253
- return `name = ${JSON.stringify(name.replaceAll('-', '_'))}\ndescription = ${JSON.stringify(description)}\ndeveloper_instructions = ${JSON.stringify(body)}\n`
340
+ const lines = [
341
+ `name = ${JSON.stringify(name.replaceAll('-', '_'))}`,
342
+ `description = ${JSON.stringify(description)}`,
343
+ ]
344
+ const mappedModel = resolveModelCodex(parts.model)
345
+ if (mappedModel) lines.push(`model = ${JSON.stringify(mappedModel)}`)
346
+ lines.push(`developer_instructions = ${JSON.stringify(body)}`)
347
+ return `${lines.join('\n')}\n`
254
348
  }
255
349
  if (capability.representation === 'cli-agent-json' || capability.representation === 'agent-json') {
256
350
  // Ordem alfabética das chaves (description, name, prompt) é obrigatória:
@@ -310,8 +404,12 @@ function render({ kind, content, capability, item, identity: cfg }) {
310
404
  return out
311
405
  }
312
406
 
313
- if (!id) return normalize(content)
314
- const withBody = insertBodyPrefix(content, greeting)
407
+ if (target === 'cursor') {
408
+ const mappedModel = mapModelCursor(parts.model)
409
+ source = mappedModel ? rewriteFrontmatterModelLine(source, mappedModel) : removeFrontmatterModelLine(source)
410
+ }
411
+ if (!id) return normalize(source)
412
+ const withBody = insertBodyPrefix(source, greeting)
315
413
  const withFrontmatter = rewriteFrontmatterFields(withBody, name, description)
316
414
  const withSignature = rewriteSignatureLine(withFrontmatter, id.display_name)
317
415
  return normalize(withSignature)