todo2code
MCP server that extracts and links code, tasks, documentation, and git history into a graph, then diagnoses discrepancies and generates reports.
README
todo2code (t2c)
todo2code buduje wspólny Intent Evidence DSL z poleceń, historii Git, aktualnego kodu, list zadań, changelogu i dokumentacji. Następnie łączy rekordy w graf przepływu wiedzy, wykrywa rozbieżności i generuje raport dla zespołu.
Projekt działa na Node.js/TypeScript. Wielojęzykowe fakty kodu dostarczają
adaptery TypeScript/JavaScript, Python (ast), Go (go/ast), Java (JDK
Compiler Tree API) i Rust (syn). Toolchainy poza Node są opcjonalne — brak
narzędzia daje jawne ostrzeżenie tylko wtedy, gdy repo zawiera pasujące źródła.
Integracje są dostępne przez CLI, MCP/stdio i A2A v1.0/JSON-RPC.
Stan projektu
Wersja 0.4.0 ma działającą ścieżkę źródła → kanoniczny DSL → graf →
diagnostyka/Intent vs Reality → raport. Kontrakty t2c.conclusion/v1 i
t2c.todo-proposal/v1 wraz z walidacją cytowań i provenance są wdrożone, a API
biblioteki potrafi je syntetyzować z grafu i diagnostyki przez OpenRouter.
Integracja DSL2TODO nie jest jeszcze kompletna: obecna lista następnych
działań w raporcie pozostaje projekcją diagnostyki, a CLI/SDK i zatwierdzalny
TODO.patch są kolejnymi punktami P0. API syntezy waliduje już zależności,
priorytety, kryteria i klasyfikuje duplikaty względem istniejącego TODO.
Aktualna macierz komponentów, wyniki walidacji, znane ograniczenia i projekt
docelowego DSL2TODO znajdują się w
docs/PROJECT_STATUS.md. Priorytety implementacyjne
są utrzymywane w TODO.md.
Komunikację zespołu można zapisywać append-only w project/<ticket>/. Konwerter
zachowuje uczestnika i rolę human|agent, a t2c communication porównuje
wypowiedzi z dowodami Git/AST osobno dla każdego uczestnika. Kontrakt plików i
gotowe polecenia opisuje
docs/TEAM_COMMUNICATION.md.
Praktyczny przebieg CLI — od instalacji przez tryb offline/LLM po diff,
Intent vs Reality, komunikację i automatyczną kontrolę wszystkich przykładów —
opisuje docs/CLI_GUIDE.md.
Reality vs Intent
GUI

Granica LLM
| Etap | Mechanizm | LLM |
|---|---|---|
| NL → DSL | OpenRouter structured output; jawny fallback heurystyczny/TensorFlow | tak, domyślnie preferowany |
| 10 commitów Git → DSL | git log, diff, heurystyki symboli |
nie |
| TypeScript/JavaScript/Python/Go/Java/Rust AST → DSL | natywne parsery języków; Java Tree API, Rust syn |
nie |
| TODO + CHANGELOG → DSL | deterministyczna struktura + audytowane wzbogacanie OpenRouter | tak, domyślnie preferowany |
| Dokumentacja → DSL | OpenRouter structured outputs | tak |
project/<ticket>/ komunikacja → DSL |
deterministyczny kontrakt uczestnika, roli i typu wypowiedzi | nie |
| Linkowanie i diagnostyka | deterministyczny graf relacji | nie |
| Graf DSL → raport NL | OpenRouter; wejściem jest tylko graf i diagnostyka | tak |
Moduły deterministyczne nie importują klienta OpenRouter. Sprawdzają to
npm run verify:no-llm oraz bezcykliczny graf modułów npm run verify:modules.
Kompletność i brak duplikatów zmiennych sprawdza npm run verify:env.
Szybki start
Wymagania: Node.js 20+ i Git. Opcjonalne adaptery wymagają odpowiednio Python 3.10+, Go, JDK 17+ lub Cargo/Rust.
cp .env.example .env
npm install
npm run build
node dist/src/cli.js doctor
Zwykłe npm install i make install instalują wyłącznie rdzeń, dla którego
audyt z 2026-07-29 ma 0 podatności. make install-tf instaluje
@tensorflow/tfjs-node@4.22.0 w odizolowanym adapters/tensorflow/node_modules;
jego 8 zgłoszeń nie trafia do drzewa zależności rdzenia. Nie należy stosować
npm audit fix --force, ponieważ proponuje niekompatybilny downgrade.
Demonstracja działania 0.4.0
Poniższa demonstracja używa wersjonowanego repozytorium examples/, nie wymaga
klucza ani połączenia z OpenRouter i pozostawia jednoznaczny audyt. Uruchom:
make demo
Polecenie wykonuje kolejno NL → DSL, Git → DSL, AST → DSL, osobne konwertery
TODO/CHANGELOG, linker, diagnostykę i deterministyczne podsumowanie. Następnie
analizuje komunikację examples/project/DEMO-101 osobno dla ludzi i agentów.
Wyniki trafiają do examples/.intent-demo/runs/<run-id>/ oraz
examples/.intent-communication/. Stan ostatniego runu można wyświetlić bez
dodatkowych narzędzi:
node --input-type=module <<'NODE'
import { readFile } from 'node:fs/promises';
const latest = JSON.parse(await readFile('examples/.intent-demo/latest.json', 'utf8'));
const manifest = JSON.parse(await readFile(`examples/${latest.runDirectory}/manifest.json`, 'utf8'));
const graph = JSON.parse(await readFile(`examples/${manifest.files.graph}`, 'utf8'));
const stages = Object.fromEntries(Object.entries(manifest.stages).map(([name, stage]) => [name, {
status: stage.status,
effectiveMode: stage.effectiveMode,
reason: stage.reason?.code ?? null,
runtimeVersion: stage.runtimeVersion,
}]));
console.log({ status: manifest.status, runtime: manifest.runtime, stages });
console.log({ records: graph.records.length, relations: graph.relations.length, bySource: graph.stats.bySource });
NODE
Weryfikowany wynik dla 0.4.0 ma 202 rekordy. Liczba relacji zależy również od
ostatnich 10 commitów Git, dlatego po każdym commicie może się prawidłowo
zmienić i należy odczytać ją z bieżącego grafu:
status: succeeded, runtime: todo2code 0.4.0
naturalLanguageExtraction: succeeded / deterministic
markdownExtraction: succeeded / deterministic
documentationExtraction: skipped / none
summary: skipped / deterministic / LLM_DISABLED
records: 202, relations: <zależne od ostatnich 10 commitów>
bySource: ast=180, changelog=2, git=10, nl=7, todo=3
Demo jawnie wyłącza LLM dokumentacji i podsumowania, więc nie korzysta z
prywatnego .env, sieci ani fallbacku. Każdy audyt zawiera runtimeVersion, requested/effective
mode, model, czas, licznik rekordów/ostrzeżeń, powód i bezpieczne parametry;
apiKey nigdy nie jest zapisywany.
A2A, SDK i UI
Uruchom backend:
npm run a2a
Następnie otwórz http://localhost:8787/ui. Widok pobierze historię z
GET /api/runs, domyślnie wybierze dwa ostatnie kompletne runy i pokaże ich
diff SVG. Stan serwera można sprawdzić przez:
curl -fsS http://localhost:8787/healthz
# {"status":"ok","service":"todo2code","protocol":"A2A","version":"1.0"}
Ten sam runtime jest dostępny przez SDK. Przykład TypeScript wykonuje deterministyczne NL → DSL i sprawdza audyt, zamiast zakładać, że LLM zadziałał:
import { Todo2CodeClient } from 'todo2code/sdk';
const client = new Todo2CodeClient({ baseUrl: 'http://localhost:8787' });
const result = await client.extractNl('TASK.md', '.', 'deterministic');
console.log(result.records.length); // 10 dla bieżącego TASK.md
console.log(result.audit?.status); // succeeded
console.log(result.audit?.effectiveMode); // deterministic
console.log(result.audit?.runtimeVersion); // 0.4.0
console.log(result.audit?.configuration); // bez apiKey
Odpowiedniki extractNl/extractDocs są dostępne również w Pythonie, Go,
Ruście i PHP; kompletne uruchamialne przykłady znajdują się w sdk/*/examples/.
Widoczna awaria LLM
require-llm nigdy nie przechodzi po cichu na parser deterministyczny. Ten
kontrolowany test kończy się kodem procesu 1:
OPENROUTER_API_KEY= T2C_NL_MODE=require-llm \
node dist/src/cli.js pipeline examples \
--task task.md --todo TODO.md --changelog CHANGELOG.md \
--no-docs-llm --out .intent-failure-demo
Mimo błędu powstaje examples/.intent-failure-demo/runs/<run-id>/manifest.json:
{
"status": "failed",
"failure": {
"stage": "naturalLanguageExtraction",
"code": "LLM_NOT_CONFIGURED",
"message": "OPENROUTER_API_KEY is not configured"
},
"graphFingerprint": null,
"files": {}
}
Manifest zachowuje pełny audyt nieudanego etapu i wersję runtime, ale nie
publikuje nieistniejącego grafu ani nie zmienia latest.json. Przy błędnym ID
modelu kod LLM_INVALID_MODEL zawiera dodatkowo aktualną, posortowaną listę ID
z endpointu OpenRouter /models.
Pełny pipeline bez połączeń LLM (również wtedy, gdy lokalny .env zawiera klucz):
node dist/src/cli.js pipeline examples \
--task task.md \
--todo TODO.md \
--changelog CHANGELOG.md \
--docs 'docs/**/*.md' \
--nl-mode deterministic \
--markdown-mode deterministic \
--no-docs-llm \
--no-summary-llm \
--out .intent-demo
Pełny pipeline z OpenRouter:
# w .env:
# OPENROUTER_API_KEY=...
# T2C_NL_MODE=prefer-llm
# T2C_MARKDOWN_MODE=prefer-llm
# OPENROUTER_NL_MODEL=qwen/qwen3.7-plus
# OPENROUTER_MARKDOWN_MODEL=qwen/qwen3.7-plus
# OPENROUTER_DOC_MODEL=openrouter/auto-beta
# OPENROUTER_SUMMARY_MODEL=openrouter/auto-beta
# OPENROUTER_TASK_MODEL=qwen/qwen3.7-plus
node dist/src/cli.js pipeline /ścieżka/do/repo \
--task project/ticket-014/README.md \
--todo TODO.md \
--changelog CHANGELOG.md \
--docs 'README.md,docs/**/*.md,project/**/*.md'
Tryb ciągły skanuje repozytorium deterministycznie i generuje raport najwyżej raz na wskazany interwał:
node dist/src/cli.js watch . \
--interval 60 \
--scan-interval 2 \
--no-docs-llm \
--out .intent
Watcher scala reguły z .gitignore, .dockerignore i .intentignore, pomija
symlinki oraz po raporcie odświeża snapshot, więc własne artefakty nie tworzą
pętli. t2c init instaluje bazowy .intentignore; --no-initial-report
pozwala czekać na pierwszą rzeczywistą zmianę.
CLI
t2c init [root]
t2c doctor
t2c extract nl <file> [--root .] [--out nl.intent.jsonl]
t2c extract git [--root .] [--count 10] [--out git.intent.jsonl]
t2c extract ast [root] [--out ast.intent.jsonl]
t2c extract markdown [--todo TODO.md] [--changelog CHANGELOG.md] [--markdown-mode deterministic|prefer-llm|require-llm]
t2c extract docs [--patterns 'README.md,docs/**/*.md']
t2c link <*.intent.jsonl>... --out intent.graph.json
t2c diagnose intent.graph.json --out diagnostics.json
t2c diff before.graph.json after.graph.json --out graph.diff.json --svg graph.diff.svg
t2c diff --mode files before.ts after.ts --svg files.diff.svg --html files.diff.html
t2c diff --mode git . --rev HEAD --svg worktree.diff.svg
t2c reality intent.graph.json --diagnostics diagnostics.json --svg reality.svg --md reality.md
t2c summarize intent.graph.json --diagnostics diagnostics.json --out team-summary.md
t2c watch [root] [--interval 60] [--scan-interval 2] [--no-initial-report]
t2c compare-workspace [root] [--base origin/main] [--task TASK.md] [--docs-llm]
t2c pipeline [root] --task TASK.md --todo TODO.md --changelog CHANGELOG.md
t2c mcp
t2c a2a
extract nl, extract markdown, extract docs i summarize mogą korzystać z
OpenRouter. Dla NL oraz Markdown prefer-llm jest trybem domyślnym: awaria daje
oznaczony fallback; require-llm kończy operację błędem, a deterministic
świadomie pomija sieć. W Markdown LLM nie może zmienić checkboxa, lifecycle,
wersji, daty, kategorii ani provenance — wzbogaca wyłącznie semantykę wpisu.
Dokumentacja bez klucza jest pomijana, a raport może użyć oznaczonego fallbacku.
Etap dokumentacji ma osobne limity fragmentu, liczby fragmentów, rekordów,
współbieżności i timeoutu (T2C_DOC_*). Najpierw analizuje fragmenty pasujące
do ścieżek, symboli, ticketów i wersji wykrytych w pozostałych źródłach; obcięcie
budżetu zapisuje ostrzeżenie DOC_CHUNK_BUDGET.
Origin vs bieżący workspace
Porównanie nie wykonuje checkoutu w katalogu użytkownika. Runtime rozwiązuje bazę do pełnego SHA, tworzy prywatny tymczasowy Git worktree i uruchamia ten sam TypeScript pipeline na bazie oraz aktualnym filesystemie:
node dist/src/cli.js compare-workspace . --base origin/main --out .intent
Stan workspace obejmuje lokalne commity, indeks, zmiany unstaged i pliki
untracked. Wynik t2c.workspace-comparison/v1 zawiera ahead/behind, listę
zmienionych plików, diff rekordów i relacji oraz zmianę metryk Intent vs Reality:
pełne alignmentRate, pokrycie deklarowanej intencji implementacją, udział kodu
posiadającego plan i dokumentację, gaps oraz liczniki diagnostyk. Trend może być
improved, regressed, mixed albo unchanged. Artefakty trafiają do:
.intent/comparisons/<comparison-id>/
├── comparison.json
├── trend.md
├── intent-diff.svg
├── base.graph.json
├── workspace.graph.json
├── base-reality.md
├── workspace-reality.md
└── workspace-reality.svg
Narracyjne podsumowania obu przebiegów są zawsze deterministyczne i nie wykonują
zbędnych zapytań LLM. Dokumentacja LLM po obu stronach jest opcjonalna, ponieważ
podwaja liczbę zapytań i może wprowadzać niedeterministyczny szum. Jeśli podano
--task, ekstrakcja NL respektuje T2C_NL_MODE i jest osobno audytowana:
t2c compare-workspace . --base origin/main --docs-llm \
--docs 'README.md,docs/**/*.md,.intent/runs/<run-id>/team-summary.md' \
--doc-excludes 'node_modules/**,.git/**,dist/**,TODO.md,CHANGELOG.md'
Usunięcie .intent/** z --doc-excludes jest wymagane tylko dla jawnie
wskazanego historycznego raportu. Nie należy używać szerokiego .intent/**/*.md,
bo bieżące raporty zaczęłyby zasilać kolejne runy.
Tryb obserwowania
t2c watch pilnuje lokalnych zmian i generuje świeży raport najwyżej raz na minutę:
node dist/src/cli.js watch . --task TASK.md --no-docs-llm
Obowiązują dwa niezależne czasy:
| Opcja | Domyślnie | Znaczenie |
|---|---|---|
--scan-interval |
2 s | jak szybko zmiana zostaje zauważona |
--interval |
60 s | minimalny odstęp między dwoma raportami |
Zmiany napływające częściej niż --interval są kumulowane, a nie kolejkowane: po
upływie progu powstaje jeden raport obejmujący wszystko, co się zmieniło. Raport
nigdy nie startuje, gdy poprzedni jeszcze trwa, więc wolny pipeline nie tworzy
nakładających się runów. --no-initial-report pomija raport startowy i czeka na
pierwszą realną zmianę.
Detekcja opiera się na cyklicznym skanowaniu (rozmiar + mtime), a nie na
fs.watch, który zależy od platformy i gubi zdarzenia pod obciążeniem. Skan jest
tani, bo katalogi wykluczone są odcinane przed odczytem — node_modules nigdy
nie jest czytane.
Pliki ignorowane
Watch pomija ścieżki wymienione w trzech plikach, czytanych w tej kolejności:
.gitignore.dockerignore.intentignore
Późniejszy plik wygrywa, więc .intentignore może przywrócić ścieżkę przez !wzorzec.
.intentignore jest zakładany przez t2c init i wyklucza m.in. wszystkie katalogi
kropkowe (.*/ — .git, .idea, .venv, .github, .cache), katalog .intent/
z własnymi raportami, wyjścia buildu (node_modules/, dist/, target/,
__pycache__/), lockfile'e oraz logi i pliki tymczasowe.
Składnia jest zgodna z gitignore: komentarze #, negacja !, końcowy /
ogranicza regułę do katalogów, wzorzec bez ukośnika dopasowuje się na dowolnej
głębokości, a ** przechodzi przez katalogi. Reguły .dockerignore są
interpretowane tą samą semantyką, czyli nieco szerzej niż robi to Docker
(kotwiczący wzorce do korzenia kontekstu) — wpisy w tym pliku nazywają wyjścia
buildu, więc wykluczenie zagnieżdżonej kopii jest zamierzone.
Artefakty runu
.intent/
├── latest.json
└── runs/<run-id>/
├── nl.intent.jsonl
├── git.intent.jsonl
├── ast.intent.jsonl
├── todo.intent.jsonl
├── changelog.intent.jsonl
├── document.intent.jsonl
├── intent.graph.json
├── diagnostics.json
├── team-summary.md
└── manifest.json
Każdy rekord zawiera identyfikator, statement, lifecycle, dokładne źródło, hash treści, klasę epistemiczną, confidence i podstawy wnioskowania. Fakty AST mają confidence 1.0. Rekordy wygenerowane przez LLM są oznaczone jako llm_inference i mają pułap zależny od struktury źródła: 0.94 dla wzbogaconych pozycji TODO/CHANGELOG, 0.90 dla prozy NL i 0.85 dla dokumentacji. Żaden z nich nie sięga poziomu obserwacji deterministycznej — pełną tabelę zawiera docs/DSL.md.
manifest.json zapisuje również runtime.version, bezpieczny snapshot i
fingerprint konfiguracji oraz statusy naturalLanguageExtraction,
markdownExtraction, documentationExtraction i summary. Status runu degraded jest pokazywany
w CLI, GET /api/runs i UI. Parametry obejmują modele, timeout, temperaturę,
limit tokenów, budżet dokumentów, konfigurację adapterów i tryb structured
output; klucz API nigdy nie jest zapisywany. Odpowiedzi LLM zapisują zwrócone
przez provider responseId, resolved model/provider oraz usage/cost. Każdy
audyt ekstrakcji zawiera też wersję runtime i bezpieczne parametry. Każda awaria
pipeline po utworzeniu runu tworzy manifest status=failed z kodem i etapem, ale bez
nieistniejącego grafu ani aktualizacji latest.json.
MCP
Uruchomienie serwera stdio:
node dist/src/interfaces/mcp.js
Przykładowa konfiguracja hosta MCP:
{
"mcpServers": {
"todo2code": {
"command": "node",
"args": ["/absolute/path/todo2code/dist/src/interfaces/mcp.js"],
"env": {
"T2C_ROOT": "/absolute/path/workspace",
"OPENROUTER_API_KEY": "${OPENROUTER_API_KEY}"
}
}
}
}
Dostępne narzędzia: extract_nl, extract_git, extract_ast, extract_markdown, extract_docs, extract_communication, analyze_communication, link, diagnose, diff, diff_files, diff_git, reality, compare_workspace, summarize, pipeline. Serwer udostępnia też zasoby t2c://latest/*.
Diff DSL, SVG i SDK
Porównanie dwóch grafów zwraca kanoniczny t2c.diff/v1 z rekordami added, removed, changed i liczbą elementów bez zmian. --mode files tworzy deterministyczny diff linii t2c.filediff/v1, a --mode git stosuje ten sam silnik do rewizji, indeksu lub drzewa roboczego. Dostępne są widoki SVG, HTML oraz unified diff; nie wymagają bibliotek renderujących i nie wykonują treści pochodzącej z plików.
Polecenie t2c reality projektuje pojedynczy graf do t2c.reality/v1: zestawia deklaracje z taska, TODO i dokumentacji z faktami Git/AST, a rozbieżności pokazuje jako SVG albo tabelę Markdown.
Po uruchomieniu A2A dostępne są:
- frontend:
http://localhost:8787/ui— pobiera historię z.intent/runs, domyślnie wybiera dwa najnowsze kompletne runy i automatycznie pokazuje ich diff SVG; - historia runów:
GET http://localhost:8787/api/runs; - REST diff:
POST http://localhost:8787/api/diff; - A2A/MCP action:
diff.
POST /api/diff domyślnie zwraca pełny t2c.diff/v1. Ustawienie compact: true
zwraca projekcję przeznaczoną dla UI: fingerprinty, liczniki summary i opcjonalny
SVG, bez pełnych tablic rekordów oraz relacji.
SDK TypeScript/JavaScript:
import { Todo2CodeClient } from 'todo2code/sdk';
const client = new Todo2CodeClient({ baseUrl: 'http://localhost:8787' });
const result = await client.diffGraphs(beforeGraph, afterGraph);
console.log(result.diff.summary, result.svg);
const files = await client.diffTextFiles('before.ts', 'after.ts', { includeHtml: true });
const reality = await client.reality(afterGraph);
const comparison = await client.compareWorkspace({ root: '.', base: 'origin/main' });
SDK Python nie ma zewnętrznych zależności:
from sdk.python import Todo2CodeClient
client = Todo2CodeClient("http://localhost:8787")
result = client.diff_graphs(before_graph, after_graph)
print(result["diff"]["summary"])
files = client.diff_text_files("before.ts", "after.ts", include_html=True)
reality = client.reality(after_graph)
comparison = client.compare_workspace(root=".", base="origin/main")
Można go także zainstalować przez python3 -m pip install ./sdk/python i importować jako todo2code_sdk.
Uruchamialne przykłady znajdują się w examples/sdk/typescript.mjs i examples/sdk/python.py.
Pomiary oraz bezpieczne i semantycznie istotne dalsze optymalizacje opisuje docs/OPTIMIZATION.md.
SDK dla pięciu języków
Katalog sdk/ zawiera pełne klienty A2A v1.0 udostępniające wszystkie akcje runtime'u (nie tylko diff), wraz z typami Intent DSL:
| Język | Katalog | Zależności | Klasa |
|---|---|---|---|
| TypeScript / Node | sdk/typescript/ |
brak | T2CClient |
| Python 3.10+ | sdk/python/ |
brak | T2CClient |
| Go 1.21+ | sdk/go/ |
brak | todo2code.Client |
| Rust 1.70+ | sdk/rust/ |
serde_json |
todo2code::Client |
| PHP 8.1+ | sdk/php/ |
brak | Todo2Code\Client |
Każdy język ma uruchamialny przykład w sdk/<język>/examples/. Wszystkie przepuszczają ten sam zbiór rekordów przez link i muszą otrzymać identyczny fingerprint grafu — to test wierności round-tripu typów. Szczegóły: sdk/README.md.
Python udostępnia także lokalny TypeScriptRuntime. Nie kopiuje implementacji
DSL do Pythona, tylko uruchamia przez Node.js skompilowany dist/src/cli.js:
make python-wheel
python3 -m pip install .intent-packages/python/todo2code_sdk-*.whl
T2C_TYPESCRIPT_CLI="$PWD/dist/src/cli.js" python3 sdk/python/examples/local_runtime.py
Most obsługuje pipeline, diagnose, graph diff oraz reality bez serwera
A2A. Szczegóły i przykład API: sdk/python/README.md.
Przykładowe repozytoria
examples/backend (HTTP API bez zależności) i examples/frontend (panel DOM bez frameworka) to gotowe wejścia dla runtime'u DSL. Każde ma task.md, TODO.md, CHANGELOG.md, README.md i src/, i celowo zawiera rozbieżności plan↔kod, żeby t2c reality miał co pokazać:
node dist/src/cli.js pipeline examples/backend \
--task task.md --todo TODO.md --changelog CHANGELOG.md \
--docs 'README.md' --no-docs-llm --out .intent
node dist/src/cli.js reality examples/backend/.intent/runs/<run-id>/intent.graph.json \
--diagnostics examples/backend/.intent/runs/<run-id>/diagnostics.json \
--svg reality.svg --md reality.md
A2A v1.0
node dist/src/interfaces/a2a.js
Agent Card:
curl http://localhost:8787/.well-known/agent-card.json
Uruchomienie pipeline przez SendMessage:
curl -s http://localhost:8787/a2a \
-H 'Content-Type: application/json' \
-H 'A2A-Version: 1.0' \
-d '{
"jsonrpc":"2.0",
"id":"req-1",
"method":"SendMessage",
"params":{
"message":{
"messageId":"msg-1",
"role":"ROLE_USER",
"parts":[{
"data":{
"action":"pipeline",
"input":{
"root":".",
"task":"TASK.md",
"includeDocsLlm":false
}
},
"mediaType":"application/json"
}]
}
}
}'
Interfejs A2A jest v1-only: nagłówek A2A-Version: 1.0 (albo parametr zapytania o tej nazwie) jest wymagany. Brak nagłówka oznacza protokół 0.3 i jest odrzucany kodem -32009; aliasy metod v0.3 nie są przyjmowane. GetTask i CancelTask zwracają task bez wrappera, a ListTasks obsługuje filtry, cursor pagination, historyLength oraz includeArtifacts (domyślnie false).
Ustawienie T2C_A2A_TOKEN włącza Bearer authentication i izolację tasków według principalu. Domyślnie MCP i A2A nie mogą analizować ścieżek poza T2C_ROOT; wyjątek wymaga jawnego T2C_ALLOW_OUTSIDE_ROOT=true.
Domyślny task store A2A pozostaje pamięciowy. Aby zachować taski po restarcie i współdzielić je między replikami używającymi tego samego wolumenu, ustaw:
T2C_A2A_TASK_STORE=.intent/a2a-tasks.json
Snapshot jest zapisywany atomowo z uprawnieniami 0600. Blokada katalogowa
chroni idempotency i aktualizacje między procesami; ścieżka podlega tym samym
ograniczeniom T2C_ROOT co pozostałe operacje runtime'u.
OpenRouter
Runtime używa POST /api/v1/chat/completions. Ekstraktory NL i dokumentacji
oraz synteza zadań proszą o response_format: json_schema, wymuszają
provider.require_parameters, a przy braku wsparcia endpointu próbują
kontrolowanego fallbacku json_object. Opcjonalny plugin response-healing
jest sterowany przez .env. Osobny OPENROUTER_TASK_MODEL wybiera model dla
graf + diagnostyka → zadania i domyślnie dziedziczy OPENROUTER_MODEL.
Klucz nie jest zapisywany do artefaktów, logów ani odpowiedzi MCP/A2A. doctor pokazuje jedynie status configured/not configured.
Do czasu dodania komendy propose-todo etap jest publicznym API TypeScript:
import { readFile } from 'node:fs/promises';
import { getConfig, synthesizeTodoProposals } from 'todo2code';
const graph = JSON.parse(await readFile('.intent/runs/<run>/intent.graph.json', 'utf8'));
const diagnostics = JSON.parse(await readFile('.intent/runs/<run>/diagnostics.json', 'utf8'));
const result = await synthesizeTodoProposals(graph, diagnostics, getConfig(), 'require-llm');
console.log(JSON.stringify(result, null, 2));
W prefer-llm awaria daje puste conclusions/proposals i osobne
rawDiagnosticActions; nie są one oznaczane jako wynik semantycznej syntezy.
Opcjonalny TensorFlow
NL i Git zawsze mają deterministyczny klasyfikator słownikowy. Lokalny model TensorFlow można włączyć przez:
T2C_ENABLE_TF=true
T2C_TF_MODEL_PATH=/models/action/model.json
T2C_TF_MODULE_PATH=adapters/tensorflow/node_modules/@tensorflow/tfjs-node/dist/index.js
T2C_TF_LABELS=add,fix,remove,refactor,test,document,configure,analyze,unknown
Najpierw należy wykonać make install-tf. Obok model.json musi znajdować się
vocabulary.json, czyli mapa token → indeks. Model powinien przyjmować tensor
[1, vocabulary_size] i zwracać rozkład klas. Przy braku adaptera lub błędzie
modelu runtime wraca do heurystyk i zapisuje heuristic_fallback:<powód>.
Docker i Makefile
make setup
make verify
make demo
make docker-build
make docker-up
Jedynym plikiem Compose jest docker-compose.yml. Montuje repozytorium
T2C_WORKSPACE pod /workspace, wystawia kontenerowy port 8787 jako
T2C_DOCKER_HOST_PORT i zachowuje .intent w analizowanym workspace. Przy
zmianie portu hosta należy odpowiednio ustawić również publiczny
T2C_A2A_PUBLIC_URL oraz kliencki T2C_A2A_URL.
Diagnostyka
Wbudowane klasy obejmują m.in.:
PLANNED_NOT_IMPLEMENTED;IMPLEMENTED_NOT_PLANNED;IMPLEMENTED_NOT_DOCUMENTED;CHANGELOG_WITHOUT_IMPLEMENTATION;CONFLICTING_INTENT;AMBIGUOUS_REQUIREMENT;UNLINKED_RECORD.
ALIGNED oznacza wyłącznie brak wykrytej blokującej rozbieżności w dostępnych źródłach. Nie nadaje automatycznie statusu DONE i nie zastępuje decyzji człowieka.
Dokumentacja projektu
docs/ARCHITECTURE.md— komponenty i przepływ;docs/DSL.md— model danych i relacje;docs/REQUIREMENTS.md— śledzenie wymagań;docs/PROTOCOLS.md— MCP, A2A i OpenRouter;docs/SECURITY.md— granice dostępu i sekretów;docs/VALIDATION.md— zakres oraz wynik walidacji paczki;docs/OPTIMIZATION.md— zmierzone wąskie gardła runtime'u i zastosowane usprawnienia;sdk/README.md— SDK dla TypeScript, Pythona, Go, Rusta i PHP;docs/reference/original-monitoring-design.md— materiał wejściowy dostarczony do projektu.
Recommended Servers
playwright-mcp
A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.
Magic Component Platform (MCP)
An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.
Audiense Insights MCP Server
Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.
VeyraX MCP
Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.
graphlit-mcp-server
The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.
Kagi MCP Server
An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.
E2B
Using MCP to run code via e2b.
Neon Database
MCP server for interacting with Neon Management API and databases
Exa Search
A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.
Qdrant Server
This repository is an example of how to create a MCP server for Qdrant, a vector search engine.