crewforge 0.2.1__tar.gz → 0.2.2__tar.gz

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 (79) hide show
  1. {crewforge-0.2.1/src/crewforge.egg-info → crewforge-0.2.2}/PKG-INFO +70 -22
  2. {crewforge-0.2.1 → crewforge-0.2.2}/README.md +69 -21
  3. {crewforge-0.2.1 → crewforge-0.2.2}/pyproject.toml +1 -1
  4. {crewforge-0.2.1 → crewforge-0.2.2}/src/crewforge/__init__.py +1 -1
  5. {crewforge-0.2.1 → crewforge-0.2.2/src/crewforge.egg-info}/PKG-INFO +70 -22
  6. {crewforge-0.2.1 → crewforge-0.2.2}/LICENSE +0 -0
  7. {crewforge-0.2.1 → crewforge-0.2.2}/setup.cfg +0 -0
  8. {crewforge-0.2.1 → crewforge-0.2.2}/src/crewforge/__main__.py +0 -0
  9. {crewforge-0.2.1 → crewforge-0.2.2}/src/crewforge/cli.py +0 -0
  10. {crewforge-0.2.1 → crewforge-0.2.2}/src/crewforge/cli_support.py +0 -0
  11. {crewforge-0.2.1 → crewforge-0.2.2}/src/crewforge/core/__init__.py +0 -0
  12. {crewforge-0.2.1 → crewforge-0.2.2}/src/crewforge/core/agent.py +0 -0
  13. {crewforge-0.2.1 → crewforge-0.2.2}/src/crewforge/core/client.py +0 -0
  14. {crewforge-0.2.1 → crewforge-0.2.2}/src/crewforge/core/config.py +0 -0
  15. {crewforge-0.2.1 → crewforge-0.2.2}/src/crewforge/core/crew.py +0 -0
  16. {crewforge-0.2.1 → crewforge-0.2.2}/src/crewforge/core/errors.py +0 -0
  17. {crewforge-0.2.1 → crewforge-0.2.2}/src/crewforge/core/parsing.py +0 -0
  18. {crewforge-0.2.1 → crewforge-0.2.2}/src/crewforge/core/providers.py +0 -0
  19. {crewforge-0.2.1 → crewforge-0.2.2}/src/crewforge/core/usage.py +0 -0
  20. {crewforge-0.2.1 → crewforge-0.2.2}/src/crewforge/py.typed +0 -0
  21. {crewforge-0.2.1 → crewforge-0.2.2}/src/crewforge/recipes/__init__.py +0 -0
  22. {crewforge-0.2.1 → crewforge-0.2.2}/src/crewforge/recipes/academic/__init__.py +0 -0
  23. {crewforge-0.2.1 → crewforge-0.2.2}/src/crewforge/recipes/academic/agents.py +0 -0
  24. {crewforge-0.2.1 → crewforge-0.2.2}/src/crewforge/recipes/academic/citations.py +0 -0
  25. {crewforge-0.2.1 → crewforge-0.2.2}/src/crewforge/recipes/academic/cli.py +0 -0
  26. {crewforge-0.2.1 → crewforge-0.2.2}/src/crewforge/recipes/academic/disclosure.py +0 -0
  27. {crewforge-0.2.1 → crewforge-0.2.2}/src/crewforge/recipes/academic/language.py +0 -0
  28. {crewforge-0.2.1 → crewforge-0.2.2}/src/crewforge/recipes/academic/locales/en.yaml +0 -0
  29. {crewforge-0.2.1 → crewforge-0.2.2}/src/crewforge/recipes/academic/locales/ms.yaml +0 -0
  30. {crewforge-0.2.1 → crewforge-0.2.2}/src/crewforge/recipes/academic/pipeline.py +0 -0
  31. {crewforge-0.2.1 → crewforge-0.2.2}/src/crewforge/recipes/academic/report.py +0 -0
  32. {crewforge-0.2.1 → crewforge-0.2.2}/src/crewforge/recipes/academic/settings.py +0 -0
  33. {crewforge-0.2.1 → crewforge-0.2.2}/src/crewforge/recipes/api/__init__.py +0 -0
  34. {crewforge-0.2.1 → crewforge-0.2.2}/src/crewforge/recipes/api/agents.py +0 -0
  35. {crewforge-0.2.1 → crewforge-0.2.2}/src/crewforge/recipes/api/analytics.py +0 -0
  36. {crewforge-0.2.1 → crewforge-0.2.2}/src/crewforge/recipes/api/appcheck.py +0 -0
  37. {crewforge-0.2.1 → crewforge-0.2.2}/src/crewforge/recipes/api/cli.py +0 -0
  38. {crewforge-0.2.1 → crewforge-0.2.2}/src/crewforge/recipes/api/formatters.py +0 -0
  39. {crewforge-0.2.1 → crewforge-0.2.2}/src/crewforge/recipes/api/generator.py +0 -0
  40. {crewforge-0.2.1 → crewforge-0.2.2}/src/crewforge/recipes/api/pipeline.py +0 -0
  41. {crewforge-0.2.1 → crewforge-0.2.2}/src/crewforge/recipes/api/scaffold.py +0 -0
  42. {crewforge-0.2.1 → crewforge-0.2.2}/src/crewforge/recipes/api/templates/docker-compose.j2 +0 -0
  43. {crewforge-0.2.1 → crewforge-0.2.2}/src/crewforge/recipes/api/templates/dockerfile.j2 +0 -0
  44. {crewforge-0.2.1 → crewforge-0.2.2}/src/crewforge/recipes/api/templates/env.example.j2 +0 -0
  45. {crewforge-0.2.1 → crewforge-0.2.2}/src/crewforge/recipes/api/templates/fastapi_main.j2 +0 -0
  46. {crewforge-0.2.1 → crewforge-0.2.2}/src/crewforge/recipes/api/templates/model.j2 +0 -0
  47. {crewforge-0.2.1 → crewforge-0.2.2}/src/crewforge/recipes/api/templates/requirements.j2 +0 -0
  48. {crewforge-0.2.1 → crewforge-0.2.2}/src/crewforge/recipes/api/templates/route.j2 +0 -0
  49. {crewforge-0.2.1 → crewforge-0.2.2}/src/crewforge/recipes/api/templates/test.j2 +0 -0
  50. {crewforge-0.2.1 → crewforge-0.2.2}/src/crewforge/recipes/api/utils.py +0 -0
  51. {crewforge-0.2.1 → crewforge-0.2.2}/src/crewforge/recipes/content/__init__.py +0 -0
  52. {crewforge-0.2.1 → crewforge-0.2.2}/src/crewforge/recipes/content/agents.py +0 -0
  53. {crewforge-0.2.1 → crewforge-0.2.2}/src/crewforge/recipes/content/cli.py +0 -0
  54. {crewforge-0.2.1 → crewforge-0.2.2}/src/crewforge/recipes/content/export.py +0 -0
  55. {crewforge-0.2.1 → crewforge-0.2.2}/src/crewforge/recipes/content/pipeline.py +0 -0
  56. {crewforge-0.2.1 → crewforge-0.2.2}/src/crewforge/recipes/content/settings.py +0 -0
  57. {crewforge-0.2.1 → crewforge-0.2.2}/src/crewforge/recipes/content/text.py +0 -0
  58. {crewforge-0.2.1 → crewforge-0.2.2}/src/crewforge/recipes/docs/__init__.py +0 -0
  59. {crewforge-0.2.1 → crewforge-0.2.2}/src/crewforge/recipes/docs/agents.py +0 -0
  60. {crewforge-0.2.1 → crewforge-0.2.2}/src/crewforge/recipes/docs/cli.py +0 -0
  61. {crewforge-0.2.1 → crewforge-0.2.2}/src/crewforge/recipes/docs/export.py +0 -0
  62. {crewforge-0.2.1 → crewforge-0.2.2}/src/crewforge/recipes/docs/index.py +0 -0
  63. {crewforge-0.2.1 → crewforge-0.2.2}/src/crewforge/recipes/docs/ingest.py +0 -0
  64. {crewforge-0.2.1 → crewforge-0.2.2}/src/crewforge/recipes/docs/pipeline.py +0 -0
  65. {crewforge-0.2.1 → crewforge-0.2.2}/src/crewforge/recipes/docs/retrieve.py +0 -0
  66. {crewforge-0.2.1 → crewforge-0.2.2}/src/crewforge/recipes/docs/settings.py +0 -0
  67. {crewforge-0.2.1 → crewforge-0.2.2}/src/crewforge/recipes/review/__init__.py +0 -0
  68. {crewforge-0.2.1 → crewforge-0.2.2}/src/crewforge/recipes/review/agents.py +0 -0
  69. {crewforge-0.2.1 → crewforge-0.2.2}/src/crewforge/recipes/review/cli.py +0 -0
  70. {crewforge-0.2.1 → crewforge-0.2.2}/src/crewforge/recipes/review/pipeline.py +0 -0
  71. {crewforge-0.2.1 → crewforge-0.2.2}/src/crewforge/recipes/review/report.py +0 -0
  72. {crewforge-0.2.1 → crewforge-0.2.2}/src/crewforge/recipes/review/sources.py +0 -0
  73. {crewforge-0.2.1 → crewforge-0.2.2}/src/crewforge.egg-info/SOURCES.txt +0 -0
  74. {crewforge-0.2.1 → crewforge-0.2.2}/src/crewforge.egg-info/dependency_links.txt +0 -0
  75. {crewforge-0.2.1 → crewforge-0.2.2}/src/crewforge.egg-info/entry_points.txt +0 -0
  76. {crewforge-0.2.1 → crewforge-0.2.2}/src/crewforge.egg-info/requires.txt +0 -0
  77. {crewforge-0.2.1 → crewforge-0.2.2}/src/crewforge.egg-info/top_level.txt +0 -0
  78. {crewforge-0.2.1 → crewforge-0.2.2}/tests/test_honest_failure_e2e.py +0 -0
  79. {crewforge-0.2.1 → crewforge-0.2.2}/tests/test_readme.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: crewforge
3
- Version: 0.2.1
3
+ Version: 0.2.2
4
4
  Summary: One crew of LLM agents, five recipes: code review, document Q&A, API scaffolding, content and honest academic-writing help — on any OpenAI-compatible provider.
5
5
  Author: Muhammad Aiman
6
6
  License-Expression: MIT
@@ -56,15 +56,21 @@ Requires-Dist: fastapi>=0.110; extra == "dev"
56
56
  Requires-Dist: httpx>=0.27; extra == "dev"
57
57
  Dynamic: license-file
58
58
 
59
- # crewforge
59
+ <p align="center"><img src="https://raw.githubusercontent.com/aimanmalib/crewforge/main/brand/logo-512.png" width="112" height="112" alt="crewforge"></p>
60
60
 
61
- **One crew of LLM agents, five recipes — code review, document Q&A, API scaffolding, content and honest academic-writing help — on any OpenAI-compatible provider, and it fails loudly instead of pretending.**
61
+ <h1 align="center">crewforge</h1>
62
62
 
63
- [![CI](https://github.com/aimanmalib/crewforge/actions/workflows/ci.yml/badge.svg)](https://github.com/aimanmalib/crewforge/actions/workflows/ci.yml)
64
- [![PyPI](https://img.shields.io/pypi/v/crewforge)](https://pypi.org/project/crewforge/)
65
- [![OpenSSF Scorecard](https://api.scorecard.dev/projects/github.com/aimanmalib/crewforge/badge)](https://scorecard.dev/viewer/?uri=github.com/aimanmalib/crewforge)
66
- ![Python 3.10–3.14](https://img.shields.io/badge/python-3.10%E2%80%933.14-blue)
67
- ![License: MIT](https://img.shields.io/badge/license-MIT-green)
63
+ <p align="center"><a href="https://github.com/aimanmalib/crewforge/actions/workflows/ci.yml"><img src="https://github.com/aimanmalib/crewforge/actions/workflows/ci.yml/badge.svg" alt="CI"></a> <a href="https://pypi.org/project/crewforge/"><img src="https://img.shields.io/pypi/v/crewforge" alt="PyPI"></a> <a href="https://scorecard.dev/viewer/?uri=github.com/aimanmalib/crewforge"><img src="https://api.scorecard.dev/projects/github.com/aimanmalib/crewforge/badge" alt="OpenSSF Scorecard"></a> <img src="https://img.shields.io/badge/python-3.10%E2%80%933.14-blue" alt="Python 3.10–3.14"> <a href="https://github.com/aimanmalib/crewforge/blob/main/LICENSE"><img src="https://img.shields.io/badge/license-MIT-green" alt="License: MIT"></a></p>
64
+
65
+ <p align="center"><b>One crew of LLM agents, five recipes, any OpenAI-compatible provider.</b> · <i>Satu kru ejen LLM, lima resipi, mana-mana penyedia serasi OpenAI.</i><br>
66
+ <a href="https://pypi.org/project/crewforge/">PyPI</a> · <a href="https://github.com/aimanmalib/crewforge/blob/main/CHANGELOG.md">changelog</a> · <a href="https://github.com/aimanmalib/crewforge/blob/main/docs/porting.md">porting notes</a> · Built in Malaysia by <a href="https://aimanmalib.com">Aiman Malib</a></p>
67
+
68
+ crewforge is a command-line tool and Python library that runs a crew of LLM agents through five recipes: code
69
+ review, document Q&A, API scaffolding, content writing and honest academic-writing help. It works with any
70
+ OpenAI-compatible provider, reads API keys only from the environment, and fails loudly instead of pretending: a run
71
+ in which an agent produced nothing exits with code 1 and names that agent.
72
+
73
+ [Bahasa Melayu ↓](#bahasa-melayu)
68
74
 
69
75
  ```bash
70
76
  crewforge review src/ # six reviewers + a summary
@@ -81,7 +87,7 @@ crewforge academic feedback draft.md --brief brief.md --language ms
81
87
 
82
88
  ## Why one crew, many recipes
83
89
 
84
- crewforge started as four separate command-line tools —
90
+ crewforge started as four separate command-line tools:
85
91
  [codeguard](https://github.com/aimanmalib/codeguard),
86
92
  [documind](https://github.com/aimanmalib/documind),
87
93
  [apiforge](https://github.com/aimanmalib/apiforge) and
@@ -95,7 +101,7 @@ showed the copies had drifted and that each hid its failures differently:
95
101
  - apiforge scored a spec with **no endpoints** 100/100;
96
102
  - contentforge wrote the real API key into its YAML file, and sent `${OPENAI_API_KEY}` literally as the key.
97
103
 
98
- crewforge keeps one core — so a fix lands once — and turns each tool into a
104
+ crewforge keeps one core, so a fix lands once, and turns each tool into a
99
105
  *recipe*: a set of agents plus the steps that connect them. The same core rules
100
106
  apply to every recipe: non-streaming requests, bounded retries, usage numbers
101
107
  taken only from the provider, keys only from the environment, and no run that
@@ -290,13 +296,13 @@ Saya menggunakan crewforge academic (versi 0.1.0), sebuah alat berbantukan AI, d
290
296
  - 22 Oktober 2026: Perancangan: alat ini menukar taklimat tugasan (brief-ms.md) kepada 3 soalan kajian, rangka 5 bahagian dan peruntukan perkataan. ...
291
297
  ```
292
298
 
293
- How sources are labelled — there is no "verified" status, because the tool
299
+ How sources are labelled: there is no "verified" status, because the tool
294
300
  cannot check that a source exists:
295
301
 
296
302
  | Source | Label |
297
303
  |---|---|
298
304
  | You supplied it | *supplied by you (not checked online)* |
299
- | The model proposed it, with a DOI, URL or valid ISBN | **UNVERIFIED** — check it |
305
+ | The model proposed it, with a DOI, URL or valid ISBN | **UNVERIFIED**: check it |
300
306
  | The model proposed it with none of those | **LIKELY FABRICATED** |
301
307
  | The model added a DOI/URL/ISBN to a reference you supplied | **UNVERIFIED**, naming the added identifier |
302
308
 
@@ -335,16 +341,16 @@ An unknown provider name is a configuration error, not a silent fallback.
335
341
 
336
342
  <sub>Source: [docs/architecture.mmd](https://github.com/aimanmalib/crewforge/blob/main/docs/architecture.mmd) (re-render with `scripts/render_architecture.py`).</sub>
337
343
 
338
- - **`core/client.py`** — one async client. It always sends `"stream": false`,
344
+ - **`core/client.py`**: one async client. It always sends `"stream": false`,
339
345
  retries only HTTP 429, 5xx and network/timeout errors (with capped exponential
340
346
  backoff that honours `Retry-After`), and fails on the first 401/403/4xx with a
341
347
  message naming the variable to fix. The key is only ever a request header.
342
- - **`core/agent.py`** — an agent is a role, a system prompt and per-agent
348
+ - **`core/agent.py`**: an agent is a role, a system prompt and per-agent
343
349
  sampling defaults. `ask()` records usage and raises if the reply is blank;
344
350
  `ask_json()` additionally requires parseable JSON (optionally a pydantic schema).
345
- - **`core/crew.py`** — runs agents as sequential steps or parallel stages and
351
+ - **`core/crew.py`**: runs agents as sequential steps or parallel stages and
346
352
  turns any failure into a `CrewFailedError` that lists every failed agent.
347
- - **`core/usage.py`** — per-agent calls, tokens, retries and latency, taken from
353
+ - **`core/usage.py`**: per-agent calls, tokens, retries and latency, taken from
348
354
  the provider's `usage` object. Calls without usage are counted as "not reported",
349
355
  never estimated.
350
356
 
@@ -409,10 +415,10 @@ watching them fail; see [docs/porting.md](https://github.com/aimanmalib/crewforg
409
415
 
410
416
  crewforge was built with AI coding assistance (Claude Code) under the
411
417
  direction of its author, Muhammad Aiman. It consolidates four earlier tools by
412
- the same author — [codeguard](https://github.com/aimanmalib/codeguard),
418
+ the same author ([codeguard](https://github.com/aimanmalib/codeguard),
413
419
  [documind](https://github.com/aimanmalib/documind),
414
420
  [apiforge](https://github.com/aimanmalib/apiforge) and
415
- [contentforge](https://github.com/aimanmalib/contentforge) — whose test suites
421
+ [contentforge](https://github.com/aimanmalib/contentforge)), whose test suites
416
422
  were carried over into this repository (see [docs/porting.md](https://github.com/aimanmalib/crewforge/blob/main/docs/porting.md)
417
423
  for what was ported, re-targeted at the shared core, or dropped and why).
418
424
 
@@ -435,10 +441,52 @@ Please report vulnerabilities privately through
435
441
  See [SECURITY.md](https://github.com/aimanmalib/crewforge/blob/main/SECURITY.md) for scope notes (what is sent to your provider,
436
442
  and what `validate` executes).
437
443
 
438
- ## License
444
+ ## Bahasa Melayu
445
+
446
+ crewforge ialah alat baris arahan dan pustaka Python yang menjalankan satu kru ejen LLM melalui lima resipi:
447
+ semakan kod (`review`), soal jawab dokumen (`ask`, `summarize`), penjanaan projek API FastAPI (`scaffold`,
448
+ `validate`), penulisan kandungan (`write`) dan bantuan penulisan akademik yang jujur (`academic`). Ia berfungsi
449
+ dengan mana-mana penyedia serasi OpenAI, termasuk model tempatan melalui Ollama atau llama.cpp. Kunci API hanya
450
+ dibaca dari pemboleh ubah persekitaran, tidak pernah ditulis ke fail.
451
+
452
+ **Mengapa satu kru.** crewforge menggabungkan empat alat lama (codeguard, documind, apiforge, contentforge) yang
453
+ masing-masing menyimpan salinan sendiri bagi rangka yang sama. Salinan itu sudah berbeza dan setiap satu
454
+ menyembunyikan kegagalan dengan cara sendiri. Kini teras dikongsi: pembaikan dibuat sekali, dan setiap alat menjadi
455
+ resipi di atas teras itu.
456
+
457
+ **Gagal dengan jelas.** Larian yang ejennya memulangkan jawapan kosong atau tidak boleh dihurai, atau pengesah
458
+ yang tidak menyemak apa-apa, keluar dengan kod 1 dan menamakan ejen itu. Kod keluar: `0` berjaya, `1` larian
459
+ gagal, `2` ralat penggunaan atau konfigurasi. Bilangan token diambil daripada laporan penyedia sahaja, tidak
460
+ dianggar.
461
+
462
+ **Resipi `academic`.** Membantu pelajar dan penyelidik dengan kerja mereka **sendiri**: merancang dari taklimat
463
+ tugasan, memberi ulasan atas draf tanpa menulis semula, memformat rujukan yang diberi pengguna (APA 7, IEEE,
464
+ Harvard) tanpa menambah rujukan baharu, dan menulis pernyataan penggunaan AI daripada rekod langkah yang
465
+ dijalankan. Output dalam bahasa Inggeris atau Bahasa Melayu (`--language ms`); output BM disemak untuk bentuk
466
+ Indonesia seperti *karena* atau *kualitas*. Sumber yang dicadangkan model dilabel UNVERIFIED, atau LIKELY
467
+ FABRICATED jika tiada DOI, URL atau ISBN. Tiada ciri "humanise" atau mengelak pengesan AI.
468
+
469
+ **Pasang dan guna.**
470
+
471
+ ```bash
472
+ pip install crewforge # Python 3.10 hingga 3.14
473
+ pip install "crewforge[docs,api]" # pilihan: PDF/DOCX dan semakan aplikasi FastAPI
474
+ export OPENAI_API_KEY=sk-... # atau penyedia lain, lihat `crewforge providers`
475
+ crewforge review src/
476
+ crewforge academic feedback draf.md --brief taklimat.md --language ms
477
+ ```
478
+
479
+ Senarai penyedia, contoh setiap resipi dan seni bina ada dalam bahagian bahasa Inggeris di atas
480
+ ([Providers](https://github.com/aimanmalib/crewforge#providers), [Recipes](https://github.com/aimanmalib/crewforge#recipes)).
481
+
482
+ ## Licence
483
+
484
+ [MIT](https://github.com/aimanmalib/crewforge/blob/main/LICENSE) © Muhammad Aiman. Made by [Aiman Malib](https://aimanmalib.com), Malaysia.
485
+
486
+ ## Work with Sasa Teguh
439
487
 
440
- [MIT](https://github.com/aimanmalib/crewforge/blob/main/LICENSE) © Muhammad Aiman
488
+ [![Work with Sasa Teguh: book a call](https://raw.githubusercontent.com/sasateguh/.github/main/assets/work-with-sasa-teguh.png)](https://sasateguh.com/book)
441
489
 
442
- ---
490
+ I built this project. I run [Sasa Teguh](https://sasateguh.com), a studio in Malaysia that builds websites found on Google and in AI answers, and sets up systems like this one for businesses.
443
491
 
444
- Built by [Sasa Teguh](https://sasateguh.com) · Malaysia
492
+ [Book a call](https://sasateguh.com/book) · hello@sasateguh.com · [More from Sasa Teguh](https://github.com/sasateguh)
@@ -1,12 +1,18 @@
1
- # crewforge
1
+ <p align="center"><img src="https://raw.githubusercontent.com/aimanmalib/crewforge/main/brand/logo-512.png" width="112" height="112" alt="crewforge"></p>
2
2
 
3
- **One crew of LLM agents, five recipes — code review, document Q&A, API scaffolding, content and honest academic-writing help — on any OpenAI-compatible provider, and it fails loudly instead of pretending.**
3
+ <h1 align="center">crewforge</h1>
4
4
 
5
- [![CI](https://github.com/aimanmalib/crewforge/actions/workflows/ci.yml/badge.svg)](https://github.com/aimanmalib/crewforge/actions/workflows/ci.yml)
6
- [![PyPI](https://img.shields.io/pypi/v/crewforge)](https://pypi.org/project/crewforge/)
7
- [![OpenSSF Scorecard](https://api.scorecard.dev/projects/github.com/aimanmalib/crewforge/badge)](https://scorecard.dev/viewer/?uri=github.com/aimanmalib/crewforge)
8
- ![Python 3.10–3.14](https://img.shields.io/badge/python-3.10%E2%80%933.14-blue)
9
- ![License: MIT](https://img.shields.io/badge/license-MIT-green)
5
+ <p align="center"><a href="https://github.com/aimanmalib/crewforge/actions/workflows/ci.yml"><img src="https://github.com/aimanmalib/crewforge/actions/workflows/ci.yml/badge.svg" alt="CI"></a> <a href="https://pypi.org/project/crewforge/"><img src="https://img.shields.io/pypi/v/crewforge" alt="PyPI"></a> <a href="https://scorecard.dev/viewer/?uri=github.com/aimanmalib/crewforge"><img src="https://api.scorecard.dev/projects/github.com/aimanmalib/crewforge/badge" alt="OpenSSF Scorecard"></a> <img src="https://img.shields.io/badge/python-3.10%E2%80%933.14-blue" alt="Python 3.10–3.14"> <a href="https://github.com/aimanmalib/crewforge/blob/main/LICENSE"><img src="https://img.shields.io/badge/license-MIT-green" alt="License: MIT"></a></p>
6
+
7
+ <p align="center"><b>One crew of LLM agents, five recipes, any OpenAI-compatible provider.</b> · <i>Satu kru ejen LLM, lima resipi, mana-mana penyedia serasi OpenAI.</i><br>
8
+ <a href="https://pypi.org/project/crewforge/">PyPI</a> · <a href="https://github.com/aimanmalib/crewforge/blob/main/CHANGELOG.md">changelog</a> · <a href="https://github.com/aimanmalib/crewforge/blob/main/docs/porting.md">porting notes</a> · Built in Malaysia by <a href="https://aimanmalib.com">Aiman Malib</a></p>
9
+
10
+ crewforge is a command-line tool and Python library that runs a crew of LLM agents through five recipes: code
11
+ review, document Q&A, API scaffolding, content writing and honest academic-writing help. It works with any
12
+ OpenAI-compatible provider, reads API keys only from the environment, and fails loudly instead of pretending: a run
13
+ in which an agent produced nothing exits with code 1 and names that agent.
14
+
15
+ [Bahasa Melayu ↓](#bahasa-melayu)
10
16
 
11
17
  ```bash
12
18
  crewforge review src/ # six reviewers + a summary
@@ -23,7 +29,7 @@ crewforge academic feedback draft.md --brief brief.md --language ms
23
29
 
24
30
  ## Why one crew, many recipes
25
31
 
26
- crewforge started as four separate command-line tools —
32
+ crewforge started as four separate command-line tools:
27
33
  [codeguard](https://github.com/aimanmalib/codeguard),
28
34
  [documind](https://github.com/aimanmalib/documind),
29
35
  [apiforge](https://github.com/aimanmalib/apiforge) and
@@ -37,7 +43,7 @@ showed the copies had drifted and that each hid its failures differently:
37
43
  - apiforge scored a spec with **no endpoints** 100/100;
38
44
  - contentforge wrote the real API key into its YAML file, and sent `${OPENAI_API_KEY}` literally as the key.
39
45
 
40
- crewforge keeps one core — so a fix lands once — and turns each tool into a
46
+ crewforge keeps one core, so a fix lands once, and turns each tool into a
41
47
  *recipe*: a set of agents plus the steps that connect them. The same core rules
42
48
  apply to every recipe: non-streaming requests, bounded retries, usage numbers
43
49
  taken only from the provider, keys only from the environment, and no run that
@@ -232,13 +238,13 @@ Saya menggunakan crewforge academic (versi 0.1.0), sebuah alat berbantukan AI, d
232
238
  - 22 Oktober 2026: Perancangan: alat ini menukar taklimat tugasan (brief-ms.md) kepada 3 soalan kajian, rangka 5 bahagian dan peruntukan perkataan. ...
233
239
  ```
234
240
 
235
- How sources are labelled — there is no "verified" status, because the tool
241
+ How sources are labelled: there is no "verified" status, because the tool
236
242
  cannot check that a source exists:
237
243
 
238
244
  | Source | Label |
239
245
  |---|---|
240
246
  | You supplied it | *supplied by you (not checked online)* |
241
- | The model proposed it, with a DOI, URL or valid ISBN | **UNVERIFIED** — check it |
247
+ | The model proposed it, with a DOI, URL or valid ISBN | **UNVERIFIED**: check it |
242
248
  | The model proposed it with none of those | **LIKELY FABRICATED** |
243
249
  | The model added a DOI/URL/ISBN to a reference you supplied | **UNVERIFIED**, naming the added identifier |
244
250
 
@@ -277,16 +283,16 @@ An unknown provider name is a configuration error, not a silent fallback.
277
283
 
278
284
  <sub>Source: [docs/architecture.mmd](https://github.com/aimanmalib/crewforge/blob/main/docs/architecture.mmd) (re-render with `scripts/render_architecture.py`).</sub>
279
285
 
280
- - **`core/client.py`** — one async client. It always sends `"stream": false`,
286
+ - **`core/client.py`**: one async client. It always sends `"stream": false`,
281
287
  retries only HTTP 429, 5xx and network/timeout errors (with capped exponential
282
288
  backoff that honours `Retry-After`), and fails on the first 401/403/4xx with a
283
289
  message naming the variable to fix. The key is only ever a request header.
284
- - **`core/agent.py`** — an agent is a role, a system prompt and per-agent
290
+ - **`core/agent.py`**: an agent is a role, a system prompt and per-agent
285
291
  sampling defaults. `ask()` records usage and raises if the reply is blank;
286
292
  `ask_json()` additionally requires parseable JSON (optionally a pydantic schema).
287
- - **`core/crew.py`** — runs agents as sequential steps or parallel stages and
293
+ - **`core/crew.py`**: runs agents as sequential steps or parallel stages and
288
294
  turns any failure into a `CrewFailedError` that lists every failed agent.
289
- - **`core/usage.py`** — per-agent calls, tokens, retries and latency, taken from
295
+ - **`core/usage.py`**: per-agent calls, tokens, retries and latency, taken from
290
296
  the provider's `usage` object. Calls without usage are counted as "not reported",
291
297
  never estimated.
292
298
 
@@ -351,10 +357,10 @@ watching them fail; see [docs/porting.md](https://github.com/aimanmalib/crewforg
351
357
 
352
358
  crewforge was built with AI coding assistance (Claude Code) under the
353
359
  direction of its author, Muhammad Aiman. It consolidates four earlier tools by
354
- the same author — [codeguard](https://github.com/aimanmalib/codeguard),
360
+ the same author ([codeguard](https://github.com/aimanmalib/codeguard),
355
361
  [documind](https://github.com/aimanmalib/documind),
356
362
  [apiforge](https://github.com/aimanmalib/apiforge) and
357
- [contentforge](https://github.com/aimanmalib/contentforge) — whose test suites
363
+ [contentforge](https://github.com/aimanmalib/contentforge)), whose test suites
358
364
  were carried over into this repository (see [docs/porting.md](https://github.com/aimanmalib/crewforge/blob/main/docs/porting.md)
359
365
  for what was ported, re-targeted at the shared core, or dropped and why).
360
366
 
@@ -377,10 +383,52 @@ Please report vulnerabilities privately through
377
383
  See [SECURITY.md](https://github.com/aimanmalib/crewforge/blob/main/SECURITY.md) for scope notes (what is sent to your provider,
378
384
  and what `validate` executes).
379
385
 
380
- ## License
386
+ ## Bahasa Melayu
387
+
388
+ crewforge ialah alat baris arahan dan pustaka Python yang menjalankan satu kru ejen LLM melalui lima resipi:
389
+ semakan kod (`review`), soal jawab dokumen (`ask`, `summarize`), penjanaan projek API FastAPI (`scaffold`,
390
+ `validate`), penulisan kandungan (`write`) dan bantuan penulisan akademik yang jujur (`academic`). Ia berfungsi
391
+ dengan mana-mana penyedia serasi OpenAI, termasuk model tempatan melalui Ollama atau llama.cpp. Kunci API hanya
392
+ dibaca dari pemboleh ubah persekitaran, tidak pernah ditulis ke fail.
393
+
394
+ **Mengapa satu kru.** crewforge menggabungkan empat alat lama (codeguard, documind, apiforge, contentforge) yang
395
+ masing-masing menyimpan salinan sendiri bagi rangka yang sama. Salinan itu sudah berbeza dan setiap satu
396
+ menyembunyikan kegagalan dengan cara sendiri. Kini teras dikongsi: pembaikan dibuat sekali, dan setiap alat menjadi
397
+ resipi di atas teras itu.
398
+
399
+ **Gagal dengan jelas.** Larian yang ejennya memulangkan jawapan kosong atau tidak boleh dihurai, atau pengesah
400
+ yang tidak menyemak apa-apa, keluar dengan kod 1 dan menamakan ejen itu. Kod keluar: `0` berjaya, `1` larian
401
+ gagal, `2` ralat penggunaan atau konfigurasi. Bilangan token diambil daripada laporan penyedia sahaja, tidak
402
+ dianggar.
403
+
404
+ **Resipi `academic`.** Membantu pelajar dan penyelidik dengan kerja mereka **sendiri**: merancang dari taklimat
405
+ tugasan, memberi ulasan atas draf tanpa menulis semula, memformat rujukan yang diberi pengguna (APA 7, IEEE,
406
+ Harvard) tanpa menambah rujukan baharu, dan menulis pernyataan penggunaan AI daripada rekod langkah yang
407
+ dijalankan. Output dalam bahasa Inggeris atau Bahasa Melayu (`--language ms`); output BM disemak untuk bentuk
408
+ Indonesia seperti *karena* atau *kualitas*. Sumber yang dicadangkan model dilabel UNVERIFIED, atau LIKELY
409
+ FABRICATED jika tiada DOI, URL atau ISBN. Tiada ciri "humanise" atau mengelak pengesan AI.
410
+
411
+ **Pasang dan guna.**
412
+
413
+ ```bash
414
+ pip install crewforge # Python 3.10 hingga 3.14
415
+ pip install "crewforge[docs,api]" # pilihan: PDF/DOCX dan semakan aplikasi FastAPI
416
+ export OPENAI_API_KEY=sk-... # atau penyedia lain, lihat `crewforge providers`
417
+ crewforge review src/
418
+ crewforge academic feedback draf.md --brief taklimat.md --language ms
419
+ ```
420
+
421
+ Senarai penyedia, contoh setiap resipi dan seni bina ada dalam bahagian bahasa Inggeris di atas
422
+ ([Providers](https://github.com/aimanmalib/crewforge#providers), [Recipes](https://github.com/aimanmalib/crewforge#recipes)).
423
+
424
+ ## Licence
425
+
426
+ [MIT](https://github.com/aimanmalib/crewforge/blob/main/LICENSE) © Muhammad Aiman. Made by [Aiman Malib](https://aimanmalib.com), Malaysia.
427
+
428
+ ## Work with Sasa Teguh
381
429
 
382
- [MIT](https://github.com/aimanmalib/crewforge/blob/main/LICENSE) © Muhammad Aiman
430
+ [![Work with Sasa Teguh: book a call](https://raw.githubusercontent.com/sasateguh/.github/main/assets/work-with-sasa-teguh.png)](https://sasateguh.com/book)
383
431
 
384
- ---
432
+ I built this project. I run [Sasa Teguh](https://sasateguh.com), a studio in Malaysia that builds websites found on Google and in AI answers, and sets up systems like this one for businesses.
385
433
 
386
- Built by [Sasa Teguh](https://sasateguh.com) · Malaysia
434
+ [Book a call](https://sasateguh.com/book) · hello@sasateguh.com · [More from Sasa Teguh](https://github.com/sasateguh)
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "crewforge"
7
- version = "0.2.1"
7
+ version = "0.2.2"
8
8
  description = "One crew of LLM agents, five recipes: code review, document Q&A, API scaffolding, content and honest academic-writing help — on any OpenAI-compatible provider."
9
9
  readme = "README.md"
10
10
  license = "MIT"
@@ -1,3 +1,3 @@
1
1
  """crewforge — one crew of LLM agents, five recipes, any OpenAI-compatible provider."""
2
2
 
3
- __version__ = "0.2.1"
3
+ __version__ = "0.2.2"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: crewforge
3
- Version: 0.2.1
3
+ Version: 0.2.2
4
4
  Summary: One crew of LLM agents, five recipes: code review, document Q&A, API scaffolding, content and honest academic-writing help — on any OpenAI-compatible provider.
5
5
  Author: Muhammad Aiman
6
6
  License-Expression: MIT
@@ -56,15 +56,21 @@ Requires-Dist: fastapi>=0.110; extra == "dev"
56
56
  Requires-Dist: httpx>=0.27; extra == "dev"
57
57
  Dynamic: license-file
58
58
 
59
- # crewforge
59
+ <p align="center"><img src="https://raw.githubusercontent.com/aimanmalib/crewforge/main/brand/logo-512.png" width="112" height="112" alt="crewforge"></p>
60
60
 
61
- **One crew of LLM agents, five recipes — code review, document Q&A, API scaffolding, content and honest academic-writing help — on any OpenAI-compatible provider, and it fails loudly instead of pretending.**
61
+ <h1 align="center">crewforge</h1>
62
62
 
63
- [![CI](https://github.com/aimanmalib/crewforge/actions/workflows/ci.yml/badge.svg)](https://github.com/aimanmalib/crewforge/actions/workflows/ci.yml)
64
- [![PyPI](https://img.shields.io/pypi/v/crewforge)](https://pypi.org/project/crewforge/)
65
- [![OpenSSF Scorecard](https://api.scorecard.dev/projects/github.com/aimanmalib/crewforge/badge)](https://scorecard.dev/viewer/?uri=github.com/aimanmalib/crewforge)
66
- ![Python 3.10–3.14](https://img.shields.io/badge/python-3.10%E2%80%933.14-blue)
67
- ![License: MIT](https://img.shields.io/badge/license-MIT-green)
63
+ <p align="center"><a href="https://github.com/aimanmalib/crewforge/actions/workflows/ci.yml"><img src="https://github.com/aimanmalib/crewforge/actions/workflows/ci.yml/badge.svg" alt="CI"></a> <a href="https://pypi.org/project/crewforge/"><img src="https://img.shields.io/pypi/v/crewforge" alt="PyPI"></a> <a href="https://scorecard.dev/viewer/?uri=github.com/aimanmalib/crewforge"><img src="https://api.scorecard.dev/projects/github.com/aimanmalib/crewforge/badge" alt="OpenSSF Scorecard"></a> <img src="https://img.shields.io/badge/python-3.10%E2%80%933.14-blue" alt="Python 3.10–3.14"> <a href="https://github.com/aimanmalib/crewforge/blob/main/LICENSE"><img src="https://img.shields.io/badge/license-MIT-green" alt="License: MIT"></a></p>
64
+
65
+ <p align="center"><b>One crew of LLM agents, five recipes, any OpenAI-compatible provider.</b> · <i>Satu kru ejen LLM, lima resipi, mana-mana penyedia serasi OpenAI.</i><br>
66
+ <a href="https://pypi.org/project/crewforge/">PyPI</a> · <a href="https://github.com/aimanmalib/crewforge/blob/main/CHANGELOG.md">changelog</a> · <a href="https://github.com/aimanmalib/crewforge/blob/main/docs/porting.md">porting notes</a> · Built in Malaysia by <a href="https://aimanmalib.com">Aiman Malib</a></p>
67
+
68
+ crewforge is a command-line tool and Python library that runs a crew of LLM agents through five recipes: code
69
+ review, document Q&A, API scaffolding, content writing and honest academic-writing help. It works with any
70
+ OpenAI-compatible provider, reads API keys only from the environment, and fails loudly instead of pretending: a run
71
+ in which an agent produced nothing exits with code 1 and names that agent.
72
+
73
+ [Bahasa Melayu ↓](#bahasa-melayu)
68
74
 
69
75
  ```bash
70
76
  crewforge review src/ # six reviewers + a summary
@@ -81,7 +87,7 @@ crewforge academic feedback draft.md --brief brief.md --language ms
81
87
 
82
88
  ## Why one crew, many recipes
83
89
 
84
- crewforge started as four separate command-line tools —
90
+ crewforge started as four separate command-line tools:
85
91
  [codeguard](https://github.com/aimanmalib/codeguard),
86
92
  [documind](https://github.com/aimanmalib/documind),
87
93
  [apiforge](https://github.com/aimanmalib/apiforge) and
@@ -95,7 +101,7 @@ showed the copies had drifted and that each hid its failures differently:
95
101
  - apiforge scored a spec with **no endpoints** 100/100;
96
102
  - contentforge wrote the real API key into its YAML file, and sent `${OPENAI_API_KEY}` literally as the key.
97
103
 
98
- crewforge keeps one core — so a fix lands once — and turns each tool into a
104
+ crewforge keeps one core, so a fix lands once, and turns each tool into a
99
105
  *recipe*: a set of agents plus the steps that connect them. The same core rules
100
106
  apply to every recipe: non-streaming requests, bounded retries, usage numbers
101
107
  taken only from the provider, keys only from the environment, and no run that
@@ -290,13 +296,13 @@ Saya menggunakan crewforge academic (versi 0.1.0), sebuah alat berbantukan AI, d
290
296
  - 22 Oktober 2026: Perancangan: alat ini menukar taklimat tugasan (brief-ms.md) kepada 3 soalan kajian, rangka 5 bahagian dan peruntukan perkataan. ...
291
297
  ```
292
298
 
293
- How sources are labelled — there is no "verified" status, because the tool
299
+ How sources are labelled: there is no "verified" status, because the tool
294
300
  cannot check that a source exists:
295
301
 
296
302
  | Source | Label |
297
303
  |---|---|
298
304
  | You supplied it | *supplied by you (not checked online)* |
299
- | The model proposed it, with a DOI, URL or valid ISBN | **UNVERIFIED** — check it |
305
+ | The model proposed it, with a DOI, URL or valid ISBN | **UNVERIFIED**: check it |
300
306
  | The model proposed it with none of those | **LIKELY FABRICATED** |
301
307
  | The model added a DOI/URL/ISBN to a reference you supplied | **UNVERIFIED**, naming the added identifier |
302
308
 
@@ -335,16 +341,16 @@ An unknown provider name is a configuration error, not a silent fallback.
335
341
 
336
342
  <sub>Source: [docs/architecture.mmd](https://github.com/aimanmalib/crewforge/blob/main/docs/architecture.mmd) (re-render with `scripts/render_architecture.py`).</sub>
337
343
 
338
- - **`core/client.py`** — one async client. It always sends `"stream": false`,
344
+ - **`core/client.py`**: one async client. It always sends `"stream": false`,
339
345
  retries only HTTP 429, 5xx and network/timeout errors (with capped exponential
340
346
  backoff that honours `Retry-After`), and fails on the first 401/403/4xx with a
341
347
  message naming the variable to fix. The key is only ever a request header.
342
- - **`core/agent.py`** — an agent is a role, a system prompt and per-agent
348
+ - **`core/agent.py`**: an agent is a role, a system prompt and per-agent
343
349
  sampling defaults. `ask()` records usage and raises if the reply is blank;
344
350
  `ask_json()` additionally requires parseable JSON (optionally a pydantic schema).
345
- - **`core/crew.py`** — runs agents as sequential steps or parallel stages and
351
+ - **`core/crew.py`**: runs agents as sequential steps or parallel stages and
346
352
  turns any failure into a `CrewFailedError` that lists every failed agent.
347
- - **`core/usage.py`** — per-agent calls, tokens, retries and latency, taken from
353
+ - **`core/usage.py`**: per-agent calls, tokens, retries and latency, taken from
348
354
  the provider's `usage` object. Calls without usage are counted as "not reported",
349
355
  never estimated.
350
356
 
@@ -409,10 +415,10 @@ watching them fail; see [docs/porting.md](https://github.com/aimanmalib/crewforg
409
415
 
410
416
  crewforge was built with AI coding assistance (Claude Code) under the
411
417
  direction of its author, Muhammad Aiman. It consolidates four earlier tools by
412
- the same author — [codeguard](https://github.com/aimanmalib/codeguard),
418
+ the same author ([codeguard](https://github.com/aimanmalib/codeguard),
413
419
  [documind](https://github.com/aimanmalib/documind),
414
420
  [apiforge](https://github.com/aimanmalib/apiforge) and
415
- [contentforge](https://github.com/aimanmalib/contentforge) — whose test suites
421
+ [contentforge](https://github.com/aimanmalib/contentforge)), whose test suites
416
422
  were carried over into this repository (see [docs/porting.md](https://github.com/aimanmalib/crewforge/blob/main/docs/porting.md)
417
423
  for what was ported, re-targeted at the shared core, or dropped and why).
418
424
 
@@ -435,10 +441,52 @@ Please report vulnerabilities privately through
435
441
  See [SECURITY.md](https://github.com/aimanmalib/crewforge/blob/main/SECURITY.md) for scope notes (what is sent to your provider,
436
442
  and what `validate` executes).
437
443
 
438
- ## License
444
+ ## Bahasa Melayu
445
+
446
+ crewforge ialah alat baris arahan dan pustaka Python yang menjalankan satu kru ejen LLM melalui lima resipi:
447
+ semakan kod (`review`), soal jawab dokumen (`ask`, `summarize`), penjanaan projek API FastAPI (`scaffold`,
448
+ `validate`), penulisan kandungan (`write`) dan bantuan penulisan akademik yang jujur (`academic`). Ia berfungsi
449
+ dengan mana-mana penyedia serasi OpenAI, termasuk model tempatan melalui Ollama atau llama.cpp. Kunci API hanya
450
+ dibaca dari pemboleh ubah persekitaran, tidak pernah ditulis ke fail.
451
+
452
+ **Mengapa satu kru.** crewforge menggabungkan empat alat lama (codeguard, documind, apiforge, contentforge) yang
453
+ masing-masing menyimpan salinan sendiri bagi rangka yang sama. Salinan itu sudah berbeza dan setiap satu
454
+ menyembunyikan kegagalan dengan cara sendiri. Kini teras dikongsi: pembaikan dibuat sekali, dan setiap alat menjadi
455
+ resipi di atas teras itu.
456
+
457
+ **Gagal dengan jelas.** Larian yang ejennya memulangkan jawapan kosong atau tidak boleh dihurai, atau pengesah
458
+ yang tidak menyemak apa-apa, keluar dengan kod 1 dan menamakan ejen itu. Kod keluar: `0` berjaya, `1` larian
459
+ gagal, `2` ralat penggunaan atau konfigurasi. Bilangan token diambil daripada laporan penyedia sahaja, tidak
460
+ dianggar.
461
+
462
+ **Resipi `academic`.** Membantu pelajar dan penyelidik dengan kerja mereka **sendiri**: merancang dari taklimat
463
+ tugasan, memberi ulasan atas draf tanpa menulis semula, memformat rujukan yang diberi pengguna (APA 7, IEEE,
464
+ Harvard) tanpa menambah rujukan baharu, dan menulis pernyataan penggunaan AI daripada rekod langkah yang
465
+ dijalankan. Output dalam bahasa Inggeris atau Bahasa Melayu (`--language ms`); output BM disemak untuk bentuk
466
+ Indonesia seperti *karena* atau *kualitas*. Sumber yang dicadangkan model dilabel UNVERIFIED, atau LIKELY
467
+ FABRICATED jika tiada DOI, URL atau ISBN. Tiada ciri "humanise" atau mengelak pengesan AI.
468
+
469
+ **Pasang dan guna.**
470
+
471
+ ```bash
472
+ pip install crewforge # Python 3.10 hingga 3.14
473
+ pip install "crewforge[docs,api]" # pilihan: PDF/DOCX dan semakan aplikasi FastAPI
474
+ export OPENAI_API_KEY=sk-... # atau penyedia lain, lihat `crewforge providers`
475
+ crewforge review src/
476
+ crewforge academic feedback draf.md --brief taklimat.md --language ms
477
+ ```
478
+
479
+ Senarai penyedia, contoh setiap resipi dan seni bina ada dalam bahagian bahasa Inggeris di atas
480
+ ([Providers](https://github.com/aimanmalib/crewforge#providers), [Recipes](https://github.com/aimanmalib/crewforge#recipes)).
481
+
482
+ ## Licence
483
+
484
+ [MIT](https://github.com/aimanmalib/crewforge/blob/main/LICENSE) © Muhammad Aiman. Made by [Aiman Malib](https://aimanmalib.com), Malaysia.
485
+
486
+ ## Work with Sasa Teguh
439
487
 
440
- [MIT](https://github.com/aimanmalib/crewforge/blob/main/LICENSE) © Muhammad Aiman
488
+ [![Work with Sasa Teguh: book a call](https://raw.githubusercontent.com/sasateguh/.github/main/assets/work-with-sasa-teguh.png)](https://sasateguh.com/book)
441
489
 
442
- ---
490
+ I built this project. I run [Sasa Teguh](https://sasateguh.com), a studio in Malaysia that builds websites found on Google and in AI answers, and sets up systems like this one for businesses.
443
491
 
444
- Built by [Sasa Teguh](https://sasateguh.com) · Malaysia
492
+ [Book a call](https://sasateguh.com/book) · hello@sasateguh.com · [More from Sasa Teguh](https://github.com/sasateguh)
File without changes
File without changes