@softize/opus 8.6.6 → 8.6.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.
Files changed (2) hide show
  1. package/bin/lib/init.mjs +45 -3
  2. package/package.json +14 -13
package/bin/lib/init.mjs CHANGED
@@ -12,6 +12,7 @@
12
12
 
13
13
  import { promises as fs } from "node:fs";
14
14
  import path from "node:path";
15
+ import { execFileSync } from "node:child_process";
15
16
 
16
17
  const MARKER = "opus.json";
17
18
 
@@ -398,10 +399,51 @@ export async function setupUiFoundation(projectDir) {
398
399
  * Inicializa/atualiza um projeto pra usar a base.
399
400
  * @returns {Promise<{version:string, created:string[], synced:string[], warnings:string[], wasInitialized:boolean}>}
400
401
  */
401
- /** Anexa padrões ao .git/info/exclude do repo (exclusão local, fora do .gitignore). */
402
+ /**
403
+ * Onde o `info/exclude` deste repo mora de verdade. `null` = não há onde escrever.
404
+ *
405
+ * Montar `<raiz>/.git/info/exclude` na mão parece óbvio e está errado em **worktree**,
406
+ * que é como toda sessão do Maestro nasce: ali `.git` não é pasta, é um ARQUIVO com um
407
+ * ponteiro (`gitdir: …`). Checar só existência passava, e o `mkdir` seguinte estourava
408
+ * `ENOTDIR` — derrubando o postinstall, e com ele o `pnpm install` inteiro. O sintoma
409
+ * chegava longe da causa: ambiente "subindo" pra sempre, sem erro na tela.
410
+ *
411
+ * Perguntar ao git responde certo nos dois layouts. O caminho montado à mão FICA como
412
+ * rede: `opus setup` roda em postinstall, e num ambiente sem `git` no PATH trocar a
413
+ * resposta por `null` faria a exclusão parar em silêncio — a base voltaria a sujar o
414
+ * `git status` de todo mundo. Só se aplica quando `.git` é pasta; sendo arquivo, sem o
415
+ * git não há como saber pra onde o ponteiro aponta, e chutar é o defeito original.
416
+ */
417
+ function excludePathOf(repoRoot) {
418
+ try {
419
+ const p = execFileSync("git", ["rev-parse", "--git-path", "info/exclude"], {
420
+ cwd: repoRoot,
421
+ encoding: "utf-8",
422
+ stdio: ["ignore", "pipe", "ignore"],
423
+ }).trim();
424
+ // `--git-path` devolve relativo ao cwd quando o repo é o próprio cwd.
425
+ if (p !== "") return path.isAbsolute(p) ? p : path.join(repoRoot, p);
426
+ } catch {
427
+ /* sem git no PATH, ou fora de repo — cai na rede abaixo. */
428
+ }
429
+ return null;
430
+ }
431
+
432
+ /** A rede: só vale com `.git` PASTA, que é o layout onde montar o caminho acerta. */
433
+ async function excludePathFallback(repoRoot) {
434
+ const dotGit = path.join(repoRoot, ".git");
435
+ try {
436
+ if (!(await fs.stat(dotGit)).isDirectory()) return null;
437
+ } catch {
438
+ return null;
439
+ }
440
+ return path.join(dotGit, "info", "exclude");
441
+ }
442
+
443
+ /** Anexa padrões ao info/exclude do repo (exclusão local, fora do .gitignore). */
402
444
  async function gitExclude(repoRoot, patterns) {
403
- const excludePath = path.join(repoRoot, ".git", "info", "exclude");
404
- if (!(await exists(path.join(repoRoot, ".git")))) return;
445
+ const excludePath = excludePathOf(repoRoot) ?? (await excludePathFallback(repoRoot));
446
+ if (excludePath === null) return;
405
447
  let cur = "";
406
448
  try {
407
449
  cur = await fs.readFile(excludePath, "utf-8");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@softize/opus",
3
- "version": "8.6.6",
3
+ "version": "8.6.7",
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",
@@ -185,6 +185,16 @@
185
185
  "bin": {
186
186
  "opus": "./bin/cli.mjs"
187
187
  },
188
+ "scripts": {
189
+ "postinstall": "node ./bin/lib/postinstall.mjs",
190
+ "typecheck": "tsc --noEmit",
191
+ "test": "vitest run",
192
+ "test:watch": "vitest",
193
+ "test:cov": "vitest run --coverage",
194
+ "registry:up": "npx -y verdaccio --config ~/.config/verdaccio/config.yaml",
195
+ "release": "bash ./scripts/release.sh",
196
+ "release:local": "bash ./scripts/release.sh --local"
197
+ },
188
198
  "dependencies": {
189
199
  "@modelcontextprotocol/sdk": "^1.29.0",
190
200
  "@radix-ui/react-checkbox": "^1.1.3",
@@ -319,20 +329,11 @@
319
329
  "vitest": "^2.1.0",
320
330
  "zod": "^3.24.0"
321
331
  },
332
+ "packageManager": "pnpm@9.0.0",
322
333
  "repository": {
323
334
  "type": "git",
324
335
  "url": "git+https://github.com/softize-dev/opus.git",
325
336
  "directory": "packages/opus"
326
337
  },
327
- "homepage": "https://opus.softize.com.br",
328
- "scripts": {
329
- "postinstall": "node ./bin/lib/postinstall.mjs",
330
- "typecheck": "tsc --noEmit",
331
- "test": "vitest run",
332
- "test:watch": "vitest",
333
- "test:cov": "vitest run --coverage",
334
- "registry:up": "npx -y verdaccio --config ~/.config/verdaccio/config.yaml",
335
- "release": "bash ./scripts/release.sh",
336
- "release:local": "bash ./scripts/release.sh --local"
337
- }
338
- }
338
+ "homepage": "https://opus.softize.com.br"
339
+ }