@softize/opus 15.2.0 → 15.2.1

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 CHANGED
@@ -7,6 +7,15 @@ Depois de qualquer bump, rode os gates (`typecheck` · `test` · `opus check` ·
7
7
  `opus copy --check` · `base copy check` · `manifest:check`) — eles apontam o que a
8
8
  mudança cobra do seu código.
9
9
 
10
+ ## 15.2.1 — 2026-09-11
11
+
12
+ `opus copy` agora poda diretórios cobertos por um glob recursivo de `copy.exclude`, em vez de
13
+ percorrer toda a árvore para só então descartar seus arquivos. Isso evita custo desnecessário e
14
+ travamentos aparentes em repositórios que mantêm worktrees ou artefatos volumosos dentro da raiz.
15
+
16
+ **Migração:** nenhuma. Projetos com diretórios locais volumosos devem declará-los em
17
+ `copy.exclude` com um glob recursivo, como `.worktrees/**`.
18
+
10
19
  ## 15.2.0 — 2026-09-11
11
20
 
12
21
  Produtos de Dados passam a ser declarações de primeira classe com `defineDataProduct` e registro
package/bin/lib/copy.mjs CHANGED
@@ -2146,6 +2146,14 @@ function globRegex(pattern) {
2146
2146
  function sourceFiles(root, excluded = []) {
2147
2147
  const output = []
2148
2148
  const diagnostics = []
2149
+ const excludedPatterns = excluded.map((pattern) => ({
2150
+ regex: globRegex(pattern),
2151
+ subtree: pattern.endsWith('/**') ? globRegex(pattern.slice(0, -3)) : null,
2152
+ }))
2153
+ const isExcluded = (source) => excludedPatterns.some(({ regex }) => regex.test(source))
2154
+ const isExcludedDirectory = (source) => excludedPatterns.some(({ regex, subtree }) =>
2155
+ regex.test(source) || subtree?.test(source),
2156
+ )
2149
2157
  const walk = (directory = '.') => {
2150
2158
  let listing
2151
2159
  try {
@@ -2162,8 +2170,9 @@ function sourceFiles(root, excluded = []) {
2162
2170
  const target = path.join(directory, item.name)
2163
2171
  const source = portable(target === '.' ? item.name : target)
2164
2172
  if (IGNORED_DIRECTORIES.has(item.name)) continue
2173
+ if (item.isDirectory() && isExcludedDirectory(source)) continue
2165
2174
  if (item.isSymbolicLink()) {
2166
- if (!excluded.some((pattern) => globRegex(pattern).test(source))) {
2175
+ if (!isExcluded(source) && !isExcludedDirectory(source)) {
2167
2176
  diagnostics.push({
2168
2177
  source,
2169
2178
  line: 1,
@@ -2189,7 +2198,7 @@ function sourceFiles(root, excluded = []) {
2189
2198
  item.isFile() &&
2190
2199
  SOURCE_EXTENSIONS.has(path.extname(item.name)) &&
2191
2200
  !IGNORED_FILE.test(item.name) &&
2192
- !excluded.some((pattern) => globRegex(pattern).test(source))
2201
+ !isExcluded(source)
2193
2202
  ) {
2194
2203
  try {
2195
2204
  const inspected = safeProjectPath(root, target, { mustExist: true })
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@softize/opus",
3
- "version": "15.2.0",
3
+ "version": "15.2.1",
4
4
  "description": "End-to-end action protocol for TypeScript. Single package with subpath exports (core + adapters).",
5
5
  "license": "MIT",
6
6
  "type": "module",