@oomerevren/tryforge 0.1.2 → 0.1.3

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 (41) hide show
  1. package/CHANGELOG.md +107 -13
  2. package/README.md +172 -232
  3. package/dist/cli/src/adapters/agents-md.js +24 -0
  4. package/dist/cli/src/adapters/base.js +99 -0
  5. package/dist/cli/src/adapters/claude.js +43 -14
  6. package/dist/cli/src/adapters/codex.js +18 -17
  7. package/dist/cli/src/adapters/cursor.js +44 -30
  8. package/dist/cli/src/adapters/dsh.js +28 -30
  9. package/dist/cli/src/adapters/generic.js +10 -7
  10. package/dist/cli/src/adapters/opencode.js +23 -23
  11. package/dist/cli/src/adapters/types.js +12 -9
  12. package/dist/cli/src/adapters/windsurf.js +48 -28
  13. package/dist/cli/src/commands/add-external.js +111 -0
  14. package/dist/cli/src/commands/audit.js +68 -30
  15. package/dist/cli/src/commands/init.js +2 -2
  16. package/dist/cli/src/commands/install.js +90 -15
  17. package/dist/cli/src/commands/pack.js +119 -0
  18. package/dist/cli/src/commands/sync.js +181 -0
  19. package/dist/cli/src/commands/test.js +72 -0
  20. package/dist/cli/src/commands/tui.js +191 -0
  21. package/dist/cli/src/commands/update.js +4 -4
  22. package/dist/cli/src/commands/verify.js +62 -0
  23. package/dist/cli/src/core/fsutil.js +37 -0
  24. package/dist/cli/src/core/installer.js +9 -9
  25. package/dist/cli/src/core/lock.js +97 -10
  26. package/dist/cli/src/core/merge.js +108 -0
  27. package/dist/cli/src/core/plugin.js +2 -2
  28. package/dist/cli/src/core/project.js +136 -4
  29. package/dist/cli/src/core/registry.js +9 -9
  30. package/dist/cli/src/core/scan.js +159 -0
  31. package/dist/cli/src/core/semver.js +7 -7
  32. package/dist/cli/src/core/sign.js +2 -2
  33. package/dist/cli/src/core/sources.js +171 -0
  34. package/dist/cli/src/index.js +83 -16
  35. package/dist/index.cjs +359 -0
  36. package/dist/scripts/build-registry.js +2 -4
  37. package/dist/scripts/publish-verified.js +17 -9
  38. package/dist/scripts/seed-registry-13lite.js +5 -5
  39. package/dist/scripts/seed-registry.js +4 -4
  40. package/dist/scripts/verify-npm-mcps.js +6 -4
  41. package/package.json +15 -6
@@ -118,8 +118,6 @@ function build() {
118
118
  process.exit(1);
119
119
  }
120
120
  const existing = JSON.parse(readFileSync(INDEX_FILE, "utf-8"));
121
- const expected = JSON.stringify(index, null, 2);
122
- const actual = JSON.stringify(existing, null, 2);
123
121
  // compare count and package keys (ignore generatedAt)
124
122
  const existingCount = existing.count;
125
123
  const expectedCount = index.count;
@@ -130,7 +128,7 @@ function build() {
130
128
  }
131
129
  console.log(`[build --check] OK — index.json in sync (count=${existingCount})`);
132
130
  if (placeholderCount > 0)
133
- console.warn(`[build --check] warn: ${placeholderCount} placeholder sha256 (expected in Faz 2)`);
131
+ console.warn(`[build --check] warn: ${placeholderCount} placeholder sha256 (expected in Phase 2)`);
134
132
  return;
135
133
  }
136
134
  writeFileSync(INDEX_FILE, JSON.stringify(index, null, 2) + "\n");
@@ -140,6 +138,6 @@ function build() {
140
138
  console.log(`[build] wrote ${SEARCH_FILE} (${search.length} entries)`);
141
139
  console.log(`[build] wrote ${STATS_FILE} ${JSON.stringify(byType)}`);
142
140
  if (placeholderCount > 0)
143
- console.warn(`[build] warn: ${placeholderCount} placeholder sha256 (Faz 2 mock, Faz 3 real)`);
141
+ console.warn(`[build] warn: ${placeholderCount} placeholder sha256 (Phase 2 mock, Phase 3 real)`);
144
142
  }
145
143
  build();
@@ -1,13 +1,19 @@
1
1
  #!/usr/bin/env tsx
2
- // scripts/publish-verified.ts — forge-authored icerigi tarball yap, registry-v1 release'ine
3
- // yukle, sha256 pinle + verified:true isaretle. Idempotent (--clobber upload).
4
- // Ayrica sahte-SHA'li girdileri community katmanina dusurur (demote listesi).
5
- import { readFileSync, writeFileSync, existsSync, rmSync } from "fs";
2
+ // scripts/publish-verified.ts — pack forge-authored content into tarballs, upload
3
+ // them to the registry-v1 release, then pin sha256 + mark verified:true.
4
+ // Idempotent (--clobber upload). Entries carrying fake-SHA values are demoted
5
+ // to the community tier (demote list).
6
+ // Tarballs are built in .cache/forge-publish/ (gitignored temp dir) and removed
7
+ // after upload — prebuilt archives must never live in the git tree.
8
+ import { readFileSync, writeFileSync, existsSync, mkdirSync, rmSync } from "fs";
6
9
  import { execSync } from "child_process";
7
10
  import { createHash } from "crypto";
8
11
  const OWNER_REPO = "oomerevren-beep/forge";
9
12
  const RELEASE = "registry-v1";
10
- // registry slug -> registry-content dir (ayni ad)
13
+ // Scratch dir for tarball staging (gitignored via .cache/). Created on demand,
14
+ // cleaned per-asset after upload.
15
+ const STAGE_DIR = ".cache/forge-publish";
16
+ // registry slug -> registry-content dir (same name)
11
17
  const VERIFY = [
12
18
  "pdf-merge", "pdf-split", "pdf-ocr", "pdf-extract",
13
19
  "pdf-compress", "pdf-convert", "pdf-forms", "pdf-tables",
@@ -15,7 +21,7 @@ const VERIFY = [
15
21
  "agent-changelog-writer", "agent-researcher",
16
22
  "cmd-plan", "cmd-review",
17
23
  ];
18
- // Sahte hex + 404 URL tasiyanlar: community katmanina dusur (durustluk).
24
+ // Fake hex + 404 URL carriers: demote to community tier (honesty).
19
25
  const DEMOTE = ["anthropics-plan", "skill-pdf"];
20
26
  function sh(cmd) {
21
27
  return execSync(cmd, { encoding: "utf-8", stdio: ["ignore", "pipe", "pipe"] });
@@ -27,7 +33,7 @@ async function main() {
27
33
  console.log(`[publish] release ${RELEASE} exists`);
28
34
  }
29
35
  catch {
30
- sh(`gh release create ${RELEASE} --repo ${OWNER_REPO} --title "Forge verified registry content v1" --notes "Seed-verified package tarballs (Faz 6-oncesi). Each asset sha256-pinned in registry/packages/*.json."`);
36
+ sh(`gh release create ${RELEASE} --repo ${OWNER_REPO} --title "Forge verified registry content v1" --notes "Seed-verified package tarballs (pre-Phase-6). Each asset sha256-pinned in registry/packages/*.json."`);
31
37
  console.log(`[publish] release ${RELEASE} created`);
32
38
  }
33
39
  let ok = 0;
@@ -40,11 +46,13 @@ async function main() {
40
46
  }
41
47
  const detail = JSON.parse(readFileSync(pkgPath, "utf-8"));
42
48
  const version = detail.latest;
43
- // forge.toml manifest uret (paket bildirimi)
49
+ // generate forge.toml manifest (package declaration)
44
50
  const manifest = `[package]\nname = "${detail.name}"\nversion = "${version}"\ntype = "${detail.type}"\ndescription = "${detail.description.replace(/"/g, "'")}"\nlicense = "MIT"\nrepository = "https://github.com/${OWNER_REPO}"\n`;
45
51
  writeFileSync(`${srcDir}/forge.toml`, manifest);
46
52
  const asset = `${slug}-${version}.tar.gz`;
47
- const tmp = `registry-content/${asset}`;
53
+ // Stage the tarball under the gitignored scratch dir — never in the repo tree.
54
+ mkdirSync(STAGE_DIR, { recursive: true });
55
+ const tmp = `${STAGE_DIR}/${asset}`;
48
56
  sh(`tar -czf ${tmp} -C ${srcDir} .`);
49
57
  const buf = readFileSync(tmp);
50
58
  const sha256 = createHash("sha256").update(buf).digest("hex");
@@ -1,12 +1,12 @@
1
1
  #!/usr/bin/env tsx
2
- // scripts/seed-registry-13lite.ts — Faz 13-lite: 100 → 250 paket (+150, elle kürasyon)
3
- // Odak: pdf (10+), agent (20+), mcp kategorilerisearch "wow" için.
4
- // Idempotent: var olan dosyaları atlar, sonra 'npm run registry:build' çalıştır.
2
+ // scripts/seed-registry-13lite.ts — Phase 13-lite: 100 → 250 packages (+150, hand-curated)
3
+ // Focus: pdf (10+), agent (20+), mcp categoriesfor a "wow" search.
4
+ // Idempotent: skips existing files, then run 'npm run registry:build'.
5
5
  import { existsSync, writeFileSync, mkdirSync } from "fs";
6
6
  import { join } from "path";
7
7
  const PACKAGES_DIR = "registry/packages";
8
8
  const ROWS = [
9
- // --- PDF (12) — forge search pdf 10+ hedefi ---
9
+ // --- PDF (12) — 'forge search pdf' 10+ goal ---
10
10
  ["pdf/merge", "skill", "PDF merge skill — combine multiple PDFs into one document fast", ["pdf", "merge", "document"]],
11
11
  ["pdf/split", "skill", "PDF split skill — extract pages and split PDFs by range", ["pdf", "split", "pages"]],
12
12
  ["pdf/ocr", "skill", "PDF OCR skill — scanned PDFs to searchable text with OCR", ["pdf", "ocr", "scan"]],
@@ -19,7 +19,7 @@ const ROWS = [
19
19
  ["pdf/convert", "skill", "PDF convert skill — PDF to Word, HTML, Markdown and back", ["pdf", "convert", "export"]],
20
20
  ["pdf/annotate", "skill", "PDF annotate skill — comments, highlights and review markup", ["pdf", "annotate", "review"]],
21
21
  ["pdf/tables", "skill", "PDF tables skill — detect and export tables from PDFs to CSV", ["pdf", "tables", "csv"]],
22
- // --- Agent (25) — forge search agent 20+ hedefi ---
22
+ // --- Agent (25) — 'forge search agent' 20+ goal ---
23
23
  ["agent/pr-reviewer", "agent", "PR reviewer agent — thorough pull request reviews with suggestions", ["agent", "review", "pr"]],
24
24
  ["agent/changelog-writer", "agent", "Changelog writer agent — generate release notes from commits", ["agent", "changelog", "release"]],
25
25
  ["agent/migrator", "agent", "Migrator agent — framework and version migration assistant", ["agent", "migrate", "refactor"]],
@@ -1,12 +1,12 @@
1
1
  #!/usr/bin/env tsx
2
- // scripts/seed-registry.ts — Epoch 1d: sadece gerçek tarball'ı olan paketleri seed
3
- // Var olmayan repo'ları eklemez — fail-closed
2
+ // scripts/seed-registry.ts — Epoch 1d: seed only packages with real tarballs
3
+ // Never adds repos that do not exist — fail-closed
4
4
  import { existsSync, writeFileSync, mkdirSync } from "fs";
5
5
  import { join } from "path";
6
6
  const PACKAGES_DIR = "registry/packages";
7
- // Sadece gerçekten doğrulanmış tarball'lar — Epoch 1d
7
+ // Only genuinely verified tarballs — Epoch 1d
8
8
  const CATALOG = [
9
- // Gerçek tarball'lı paketler (SHA256 doğrulanmış)
9
+ // Real-tarball packages (SHA256 verified)
10
10
  {
11
11
  name: "pdf/compress", type: "skill", description: "PDF compress skill — shrink PDF size without quality loss",
12
12
  keywords: ["pdf", "compress", "optimize"], source: "registry-content",
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env tsx
2
- // scripts/verify-npm-mcps.ts — MCP girdilerini gercek upstream npm tarball'iyla dogrula.
3
- // Her paket icin: npm metadata -> dist.tarball indir -> sha256 hesapla -> JSON'a pin + verified:true.
4
- // Fail-closed: herhangi bir adim basarisizsa o paket atlanir (placeholder korunur).
2
+ // scripts/verify-npm-mcps.ts — verify MCP entries against real upstream npm tarballs.
3
+ // Per package: npm metadata -> dist.tarball download -> sha256 compute -> pin into JSON + verified:true.
4
+ // Fail-closed: any failing step skips that package (placeholder preserved).
5
5
  import { readFileSync, writeFileSync } from "fs";
6
6
  import { createHash } from "crypto";
7
7
  const MAP = [
@@ -20,7 +20,9 @@ async function main() {
20
20
  const version = meta["dist-tags"]?.latest;
21
21
  if (!version || !meta.versions?.[version]?.dist?.tarball)
22
22
  throw new Error("no latest dist");
23
- const tarball = meta.versions[version].dist.tarball;
23
+ const tarball = meta.versions[version].dist?.tarball;
24
+ if (!tarball)
25
+ throw new Error("no latest dist");
24
26
  const publishedAt = meta.time?.[version] ?? new Date().toISOString();
25
27
  const dl = await fetch(tarball);
26
28
  if (!dl.ok)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oomerevren/tryforge",
3
- "version": "0.1.2",
3
+ "version": "0.1.3",
4
4
  "description": "The Homebrew for AI Agents — one CLI for skills, MCPs, plugins, agents",
5
5
  "license": "MIT",
6
6
  "author": "Ömer Evren",
@@ -27,8 +27,8 @@
27
27
  ],
28
28
  "type": "module",
29
29
  "bin": {
30
- "forge": "dist/cli/src/index.js",
31
- "tryforge": "dist/cli/src/index.js"
30
+ "forge": "./dist/index.cjs",
31
+ "tryforge": "./dist/index.cjs"
32
32
  },
33
33
  "files": [
34
34
  "dist/",
@@ -45,20 +45,29 @@
45
45
  },
46
46
  "scripts": {
47
47
  "dev": "tsx cli/src/index.ts",
48
- "build": "tsc",
49
- "prepublishOnly": "npm run build && npm test && npm run registry:build -- --check",
48
+ "build": "tsc -p tsconfig.build.json",
49
+ "bundle": "esbuild cli/src/index.ts --bundle --platform=node --format=cjs --outfile=dist/index.cjs --banner:js=\"#!/usr/bin/env node\" --minify && node -e \"const fs=require('fs');const p='dist/index.cjs';const L=fs.readFileSync(p,'utf8').split('\\n');if(L[1]&&L[1].startsWith('#!'))L.splice(1,1);fs.writeFileSync(p,L.join('\\n'));fs.chmodSync(p, 0o755)\"",
50
+ "lint": "eslint cli/ scripts/ tests/ eslint.config.js --max-warnings 0",
51
+ "typecheck": "tsc --noEmit",
52
+ "prepublishOnly": "npm run build && npm run bundle && npm test && npm run registry:build -- --check",
50
53
  "test": "node --import tsx --test tests/**/*.test.ts cli/src/**/*.test.ts",
51
54
  "registry:build": "tsx scripts/build-registry.ts",
52
55
  "seed": "tsx scripts/seed-registry.ts"
53
56
  },
54
57
  "dependencies": {
58
+ "@clack/prompts": "^0.11.0",
55
59
  "commander": "^12.0.0",
60
+ "picocolors": "^1.1.1",
56
61
  "smol-toml": "^1.8.0"
57
62
  },
58
63
  "devDependencies": {
64
+ "@eslint/js": "^10.0.1",
59
65
  "@types/node": "^26.4.1",
66
+ "esbuild": "^0.28.2",
67
+ "eslint": "^10.9.1",
60
68
  "playwright": "^1.62.1",
61
69
  "tsx": "^4.23.13",
62
- "typescript": "^7.0.2"
70
+ "typescript": "^6.0.3",
71
+ "typescript-eslint": "^8.69.0"
63
72
  }
64
73
  }