@pathbit/agentdevkit 0.0.6 → 0.0.7
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/.pbai4devs/scripts/lib/gitignore.mjs +61 -13
- package/.pbai4devs/scripts/sincronizar-agentes/tests/LOCAL_IGNORE.mjs +66 -0
- package/CHANGELOG.md +7 -0
- package/README.en.md +2 -2
- package/README.es.md +2 -2
- package/README.md +2 -2
- package/docs/guides/installation.md +11 -2
- package/docs/maintainers/packages.md +1 -1
- package/docs/product/roadmap.md +2 -0
- package/docs/specs/README.md +1 -0
- package/docs/specs/v0.0.7/README.md +10 -0
- package/docs/specs/v0.0.7/SPEC.md +59 -0
- package/package.json +3 -2
|
@@ -114,6 +114,52 @@ function rootProbes(root, roots) {
|
|
|
114
114
|
return roots.filter(path => { const item = localStat(join(root, path)); return !item || item.isDirectory(); }).map(path => `${path}/.agentdevkit-ignore-probe`);
|
|
115
115
|
}
|
|
116
116
|
|
|
117
|
+
function artifactPolicy(templateFile) {
|
|
118
|
+
const adjacent = join(dirname(templateFile), 'agents.ignore');
|
|
119
|
+
const source = checkedLocalPath(localStat(adjacent) ? adjacent : fileURLToPath(new URL('../../templates/gitignore/agents.ignore', import.meta.url)));
|
|
120
|
+
const content = readFileSync(source, 'utf8');
|
|
121
|
+
const section = content.split(/^## Resultados e arquivos temporarios\r?$/m)[1]?.split(/^## /m)[0];
|
|
122
|
+
const patterns = section?.split(/\r?\n/).map(line => line.trim()).filter(line => line && !line.startsWith('#'));
|
|
123
|
+
if (!patterns?.length || patterns.some(pattern => !pattern.startsWith('**/') || /[!\\\x00-\x1f]/.test(pattern) || pattern.split('/').includes('..'))) throw new Error('Secao de artefatos invalida em agents.ignore.');
|
|
124
|
+
return patterns;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
function artifactProbes(root, patterns) {
|
|
128
|
+
const probes = new Set();
|
|
129
|
+
for (const pattern of patterns) {
|
|
130
|
+
const stem = pattern.slice(3).replace(/\/$/, '').replace(/\[([^\]]+)\]/g, (_match, letters) => letters[0]).replace(/\?/g, 'x');
|
|
131
|
+
const names = stem.includes('*') ? ['', '-mcp', '-report', '-cache', '-agentdevkit'].map(suffix => stem.replace(/\*/g, suffix)) : [stem];
|
|
132
|
+
for (const name of names) for (const variant of new Set([name, name.toLowerCase()])) {
|
|
133
|
+
const leaves = stem.includes('*') ? ['.agentdevkit-artifact-probe', '.cache/.agentdevkit-artifact-probe'] : ['.agentdevkit-artifact-probe'];
|
|
134
|
+
for (const leaf of leaves) for (const path of [`${variant}/${leaf}`, `.agentdevkit-ignore-probes/${variant}/${leaf}`]) {
|
|
135
|
+
let parent = root, safe = true;
|
|
136
|
+
for (const part of path.split('/').slice(0, -1)) {
|
|
137
|
+
parent = join(parent, part); const item = localStat(parent);
|
|
138
|
+
if (item && !item.isDirectory()) { safe = false; break; }
|
|
139
|
+
}
|
|
140
|
+
if (safe) probes.add(path);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
return [...probes];
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
function localIgnoreSource(location, source) {
|
|
148
|
+
const path = resolve(location.top, source);
|
|
149
|
+
if (path === location.exclude) return true;
|
|
150
|
+
const inside = relative(location.top, path);
|
|
151
|
+
return basename(path) === '.gitignore' && !isAbsolute(inside) && inside !== '..' && !inside.startsWith(`..${sep}`);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
function ignoreMatches(location, probes) {
|
|
155
|
+
const paths = probes.map(path => location.prefix ? `${location.prefix}/${path}` : path);
|
|
156
|
+
const result = gitCommand(location.top, ['-c', 'core.excludesFile=', 'check-ignore', '--verbose', '--no-index', '--stdin', '-z'], paths.join('\0') + '\0');
|
|
157
|
+
if (result.error || ![0, 1].includes(result.status)) throw new Error(result.error?.message || result.stderr || 'Falha ao conferir exclusoes Git.');
|
|
158
|
+
const values = result.stdout.split('\0'), matches = new Map();
|
|
159
|
+
for (let index = 0; index + 3 < values.length; index += 4) matches.set(values[index + 3], { source: values[index], line: Number(values[index + 1]), pattern: values[index + 2] });
|
|
160
|
+
return { paths, matches };
|
|
161
|
+
}
|
|
162
|
+
|
|
117
163
|
function localRoot(value) {
|
|
118
164
|
const missing = []; let parent = resolve(value);
|
|
119
165
|
while (!localStat(parent)) { missing.unshift(parent.slice(dirname(parent).length + 1)); parent = dirname(parent); }
|
|
@@ -128,6 +174,7 @@ export function planLocalIgnore(root, { outputs = [], templateRoot } = {}) {
|
|
|
128
174
|
const localTemplate = join(root, '.pbai4devs/templates/gitignore/local.ignore');
|
|
129
175
|
const templateFile = checkedLocalPath(templateRoot ? join(templateRoot, '.pbai4devs/templates/gitignore/local.ignore') : localStat(localTemplate) ? localTemplate : fileURLToPath(new URL('../../templates/gitignore/local.ignore', import.meta.url)));
|
|
130
176
|
const template = readFileSync(templateFile, 'utf8');
|
|
177
|
+
const artifacts = artifactPolicy(templateFile);
|
|
131
178
|
if (template.split('{{OUTPUTS}}').length !== 2) throw new Error('local.ignore exige um unico {{OUTPUTS}}.');
|
|
132
179
|
if (template.split('{{ROOTS}}').length > 2) throw new Error('local.ignore permite um unico {{ROOTS}}.');
|
|
133
180
|
const localPolicy = join(templateRoot || root, '.pbai4devs/templates/clients/ADAPTERS.json');
|
|
@@ -152,16 +199,18 @@ export function planLocalIgnore(root, { outputs = [], templateRoot } = {}) {
|
|
|
152
199
|
}
|
|
153
200
|
const id = createHash('sha256').update(root).digest('hex').slice(0, 16);
|
|
154
201
|
const first = `# BEGIN AGENTDEVKIT LOCAL ${id}`, last = `# END AGENTDEVKIT LOCAL ${id}`;
|
|
155
|
-
const fixed = template.replace('{{ROOTS}}', roots.map(path => `/${path}/`).join('\n')).replace('{{OUTPUTS}}', paths.filter(path => !roots.some(root => path === root || path.startsWith(root + '/'))).map(path => `/${escapePattern(path)}`).join('\n'))
|
|
202
|
+
const fixed = template.replace('{{ROOTS}}', roots.map(path => `/${path}/`).join('\n')).replace('{{OUTPUTS}}', paths.filter(path => !roots.some(root => path === root || path.startsWith(root + '/'))).map(path => `/${escapePattern(path)}`).join('\n'))
|
|
203
|
+
+ '\n# Resultados e arquivos temporarios\n' + artifacts.map(pattern => `/${pattern}`).join('\n') + '\n';
|
|
156
204
|
const body = fixed.split(/\r?\n/).map(line => location?.prefix && line.startsWith('/') ? `/${escapePattern(location.prefix)}${line}` : line).join('\n');
|
|
157
205
|
const target = location?.exclude ?? checkedLocalPath(join(root, '.gitignore'));
|
|
158
206
|
const before = localRead(target), after = localBlock(before, first, last, body);
|
|
159
207
|
const edits = before === after ? [] : [{ path: target, before, after }];
|
|
160
208
|
const probes = [...paths, ...rootProbes(root, roots)];
|
|
209
|
+
const artifactPaths = artifactProbes(root, artifacts);
|
|
161
210
|
const wanted = new Set(probes.map(path => location?.prefix ? `${location.prefix}/${path}` : path));
|
|
162
211
|
if (location && !before?.includes(first) && !localRead(join(root, '.gitignore'))?.includes(first)) {
|
|
163
|
-
const ignored =
|
|
164
|
-
if (
|
|
212
|
+
const ignored = ignoreMatches(location, [...probes, ...artifactPaths]);
|
|
213
|
+
if (ignored.paths.every(path => { const match = ignored.matches.get(path); return match && !match.pattern.startsWith('!') && localIgnoreSource(location, match.source); })) edits.length = 0;
|
|
165
214
|
}
|
|
166
215
|
if (location) {
|
|
167
216
|
const fallback = checkedLocalPath(join(root, '.gitignore'));
|
|
@@ -169,7 +218,7 @@ export function planLocalIgnore(root, { outputs = [], templateRoot } = {}) {
|
|
|
169
218
|
if (old !== null && old !== next) edits.push({ path: fallback, before: old, after: next });
|
|
170
219
|
}
|
|
171
220
|
const tracked = location ? gitCommand(location.top, ['ls-files', '-z']).stdout.split('\0').filter(path => wanted.has(path)).map(path => location.prefix ? path.slice(location.prefix.length + 1) : path) : [];
|
|
172
|
-
return { root, status: location ? 'git' : 'fallback', location, paths, roots, edits, trackedOutputs: tracked, first, last };
|
|
221
|
+
return { root, status: location ? 'git' : 'fallback', location, paths, roots, artifactProbes: artifactPaths, edits, trackedOutputs: tracked, first, last };
|
|
173
222
|
}
|
|
174
223
|
|
|
175
224
|
export function checkLocalIgnore(plan, { replacedBlocks = [] } = {}) {
|
|
@@ -185,19 +234,16 @@ export function checkLocalIgnore(plan, { replacedBlocks = [] } = {}) {
|
|
|
185
234
|
if (createHash('sha256').update(block).digest('hex') !== item.sha256) throw new Error('Bloco de ignore mudou antes da verificacao.');
|
|
186
235
|
return { ...item, path };
|
|
187
236
|
});
|
|
188
|
-
if (plan.location && plan.paths.length) {
|
|
189
|
-
const probes = [...plan.paths, ...rootProbes(plan.root, plan.roots || [])];
|
|
190
|
-
const
|
|
191
|
-
const result = gitCommand(plan.location.top, ['check-ignore', '--verbose', '--no-index', '--stdin', '-z'], relativePaths.join('\0') + '\0');
|
|
192
|
-
if (result.error || ![0, 1].includes(result.status)) throw new Error(result.error?.message || result.stderr || 'Falha ao conferir exclusoes Git.');
|
|
193
|
-
const values = result.stdout.split('\0'), matches = new Map();
|
|
194
|
-
for (let index = 0; index + 3 < values.length; index += 4) matches.set(values[index + 3], { source: values[index], line: Number(values[index + 1]), pattern: values[index + 2] });
|
|
237
|
+
if (plan.location && (plan.paths.length || plan.artifactProbes?.length)) {
|
|
238
|
+
const probes = [...plan.paths, ...rootProbes(plan.root, plan.roots || []), ...(plan.artifactProbes || [])];
|
|
239
|
+
const { paths: relativePaths, matches } = ignoreMatches(plan.location, probes);
|
|
195
240
|
for (let index = 0; index < relativePaths.length; index++) {
|
|
196
241
|
const match = matches.get(relativePaths[index]);
|
|
197
242
|
const negative = match?.pattern.startsWith('!');
|
|
198
|
-
const
|
|
243
|
+
const local = match && localIgnoreSource(plan.location, match.source);
|
|
244
|
+
const humanOverride = negative && local && /(?:^|[\\/])\.gitignore$/.test(match.source);
|
|
199
245
|
const replaced = negative && replacements.some(item => item.path === canonicalExisting(resolve(plan.location.top, match.source)) && match.line >= item.firstLine && match.line <= item.lastLine);
|
|
200
|
-
if (!replaced && ((!plan.edits.length && (!match || negative)) || humanOverride)) missing.push(probes[index]);
|
|
246
|
+
if (!replaced && ((!plan.edits.length && (!match || negative || !local)) || humanOverride)) missing.push(probes[index]);
|
|
201
247
|
}
|
|
202
248
|
}
|
|
203
249
|
return { ok: plan.edits.length === 0 && missing.length === 0 && plan.trackedOutputs.length === 0, status: plan.status, missing, trackedOutputs: plan.trackedOutputs, changed: plan.edits.length };
|
|
@@ -212,6 +258,8 @@ export function assertLocalIgnoreUnchanged(plan) {
|
|
|
212
258
|
|
|
213
259
|
export function applyLocalIgnore(plan) {
|
|
214
260
|
assertLocalIgnoreUnchanged(plan);
|
|
261
|
+
const before = checkLocalIgnore(plan);
|
|
262
|
+
if (before.missing.length) throw new Error(`Regras humanas reabrem derivados locais: ${before.missing.join(', ')}`);
|
|
215
263
|
const written = [];
|
|
216
264
|
try {
|
|
217
265
|
for (const edit of plan.edits) {
|
|
@@ -129,6 +129,72 @@ test('raízes dedicadas são locais, enquanto configurações de GitHub e VS Cod
|
|
|
129
129
|
assert.ok(tracked.includes('.github/settings.json')); assert.ok(tracked.includes('.vscode/settings.json'));
|
|
130
130
|
});
|
|
131
131
|
|
|
132
|
+
test('artefatos vêm da política compartilhada e não entram na lista de outputs', t => {
|
|
133
|
+
const root = fixture(t); git(root, ['init', '-q']);
|
|
134
|
+
put(root, '.agent-tests/human.txt', 'evidência humana'); git(root, ['add', '-f', '.agent-tests/human.txt']);
|
|
135
|
+
const plan = planLocalIgnore(root, { outputs: ['AGENTS.md'] });
|
|
136
|
+
assert.ok(plan.artifactProbes.some(path => path.startsWith('.agent-tests/')));
|
|
137
|
+
assert.ok(plan.artifactProbes.some(path => path.startsWith('.agentdevkit-ignore-probes/')));
|
|
138
|
+
assert.ok(plan.paths.every(path => !plan.artifactProbes.includes(path)));
|
|
139
|
+
assert.ok(!plan.trackedOutputs.includes('.agent-tests/human.txt'));
|
|
140
|
+
applyLocalIgnore(plan);
|
|
141
|
+
for (const path of ['.agent-tests/x', 'TMP/x', 'nested/TeMp/x', '.PlAyWrIgHt-McP/x', 'nested/playwright-report/x', 'TEST-RESULTS/x', 'nested/TestResults/x', 'BLOB-REPORT/x']) {
|
|
142
|
+
assert.equal(git(root, ['check-ignore', '--no-index', path]).trim(), path);
|
|
143
|
+
}
|
|
144
|
+
assert.equal(git(root, ['ls-files', '.agent-tests/human.txt']).trim(), '.agent-tests/human.txt');
|
|
145
|
+
assert.equal(readFileSync(join(root, '.agent-tests/human.txt'), 'utf8'), 'evidência humana');
|
|
146
|
+
assert.equal(checkLocalIgnore(planLocalIgnore(root, { outputs: ['AGENTS.md'] })).ok, true);
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
test('regras de artefatos são limitadas ao projeto dentro do monorepo', t => {
|
|
150
|
+
const root = fixture(t); git(root, ['init', '-q']);
|
|
151
|
+
const child = join(root, 'apps', 'my project'); mkdirSync(child, { recursive: true });
|
|
152
|
+
applyLocalIgnore(planLocalIgnore(child, { outputs: ['AGENTS.md'] }));
|
|
153
|
+
for (const path of ['apps/my project/.agent-tests/x', 'apps/my project/nested/.Playwright-MCP/x', 'apps/my project/sub/test-results/x']) {
|
|
154
|
+
assert.equal(git(root, ['check-ignore', '--no-index', path]).trim(), path);
|
|
155
|
+
}
|
|
156
|
+
for (const path of ['apps/other/.agent-tests/x', 'apps/other/tmp/x', '.agent-tests/x']) {
|
|
157
|
+
const result = spawnSync('git', ['-C', root, 'check-ignore', '--no-index', path], { encoding: 'utf8' });
|
|
158
|
+
assert.equal(result.status, 1, path + result.stderr);
|
|
159
|
+
}
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
test('ignore global não mascara a ausência das regras locais de artefatos', t => {
|
|
163
|
+
const root = fixture(t), outside = fixture(t); git(root, ['init', '-q']);
|
|
164
|
+
put(outside, 'global.ignore', '*\n');
|
|
165
|
+
git(root, ['config', 'core.excludesFile', join(outside, 'global.ignore')]);
|
|
166
|
+
const plan = planLocalIgnore(root, { outputs: ['AGENTS.md'] });
|
|
167
|
+
assert.equal(plan.edits.length, 1);
|
|
168
|
+
const missing = checkLocalIgnore({ ...plan, edits: [] });
|
|
169
|
+
assert.ok(missing.missing.some(path => path.startsWith('.agent-tests/')));
|
|
170
|
+
applyLocalIgnore(plan);
|
|
171
|
+
assert.equal(checkLocalIgnore(planLocalIgnore(root, { outputs: ['AGENTS.md'] })).ok, true);
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
test('negação humana de artefatos bloqueia aplicação sem modificar regras ou índice', t => {
|
|
175
|
+
const root = fixture(t); git(root, ['init', '-q']);
|
|
176
|
+
const human = '!/.agent-tests/**\n'; put(root, '.gitignore', human);
|
|
177
|
+
const exclude = readFileSync(join(root, '.git/info/exclude'));
|
|
178
|
+
const plan = planLocalIgnore(root, { outputs: ['AGENTS.md'] });
|
|
179
|
+
assert.ok(checkLocalIgnore(plan).missing.some(path => path.startsWith('.agent-tests/')));
|
|
180
|
+
assert.throws(() => applyLocalIgnore(plan), /Regras humanas/);
|
|
181
|
+
assert.deepEqual(readFileSync(join(root, '.git/info/exclude')), exclude);
|
|
182
|
+
assert.equal(readFileSync(join(root, '.gitignore'), 'utf8'), human);
|
|
183
|
+
});
|
|
184
|
+
|
|
185
|
+
test('probes reconhecem exceções humanas para nomes reais de Playwright', async t => {
|
|
186
|
+
for (const path of ['.playwright-mcp', 'playwright-report', 'playwright/.cache']) await t.test(path, subtest => {
|
|
187
|
+
const root = fixture(subtest); git(root, ['init', '-q']);
|
|
188
|
+
const prefixes = path.split('/').map((_part, index, parts) => '!/' + parts.slice(0, index + 1).join('/') + '/');
|
|
189
|
+
const human = [...prefixes, `!/${path}/**`, ''].join('\n'); put(root, '.gitignore', human);
|
|
190
|
+
const before = readFileSync(join(root, '.git/info/exclude'));
|
|
191
|
+
const plan = planLocalIgnore(root, { outputs: ['AGENTS.md'] });
|
|
192
|
+
assert.ok(checkLocalIgnore(plan).missing.some(probe => probe.startsWith(path + '/')));
|
|
193
|
+
assert.throws(() => applyLocalIgnore(plan), /Regras humanas/);
|
|
194
|
+
assert.deepEqual(readFileSync(join(root, '.git/info/exclude')), before);
|
|
195
|
+
});
|
|
196
|
+
});
|
|
197
|
+
|
|
132
198
|
test('milhares de caminhos usam stdin e não ampliam metadata de área já ignorada', t => {
|
|
133
199
|
const root = fixture(t); git(root, ['init', '-q']); put(root, '.gitignore', '/ignored/\n');
|
|
134
200
|
const before = readFileSync(join(root, '.git/info/exclude'), 'utf8');
|
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,13 @@ description: Alterações verificáveis por versão do AgentDevKit.
|
|
|
4
4
|
|
|
5
5
|
# Changelog
|
|
6
6
|
|
|
7
|
+
## 0.0.7 — 2026-11-11
|
|
8
|
+
|
|
9
|
+
- Artefatos de testes e pastas temporárias protegidos em projetos existentes.
|
|
10
|
+
- Regras locais respeitam o escopo do projeto e as exceções do usuário.
|
|
11
|
+
- Teste opt-in em clones reais, com commits fixos e comparação de arquivos.
|
|
12
|
+
- Relato explícito de bloqueios por links simbólicos preexistentes.
|
|
13
|
+
|
|
7
14
|
## 0.0.6 — 2026-11-11
|
|
8
15
|
|
|
9
16
|
- Metadados npm com autoria PathBit, palavras-chave e licença MIT.
|
package/README.en.md
CHANGED
|
@@ -34,7 +34,7 @@ Then open the project in your coding agent and ask:
|
|
|
34
34
|
|
|
35
35
|
See [installation](docs/guides/installation.md) for Windows, missing Node, previews
|
|
36
36
|
and updates. Install and update through the [public npm package][packages]; the
|
|
37
|
-
[v0.0.
|
|
37
|
+
[v0.0.7 release][release] retains artifacts and checksums for verification.
|
|
38
38
|
No global installation is required.
|
|
39
39
|
The CLI supports `pt`, `en` and `es`; it saves your selection per project.
|
|
40
40
|
|
|
@@ -78,7 +78,7 @@ forms. See [how to participate](docs/maintainers/community.md).
|
|
|
78
78
|
agent to read `AGENTS.md`.
|
|
79
79
|
|
|
80
80
|
[clients]: .pbai4devs/COMPATIBILIDADE.md
|
|
81
|
-
[release]: https://github.com/pathbit/AgentDevKit/releases/tag/v0.0.
|
|
81
|
+
[release]: https://github.com/pathbit/AgentDevKit/releases/tag/v0.0.7
|
|
82
82
|
[npm-package]: https://www.npmjs.com/package/@pathbit/agentdevkit
|
|
83
83
|
[npm-badge]: https://img.shields.io/npm/v/%40pathbit%2Fagentdevkit
|
|
84
84
|
[license-badge]: https://img.shields.io/badge/license-MIT-blue
|
package/README.es.md
CHANGED
|
@@ -35,7 +35,7 @@ Después, abre el proyecto en tu agente y pide:
|
|
|
35
35
|
La [guía de instalación](docs/guides/installation.md) incluye Windows, Node ausente,
|
|
36
36
|
simulación y actualización. Instala y actualiza mediante el
|
|
37
37
|
[paquete npm público][packages];
|
|
38
|
-
la [release v0.0.
|
|
38
|
+
la [release v0.0.7][release] conserva artefactos y checksums para verificarlos.
|
|
39
39
|
No requiere instalación global.
|
|
40
40
|
La CLI guarda el idioma `pt`, `en` o `es` por proyecto.
|
|
41
41
|
|
|
@@ -80,7 +80,7 @@ formularios. Consulta [cómo participar](docs/maintainers/community.md).
|
|
|
80
80
|
al agente que lea `AGENTS.md`.
|
|
81
81
|
|
|
82
82
|
[clients]: .pbai4devs/COMPATIBILIDADE.md
|
|
83
|
-
[release]: https://github.com/pathbit/AgentDevKit/releases/tag/v0.0.
|
|
83
|
+
[release]: https://github.com/pathbit/AgentDevKit/releases/tag/v0.0.7
|
|
84
84
|
[npm-package]: https://www.npmjs.com/package/@pathbit/agentdevkit
|
|
85
85
|
[npm-badge]: https://img.shields.io/npm/v/%40pathbit%2Fagentdevkit
|
|
86
86
|
[license-badge]: https://img.shields.io/badge/license-MIT-blue
|
package/README.md
CHANGED
|
@@ -32,7 +32,7 @@ Depois, abra o projeto no seu agente e peça:
|
|
|
32
32
|
|
|
33
33
|
Windows, instalação sem Node, simulação e atualização estão no
|
|
34
34
|
[guia de instalação](https://github.com/pathbit/AgentDevKit/blob/master/docs/guides/installation.md). A distribuição usa a
|
|
35
|
-
versão publicada no [npm público][packages] e na [release v0.0.
|
|
35
|
+
versão publicada no [npm público][packages] e na [release v0.0.7][release],
|
|
36
36
|
sem instalação global. Instalação e atualização usam o pacote do registro;
|
|
37
37
|
os arquivos da release servem para conferir os artefatos publicados.
|
|
38
38
|
O idioma da CLI pode ser `pt`, `en` ou `es`.
|
|
@@ -89,7 +89,7 @@ ao seu agente para ler `AGENTS.md`.
|
|
|
89
89
|
[help]: https://github.com/pathbit/AgentDevKit/blob/master/docs/guides/troubleshooting.md
|
|
90
90
|
[issues]: https://github.com/pathbit/AgentDevKit/issues/new/choose
|
|
91
91
|
[packages]: https://github.com/pathbit/AgentDevKit/blob/master/docs/maintainers/packages.md
|
|
92
|
-
[release]: https://github.com/pathbit/AgentDevKit/releases/tag/v0.0.
|
|
92
|
+
[release]: https://github.com/pathbit/AgentDevKit/releases/tag/v0.0.7
|
|
93
93
|
[npm-package]: https://www.npmjs.com/package/@pathbit/agentdevkit
|
|
94
94
|
[npm-badge]: https://img.shields.io/npm/v/%40pathbit%2Fagentdevkit
|
|
95
95
|
[license-badge]: https://img.shields.io/badge/license-MIT-blue
|
|
@@ -60,6 +60,11 @@ workflows, formulários de issues ou configurações humanas em `.github`.
|
|
|
60
60
|
Sem Git, uma proteção no `.gitignore` da raiz evita incluir os derivados
|
|
61
61
|
quando o repositório for iniciado.
|
|
62
62
|
|
|
63
|
+
O bloco local também protege `.agent-tests`, `tmp`, `temp`, `.playwright*`
|
|
64
|
+
e relatórios de testes, inclusive com letras maiúsculas e em subpastas.
|
|
65
|
+
O `.gitignore` existente e seus arquivos rastreados são preservados;
|
|
66
|
+
uma exceção humana que conflite com essa proteção é informada como conflito.
|
|
67
|
+
|
|
63
68
|
Arquivos já rastreados exigem migração do índice: apenas saídas identificadas
|
|
64
69
|
do kit podem deixar de ser rastreadas, preservando seus bytes no disco.
|
|
65
70
|
Revise o plano e os conflitos em um projeto existente; use `--dry-run` antes
|
|
@@ -77,10 +82,14 @@ gerenciados alterados geram conflito; use `--force` somente após revisar o
|
|
|
77
82
|
backup e o conteúdo que será substituído. Preserve os dados locais, as
|
|
78
83
|
configurações próprias e os commits do projeto.
|
|
79
84
|
|
|
85
|
+
Links simbólicos em caminhos usados pela instalação podem bloquear a operação.
|
|
86
|
+
O kit informa o caminho e não converte nem remove o link automaticamente.
|
|
87
|
+
Use a simulação para identificar esse caso antes de aplicar.
|
|
88
|
+
|
|
80
89
|
O [fluxo de trabalho](workflow.md) orienta a próxima etapa do projeto.
|
|
81
90
|
Se houver erro, consulte [solução de problemas](troubleshooting.md).
|
|
82
91
|
|
|
83
|
-
[Wiki](../README.md) · [Spec v0.0.
|
|
92
|
+
[Wiki](../README.md) · [Spec v0.0.7][spec]
|
|
84
93
|
|
|
85
94
|
[bootstrap]: ../../.pbai4devs/scripts/preparar-ferramentas/BOOTSTRAP.md
|
|
86
|
-
[spec]: ../specs/v0.0.
|
|
95
|
+
[spec]: ../specs/v0.0.7/SPEC.md
|
|
@@ -64,7 +64,7 @@ existir; a primeira publicação pode usar o secret `NPMJS_TOKEN`.
|
|
|
64
64
|
Para publicar somente o pacote de uma tag que já tem artefato aprovado:
|
|
65
65
|
|
|
66
66
|
```console
|
|
67
|
-
gh workflow run release.yml --ref master -f tag=v0.0.
|
|
67
|
+
gh workflow run release.yml --ref master -f tag=v0.0.7 -F package_only=true
|
|
68
68
|
```
|
|
69
69
|
|
|
70
70
|
Se o artefato expirou, reexecute o CI original da tag antes da publicação.
|
package/docs/product/roadmap.md
CHANGED
|
@@ -17,6 +17,7 @@ status: vigente
|
|
|
17
17
|
| Estrutura e exemplos v0.0.4 | CLI, distribuição e gerador | [Spec][layout]. |
|
|
18
18
|
| Instalação pelo registro v0.0.5 | Pacote publicado | [Spec][registry]. |
|
|
19
19
|
| Apresentação e licença v0.0.6 | Distribuição e atualização | [Spec][public]. |
|
|
20
|
+
| Compatibilidade real v0.0.7 | Testes em clones existentes | [Spec][oss]. |
|
|
20
21
|
|
|
21
22
|
A primeira entrega segue a [spec v0.0.1](../specs/v0.0.1/SPEC.md), disponível
|
|
22
23
|
na [release v0.0.1][release]. Os detalhes de mudanças estão no
|
|
@@ -36,3 +37,4 @@ comportamento existente, sem alterar a versão de uma release já publicada.
|
|
|
36
37
|
[layout]: ../specs/v0.0.4/SPEC.md
|
|
37
38
|
[registry]: ../specs/v0.0.5/SPEC.md
|
|
38
39
|
[public]: ../specs/v0.0.6/SPEC.md
|
|
40
|
+
[oss]: ../specs/v0.0.7/SPEC.md
|
package/docs/specs/README.md
CHANGED
|
@@ -11,6 +11,7 @@ description: Incrementos verificáveis do AgentDevKit.
|
|
|
11
11
|
- [v0.0.4](v0.0.4/SPEC.md): estrutura padrão e exemplos na raiz.
|
|
12
12
|
- [v0.0.5](v0.0.5/SPEC.md): instalação pelo registro em todos os fluxos.
|
|
13
13
|
- [v0.0.6](v0.0.6/SPEC.md): apresentação pública, licença e atualização segura.
|
|
14
|
+
- [v0.0.7](v0.0.7/SPEC.md): projetos reais e proteção local de artefatos.
|
|
14
15
|
|
|
15
16
|
Cada incremento vincula requisitos, critérios, testes e evidências locais.
|
|
16
17
|
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Compatibilidade do pacote com projetos open source existentes.
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# Versão 0.0.7
|
|
6
|
+
|
|
7
|
+
A [spec](SPEC.md) define testes em clones reais e a correção das exclusões
|
|
8
|
+
locais de artefatos, preservando os arquivos e as decisões dos projetos.
|
|
9
|
+
|
|
10
|
+
[Specs](../README.md)
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Testes em projetos reais e proteção de artefatos locais.
|
|
3
|
+
status: aprovado
|
|
4
|
+
version: 0.0.7
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Compatibilidade com projetos existentes
|
|
8
|
+
|
|
9
|
+
## Objetivo e autorização
|
|
10
|
+
|
|
11
|
+
Atender ao pedido de testar o pacote publicado em projetos open source com
|
|
12
|
+
conteúdo real, usando clones em `tmp/` ignorado. Corrigir a falta de proteção
|
|
13
|
+
de artefatos revelada em projetos que não tinham as regras do AgentDevKit.
|
|
14
|
+
|
|
15
|
+
O trabalho usa o [PRD](../../product/prd.md),
|
|
16
|
+
o [design](../../product/design.md) e a
|
|
17
|
+
[distribuição pública](../v0.0.6/SPEC.md). Não altera as aplicações clonadas.
|
|
18
|
+
|
|
19
|
+
## Contrato
|
|
20
|
+
|
|
21
|
+
- Clonar commits fixos de Express, Zod e Chi; preservar os projetos originais.
|
|
22
|
+
- Comparar bytes, tipos, permissões, links, HEAD e alterações staged.
|
|
23
|
+
- Verificar instalação, atualização, repetição, skill própria e conflitos.
|
|
24
|
+
- Proteger artefatos no ignore local sem reescrever o `.gitignore` do usuário
|
|
25
|
+
nem desindexar arquivos humanos. Respeitar projetos irmãos e exceções.
|
|
26
|
+
- Manter as recusas de links simbólicos. Um bloqueio seguro não comprova
|
|
27
|
+
instalação bem-sucedida; relatá-lo e verificar ausência de alterações.
|
|
28
|
+
- Versionar o teste; guardar clones, logs e resultados somente em `tmp/`.
|
|
29
|
+
- Publicar correções como nova versão estável; repetir a prova pública.
|
|
30
|
+
|
|
31
|
+
## Critérios de aceite
|
|
32
|
+
|
|
33
|
+
| ID | Resultado observável |
|
|
34
|
+
| --- | --- |
|
|
35
|
+
| AC-001 | Matriz real registra resultado e preservação por projeto. |
|
|
36
|
+
| AC-002 | Artefatos são ignorados sem alterar fontes ou projetos irmãos. |
|
|
37
|
+
| AC-003 | Regressões e revisão independente aprovam a correção. |
|
|
38
|
+
| AC-004 | Pacote estável publicado repete os resultados e atualiza o router. |
|
|
39
|
+
|
|
40
|
+
## Verificação
|
|
41
|
+
|
|
42
|
+
- **AC-001:** executar o runner contra o npm, incluindo caso staged e bloqueios;
|
|
43
|
+
registrar commits, versão e hashes. Não confundir com testes das aplicações.
|
|
44
|
+
- **AC-002:** testar Git, instalação sem Git, projeto aninhado, caixa mista,
|
|
45
|
+
exceções humanas e artefatos já rastreados. Não forçar sobrescritas.
|
|
46
|
+
- **AC-003:** executar testes do pacote, infraestrutura, lint e distribuição.
|
|
47
|
+
Comparar testes nativos do Express antes e depois, sem modificar suas fontes.
|
|
48
|
+
- **AC-004:** conferir release, `latest`, checksum e instalação anônima; repetir
|
|
49
|
+
matriz com o pacote publicado e atualizar o router com backup e diagnóstico.
|
|
50
|
+
|
|
51
|
+
Evidências dos clones ficam em `tmp/oss-compatibility/`; o relatório de revisão
|
|
52
|
+
em `.agent-tests/oss-compatibility/` referencia cópias dessas provas.
|
|
53
|
+
Zod e Chi não terão testes nativos sem os runtimes/gerenciadores exigidos.
|
|
54
|
+
Não concluir compatibilidade universal a partir desta matriz.
|
|
55
|
+
|
|
56
|
+
## Documentação afetada
|
|
57
|
+
|
|
58
|
+
Atualizar instalação, testes, changelog, índices e roadmap. Documentar a
|
|
59
|
+
proteção de artefatos locais e os limites de configurações preexistentes.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pathbit/agentdevkit",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.7",
|
|
4
4
|
"description": "Shared skills, specifications and workflows for AI coding agents.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -50,7 +50,8 @@
|
|
|
50
50
|
"pack:release": "node scripts/release/assets.mjs",
|
|
51
51
|
"ci:full": "node scripts/release/pipeline.mjs full",
|
|
52
52
|
"ci:portable": "node scripts/release/pipeline.mjs portable",
|
|
53
|
-
"ci:smoke": "node scripts/release/pipeline.mjs smoke"
|
|
53
|
+
"ci:smoke": "node scripts/release/pipeline.mjs smoke",
|
|
54
|
+
"test:oss": "node tests/oss-compatibility.mjs"
|
|
54
55
|
},
|
|
55
56
|
"author": {
|
|
56
57
|
"name": "PathBit",
|