autogrammar

todo2code (t2c)

Community autogrammar
Updated

Dependency-free Python SDK for todo2code A2A and the local TypeScript runtime

todo2code (t2c)

AI Cost Tracking

PyPI Version Python LicenseAI Cost Human Time Model

  • 🤖 LLM usage: $3.8584 (110 commits)
  • 👤 Human dev: ~$3603 (36.0h @ $100/h, 30min dedup)

Generated on 2026-08-01 using openrouter/qwen/qwen3-coder-next

License

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 (JDKCompiler Tree API), Rust (syn) i PHP (token_get_all z TOKEN_PARSE). Toolchainy poza Node są opcjonalne — braknarzę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.

Governance policy-as-code

Repozytorium stosuje wellmanifest/new-project 0.8.0. Każda wieloetapowazmiana wymaga aktywnego project/ticket-{NNN}, planu przedstawionego przedimplementacją oraz intent v2 ograniczającego workstream, dozwolone ścieżki,zależności, konflikty i integrację. Kilka ticketów może być aktywnych wyłączniew różnych workstreamach i bez nakładania zakresu zapisu; jeden branch/PR musirozwiązać się do dokładnie jednego ticketu. make governance emituje stabilnekody GOV-* i sprawdza integralność przypiętych plików, własność user-*.md,graf zależności, zakres, Docker oraz profile Node/Docker. W Pull Request CIwymaga niezależnego GitHub Review; wpis agenta w Markdown nie jest zaufanymzatwierdzeniem merge. Trwałe instrukcje zawiera AGENTS.md.

Bramka governance przed pushem

make governance porównuje drzewo robocze z HEAD. CI porównujebase..head całej gałęzi. To są różne pytania, więc część diagnostyk jestlokalnie niewidoczna i potrafi odrzucić Pull Request dopiero po pełnej rundzieCI. Przed każdym pushem uruchom formę CI, z gałęzi, którą wypychasz, itraktuj niezerowy kod wyjścia jako blokujący:

bash project/governance-check.sh --actor ci \
  --base "$(git merge-base origin/main HEAD)" --head HEAD

Forma robocza nie widzi GOV-INTENT-003 (intent musi trafić do commituwcześniejszego niż autoryzowana przez niego implementacja), GOV-TICKET-001(zamknięty ticket nie ma władzy nad ścieżkami implementacyjnymi) ani zakresuworkstreamu liczonego po całym diffie gałęzi.

Uruchamiaj to z właściwej gałęzi: --base/--head wybierają diff, ale aktywnyticket i intent są nadal czytane z drzewa roboczego, więc wywołanie z innejgałęzi ocenia diff jednej gałęzi względem ticketu drugiej i zwraca werdykt bezznaczenia.

Stan projektu

Wersja 0.5.0 ma działającą ścieżkę źródła → kanoniczny DSL → graf →diagnostyka/Intent vs Reality → raport oraz zamknięty, reviewowalny przepływDSL2TODO. Kontrakty t2c.conclusion/v1, t2c.todo-proposal/v1,t2c.todo-patch/v1, t2c.code-change-plan/v1,t2c.code-change-acceptance/v1 i t2c.code-change-close-result/v1 mają jawnekontrakty oraz proweniencję. CLI, MCP, A2A i pięć SDKpotrafią syntetyzować zadania, klasyfikować duplikaty, renderować audytowanyTODO.patch i zastosować go wyłącznie po jawnej akceptacji jego hasha. Głównypipeline może zapisać artefakty review przez --task-mode, lecz nigdy sam niemodyfikuje TODO.md.

Otwarte diagnostyki implementacyjne można przekształcić w ugruntowany planzmiany kodu, hash-bound review i strukturalną propozycję source patch, a poimplementacji ocenić przez ponowną analizę grafu. Pipeline nigdy nie stosujepatcha automatycznie; osobne apply-source-patch wymaga kompletnego diffu,tożsamości zatwierdzającego i dokładnego patchHash. Diagram i polecenia zawieradocs/CODE_CHANGE_PLANS.md.

Aktualna macierz komponentów, wyniki walidacji, znane ograniczenia i projektdocelowego DSL2TODO znajdują się wdocs/PROJECT_STATUS.md. Priorytety implementacyjnesą utrzymywane w TODO.md.

Czy projekt jest kompletny? Nie — warstwa deterministyczna jest operacyjniedojrzała, natomiast semantyczna mierzy niskie pokrycie na obcych repozytoriach.Ocenę dystansu do wydania, kryteria zamknięcia i listę blokerów z pomiarami zawieradocs/READINESS.md.

Komunikację zespołu można zapisywać append-only w project/<ticket>/. Głównypipeline domyślnie zachowuje uczestnika i rolę human|agent, porównujewypowiedzi z dowodami Git/AST, zapisuje analizę w manifeście i dodaje problemydo diagnostyki. Claim agenta pozostaje claimem, nigdy faktem wykonania.Kontrakt plików i gotowe polecenia opisujedocs/TEAM_COMMUNICATION.md.Opcjonalny project/participants.json wiąże kanoniczne human:<id> iagent:<id> z autorami Git, identyfikatorami A2A oraz aliasami ludzi bezzgadywania tożsamości na podstawie nazw wyświetlanych.

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

reality.svg

GUI

history-ui.png

Granica LLM

Etap Mechanizm LLM
NL → DSL OpenRouter structured output; jawny fallback heurystyczny/TensorFlow tak, domyślnie wymagany
10 commitów Git → DSL git log, diff, heurystyki symboli nie
TypeScript/JavaScript/Python/Go/Java/Rust/PHP → DSL natywne parsery języków; Java Tree API, Rust syn, PHP syntax tokens nie
TODO + CHANGELOG → DSL deterministyczna struktura + audytowane wzbogacanie OpenRouter tak, domyślnie wymagany
Dokumentacja → DSL deterministyczny baseline + opcjonalne OpenRouter structured outputs opcjonalnie
JSON/YAML/TOML, Docker i CI → DSL deterministyczny konwerter struktury konfiguracji nie
project/<ticket>/ komunikacja → DSL + synteza per uczestnik deterministyczny kontrakt; audytowane wzbogacanie OpenRouter tak, domyślnie wymagany
Linkowanie i diagnostyka deterministyczny graf relacji nie
Graf + diagnostyka → propozycje TODO OpenRouter structured output; jawny pusty fallback bez pozornej syntezy tak
Propozycje → patch → approved apply deterministyczna walidacja, renderer i atomowy zapis nie
Diagnostyka → code-change plan → acceptance/close deterministyczny plan dla konkretnych plików (bez vendoringu, binariów i artefaktów runu) oraz bramka plan-set po re-analizie; bez auto-apply i auto-DONE nie
Graf DSL → t2c.conclusion/v1 → raport NL OpenRouter structured output; runtime waliduje cytowania przed deterministycznym renderingiem Markdown tak

Moduły deterministyczne nie importują klienta OpenRouter. Sprawdzają tonpm run verify:no-llm oraz bezcykliczny graf modułów npm run verify:modules.Kompletność i brak duplikatów zmiennych sprawdza npm run verify:env.Osobny wymagany job CI instaluje Temurin JDK 17 i uruchamia fixture adapteraJava z T2C_REQUIRE_JAVA_TEST=1, co zamienia brak runtime w błąd zamiast skipu.Wersjonowany benchmark semantyczny uruchamia npm run evaluate:gold(t2c.gold-dataset/v2; poprzednia próba pozostaje pod evaluate:gold:v1).Mierzy on precision/recall ekstrakcji w czterech kanałach, linkowania osobno dlaexact-target i capability-topic, kodów diagnostycznych (w tym fałszywegoDONE), kompletność cytowań DSL2TODO, deduplikację oraz stabilność dwóchidentycznych przebiegów offline. Luki udokumentowane jako knownGap — dziśpolska proza wobec angielskiego modułu — są raportowane osobno i nie wchodzą doprecision/recall.

Cele symboliczne NL są rozstrzygane względem zaobserwowanych deklaracji AST.Krótki symbol tworzy dowód tylko wtedy, gdy ma jednego właściciela; przy wielumodułach linker abstenuje, a AMBIGUOUS_REQUIREMENT podaje kandydatów i prosio target.path. Jawna ścieżka lub kwalifikowana nazwa może wybrać jeden moduł.Sama ścieżka pozostaje relacją nawigacyjną, lecz nie zamyka deklaracji nowejfunkcji: wymagany jest symbol, temat obecny w wyekstrahowanych możliwościach,uziemiona zgodność z konkretnym faktem/commitem albo zaakceptowany rerank.Rzeczywiste kontrakty NL → DSL oraz graf → wnioski można sprawdzić osobno przeznpm run live:check. Kontrola jest opt-in, używa require-llm, zapisuje tylkozredagowany audyt latencji/tokenów/kosztu i bez klucza kończy się jako SKIPPED;wymagane testy offline nigdy nie zależą od dostępności providera.

Szybki start

Wymagania: Node.js 20+ i Git. Opcjonalne adaptery wymagają odpowiednio Python3.10+, Go, JDK 17+, Cargo/Rust lub PHP 8+.

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óregoaudyt z 2026-07-29 ma 0 podatności. make install-tf instaluje@tensorflow/[email protected] 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.5.0

Poniższa demonstracja używa wersjonowanego repozytorium examples/, nie wymagaklucza ani połączenia z OpenRouter i pozostawia jednoznaczny audyt. Uruchom:

make demo

Polecenie wykonuje kolejno NL → DSL, Git → DSL, AST → DSL, osobne konwerteryTODO/CHANGELOG, deterministyczne konwertery dokumentacji i konfiguracji,linker, diagnostykę i deterministyczne podsumowanie. Następnieanalizuje komunikację examples/project/DEMO-101 osobno dla ludzi i agentów.Wyniki trafiają do examples/.intent-demo/runs/<run-id>/ orazexamples/.intent-communication/. Stan ostatniego runu można wyświetlić bezdodatkowych 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.5.0 ma 227 rekordów, w tym 5 wersjonowanych rekordówkomunikacji. Liczba relacji zależy również odostatnich 10 commitów Git, dlatego po każdym commicie może się prawidłowozmienić i należy odczytać ją z bieżącego grafu:

status: succeeded, runtime: todo2code 0.5.0
naturalLanguageExtraction: succeeded / deterministic
markdownExtraction:        succeeded / deterministic
documentationExtraction:   succeeded / deterministic
summary:                   skipped / deterministic / LLM_DISABLED
records: 227, relations: <zależne od ostatnich 10 commitów>
bySource: agent_log=5, ast=190, changelog=2, document=4, git=10, nl=7, system=6, todo=3

Demo jawnie wyłącza LLM dokumentacji i podsumowania, więc nie korzysta zprywatnego .env, sieci ani fallbacku. Każdy audyt zawiera runtimeVersion, requested/effectivemode, model, czas, licznik rekordów/ostrzeżeń, powód i bezpieczne parametry;apiKey nigdy nie jest zapisywany.

Demonstracja z prawdziwym LLM

make demo jest celowo deterministyczne. Aby uruchomić pełny pipelinesemantyczny z prawdziwym OpenRouterem i bez możliwości ukrycia błędufallbackiem, ustaw klucz w prywatnym .env i uruchom:

make demollm

Target używa LLM dla NL, TODO/CHANGELOG, dokumentacji, komunikacji, syntezyzadań i podsumowania. Kończy się sukcesem tylko wtedy, gdy manifest potwierdzasucceeded / llm / degraded=false oraz metadane odpowiedzi dla każdego z tychsześciu etapów. Szczegółowy przepływ, diagram sekwencji i opis artefaktów są wdocs/DEMOLLM.md.

Artefakty trafiają do examples/.intent-demo-llm. Manifest zawiera model,provider, response ID, czas, tokeny i koszt, ale nie zawiera klucza, promptuani surowej odpowiedzi modelu.

Zweryfikowany przebieg z 2026-07-30:

demollm PASS: 20260730T185205Z-312a0535
naturalLanguageExtraction: deepseek/deepseek-v4-flash · llm
markdownExtraction: qwen/qwen3.7-plus · llm
documentationExtraction: qwen/qwen3.7-plus · llm
communicationAnalysis: deepseek/deepseek-v4-flash · llm
taskSynthesis: qwen/qwen3.7-plus · llm
summary: qwen/qwen3.7-flash · llm

Wnioski task synthesis i summary używają generatora wersji 2. Runtime wiążeich recordIds wyłącznie z rekordami cytowanych diagnostyk, a nieznanydiagnosticId nadal powoduje błąd require-llm. Puste klucze lokalnepropozycji są nadawane deterministycznie i nie trafiają do publicznego DSL.

Brak klucza, timeout, niepoprawny kontrakt albo zdegradowany etap daje błąd.Polecenie jest kosztowym testem live; walidacja offline pozostaje w make demoi npm run verify.

A2A, SDK i UI

Uruchom backend:

npm run a2a

Następnie otwórz http://localhost:8787/ui. Widok pobierze historię zGET /api/runs, domyślnie wybierze dwa ostatnie kompletne runy i pokaże ichdiff 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 wykonujedeterministyczne 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.5.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. Tenkontrolowany 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 niepublikuje nieistniejącego grafu ani nie zmienia latest.json. Przy błędnym IDmodelu kod LLM_INVALID_MODEL zawiera dodatkowo aktualną, posortowaną listę IDz 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=require-llm
# T2C_MARKDOWN_MODE=require-llm
# T2C_COMMUNICATION_MODE=require-llm
# OPENROUTER_MODEL=mistralai/codestral-2508
# Stage-specific OPENROUTER_*_MODEL variables may override this default.

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żejraz 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, pomijasymlinki oraz po raporcie odświeża snapshot, więc własne artefakty nie tworząpętli. t2c init instaluje bazowy .intentignore; --no-initial-reportpozwala 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 config [root] [--out configuration.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 --mode require-llm --out team-summary.md
t2c watch [root] [--interval 60] [--scan-interval 2] [--task TASK.md|none] [--no-summary-llm] [--no-initial-report]
t2c compare-workspace [root] [--base origin/main] [--task TASK.md] [--docs-llm]
t2c propose-code-change intent.graph.json --diagnostics diagnostics.json --out plans.json
t2c propose-source-patch plan.json --out source-patch.json
t2c apply-source-patch source-patch.json --actor reviewer --approval-hash <patchHash>
t2c evaluate-code-change plan.json --before-graph before.json --after-graph after.json --out acceptance.json
t2c close-code-change plans.json --before-graph before.json --after-graph after.json --out close.json
t2c pipeline [root] --task TASK.md --todo TODO.md --changelog CHANGELOG.md
t2c mcp
t2c a2a

extract nl, extract markdown, extract communication, extract docs i summarize mogą korzystać zOpenRouter. Dla NL, Markdown, komunikacji, summarize i bezpośredniej syntezyTODO domyślny require-llm kończy operację błędem przy braku klucza, timeoutcielub odrzuconej odpowiedzi. prefer-llm trzeba wybrać jawnie, aby dopuścićoznaczony fallback, a deterministic świadomie pomija sieć. W Markdown LLM nie może zmienić checkboxa, lifecycle,wersji, daty, kategorii ani provenance — wzbogaca wyłącznie semantykę wpisu.--communication-mode deterministic zachowuje komunikację lokalnie bez sieci;tryby LLM tworzą uziemioną syntezę per uczestnik bez oddawania modelowi kontroli nadidentity, rolą, ticketem, źródłem, lifecycle lub klasą epistemiczną.Dokumentacja bez klucza jest pomijana, a t2c summarize --mode deterministicświadomie nie wykonuje żądania sieciowego. Dawne --fallback pozostaje aliasemzgodności, ale nowe integracje powinny używać --mode.Etap dokumentacji ma osobne limity fragmentu, liczby fragmentów, rekordów,współbieżności i timeoutu (T2C_DOC_*). Najpierw analizuje fragmenty pasującedo ścieżek, symboli, ticketów i wersji wykrytych w pozostałych źródłach; obcięciebudżetu zapisuje ostrzeżenie DOC_CHUNK_BUDGET.

Deterministyczny AST i podział dokumentów korzystają z przyrostowego cache'u<outputDir>/cache/v1, kluczowanego ścieżką, hashem treści oraz wersjonowanymiparametrami ekstraktora. Uszkodzony lub niedostępny wpis jest pomijany iodtwarzany ze źródła. Cache nie przechowuje odpowiedzi OpenRouter; dokumentprzy cache-hit nadal przechodzi bieżące wywołanie providera.

Każdy rekord t2c.intent/v1 zawsze zawiera runtime-ownedmetadata.generation: generator i jego wersję, wersję todo2code, tryb żądany iużyty oraz stan fallbacku. Rekord LLM dodatkowo wymaga providera, rozstrzygniętegomodelu i response ID; rekord deterministyczny ma te trzy pola jawnie równenull. Brak lub niespójna provenance jest błędem kontraktu, a nie opcjonalnąmetadaną. Pełny kształt opisuje docs/DSL.md.

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 samTypeScript 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 plikiuntracked. 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ł koduposiadają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 jawniewskazanego 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 . --no-docs-llm --no-summary-llm

Istniejący TASK.md jest czytany domyślnie; --task none wyłącza to źródło.Opcja --no-summary-llm eliminuje sieciowy etap podsumowania z każdego cyklu.

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: poupływie progu powstaje jeden raport obejmujący wszystko, co się zmieniło. Raportnigdy nie startuje, gdy poprzedni jeszcze trwa, więc wolny pipeline nie tworzynakładających się runów. --no-initial-report pomija raport startowy i czeka napierwszą realną zmianę.

Detekcja opiera się na cyklicznym skanowaniu (rozmiar + mtime), a nie nafs.watch, który zależy od platformy i gubi zdarzenia pod obciążeniem. Skan jesttani, bo katalogi wykluczone są odcinane przed odczytem — node_modules nigdynie jest czytane.

Pliki ignorowane

Watch pomija ścieżki wymienione w trzech plikach, czytanych w tej kolejności:

  1. .gitignore
  2. .dockerignore
  3. .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 katalogikropkowe (.*/.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 dowolnejgłę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ściabuildu, 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
    ├── summary-conclusions.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.

summary-conclusions.json jest strukturalnym źródłem raportu: zawiera wyłączniezwalidowane t2c.conclusion/v1, a team-summary.md jest jego deterministycznąprojekcją połączoną z sekcjami faktów grafu. manifest.json zapisuje równieżruntime.version, bezpieczny snapshot ifingerprint konfiguracji oraz statusy naturalLanguageExtraction,markdownExtraction, documentationExtraction i summary. Status runu degraded jest pokazywanyw CLI, GET /api/runs i UI. Parametry obejmują modele, timeout, temperaturę,limit tokenów, budżet dokumentów, konfigurację adapterów i tryb structuredoutput; klucz API nigdy nie jest zapisywany. Odpowiedzi LLM zapisują zwróconeprzez provider responseId, resolved model/provider oraz usage/cost. Każdyaudyt ekstrakcji zawiera też wersję runtime i bezpieczne parametry. Każda awariapipeline po utworzeniu runu tworzy manifest status=failed z kodem i etapem, ale beznieistnieją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_config, extract_markdown, extract_docs, extract_communication, analyze_communication, link, diagnose, diff, diff_files, diff_git, reality, compare_workspace, summarize, pipeline, propose_todo, render_todo, apply_todo. Serwer udostępnia też zasoby t2c://latest/*, w tym analizę komunikacji i artefakty review/apply.

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: truezwraca projekcję przeznaczoną dla UI: fingerprinty, liczniki summary i opcjonalnySVG, 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 implementacjiDSL 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 serweraA2A. 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 restarciei 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 katalogowachroni idempotency i aktualizacje między procesami; ścieżka podlega tym samymograniczeniom T2C_ROOT co pozostałe operacje runtime'u.

OpenRouter

Runtime używa POST /api/v1/chat/completions. Wszystkie etapy semantyczneproszą o response_format: json_schema, wymuszająprovider.require_parameters, a przy braku wsparcia endpointu próbująkontrolowanego fallbacku json_object. Opcjonalny plugin response-healingjest sterowany przez .env. Osobny OPENROUTER_TASK_MODEL wybiera model dlagraf + diagnostyka → zadania i domyślnie dziedziczy OPENROUTER_MODEL.

Domyślny mistralai/codestral-2508 przeszedł pełną kontrolę live 6/6: 57,129 s,118 920 tokenów i $0.037994, bez fallbacku lub degradacji. Na tym samymkontrakcie google/gemini-3-flash-preview również przeszedł 6/6, adeepseek/deepseek-v4-pro przekroczył 900-sekundowy budżet. Każdybezpośredni ekstraktor wykonuje najwyżej jedną próbę korekcyjną po odrzuceniuodpowiedzi i ponownie podaje dokładny JSON Schema; walidacja pozostaje takasama, a obie odpowiedzi zachowują model, providera, tokeny i koszt w audycie.

Wszystkie siedem produkcyjnych granic structured output używa jednegokanonicznego kontraktu na etap: z niego powstaje schema wysyłana do providera iparser TypeScript wykonywany przed odczytem odpowiedzi. Runtime odrzuca obcepola, brakujące klucze, typy i wartości poza zakresem bez ich semantycznego„naprawiania”; uziemienie cytowań jest następną, osobną kontrolą. Polecenianpm run verify:structured-responses i npm run verify:schemas blokują powrótdriftu oraz nieaktualny publikowany schemat dokumentów.

Klucz nie jest zapisywany do artefaktów, logów ani odpowiedzi MCP/A2A. doctor pokazuje jedynie status configured/not configured.

Ten sam etap jest dostępny przez CLI i publiczne API TypeScript:

node dist/src/cli.js propose-todo .intent/runs/<run>/intent.graph.json \
  --diagnostics .intent/runs/<run>/diagnostics.json \
  --mode require-llm --out .intent/runs/<run>/task-synthesis.json

Odpowiedniki render-todo i apply-todo opisujedocs/CLI_GUIDE.md. API biblioteki pozostaje dostępne:

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 osobnerawDiagnosticActions; nie są one oznaczane jako wynik semantycznej syntezy.

Review i zastosowanie TODO.patch

writeTodoPatchArtifacts przyjmuje wyłącznie zwalidowane newProposalIds izapisuje obok siebie czytelny TODO.patch oraz audyt TODO.patch.json.Renderer zachowuje kolejność zależność-przed-zadaniem, grupuje kolejne zadaniawedług P0–P3 i pokazuje kryteria akceptacji, targety, zależności oraz wszystkieID dowodów. Nie modyfikuje źródłowego TODO.md.

import { applyTodoPatch, writeTodoPatchArtifacts } from 'todo2code';

const written = await writeTodoPatchArtifacts({
  directory: '.intent/runs/<run>',
  todoPath: 'TODO.md',
  todoContent,
  graph,
  diagnostics,
  conclusions: result.conclusions,
  proposals: result.proposals,
  validation: result.validation,
  synthesisAudit: result.audit,
});

// Człowiek najpierw przegląda written.patchPath i kopiuje hash z audytu.
await applyTodoPatch({
  todoPath: 'TODO.md',
  patchPath: written.patchPath,
  auditPath: written.auditPath,
  receiptPath: '.intent/runs/<run>/TODO.patch.receipt.json',
  approval: { actor: '[email protected]', patchHash: written.artifact.renderedPatchHash },
});

Apply odrzuca brak lub błędny hash akceptacji, zmieniony TODO.md i zmienionypatch. Aktualizacja TODO.md używa pliku tymczasowego, fsync i atomowegorename, zachowując dotychczasowe prawa pliku. Receipt zapisuje aktora, czas,hash źródła, patcha i wyniku. Powtórzenie tej samej operacji zwraca wynikidempotentny bez ponownego dopisania. Jeżeli proces zakończy się po rename, aleprzed zapisem receipt, następne wywołanie rozpozna dokładny suffix i hashoryginału, po czym bezpiecznie odtworzy receipt. Każda inna zmiana wymagaponownej syntezy i przeglądu.

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łędziemodelu runtime wraca do heurystyk i zapisuje heuristic_fallback:<powód>.

Docker i Makefile

make setup
make verify
make demo
make docker-build
make docker-smoke
make docker-up
make e2e-core
make e2e-full

Produkcyjny docker-compose.yml montuje repozytoriumT2C_WORKSPACE pod /workspace, wystawia kontenerowy port 8787 jakoT2C_DOCKER_HOST_PORT i zachowuje .intent w analizowanym workspace. Przyzmianie portu hosta należy odpowiednio ustawić również publicznyT2C_A2A_PUBLIC_URL oraz kliencki T2C_A2A_URL.DOCKER_SMOKE_IMAGE pozwala zmienić lokalny tag używany przez smoke test.

Osobny compose.e2e.yml używa Dockerfile.e2e i nie montuje hosta. Profilcore testuje Node/Python, a full dodaje Go 1.23, JDK 17, Rust 1.85 i PHP,odrzuca skipy oraz wymaga zgodności przykładów wszystkich pięciu SDK. Stabilnekody T2C-E2E-*, zakres bramek i sposoby naprawy opisujedocs/E2E.md.

Diagnostyka

Wbudowane klasy obejmują m.in.:

  • PLANNED_NOT_IMPLEMENTED;
  • IMPLEMENTED_NOT_PLANNED;
  • IMPLEMENTED_NOT_DOCUMENTED;
  • CHANGELOG_WITHOUT_IMPLEMENTATION;
  • CONFLICTING_INTENT;
  • AMBIGUOUS_REQUIREMENT — brakujące pole, wieloznaczny symbol lub konfliktsymbolu z target.path, wraz z konkretną sugerowaną poprawką;
  • 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/PIPELINE_DSL_NL.md — diagramy krok po kroku: zbiory → konwertery → Intent DSL → graf → wnioski → raport NL;
  • 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;
  • docs/CODE_CHANGE_PLANS.md — ugruntowany plan zmiany kodu i bramka acceptance po ponownej analizie;
  • docs/READINESS.md — ocena gotowości, zmierzone luki i kryteria wydania;
  • sdk/README.md — SDK dla TypeScript, Pythona, Go, Rusta i PHP;
  • docs/reference/original-monitoring-design.md — materiał wejściowy dostarczony do projektu.

Licencja

Projekt jest udostępniany na warunkach Apache License 2.0.

License

Licensed under Apache-2.0.

MCP Server · Populars

MCP Server · New

    JanYork

    LWC — Proactive Memory for AI Agents

    Agent-driven proactive memory CLI for AI agents — autonomously recall, maintain, and evolve persistent, source-grounded knowledge across sessions.

    Community JanYork
    mixelpixx

    Konnect *BETA Release

    AI-assisted PCB design for KiCAD 10. Native KiCAD plugin — a single Rust binary exposing 171 schematic, layout, routing, design-review, and manufacturing tools to Claude, or the LLM of your choosing

    Community mixelpixx
    mixelpixx

    Nimrod

    Web research for Claude over MCP: quality-scored Google search, clean extraction, deep research. Hosted connector for claude.ai/Desktop/Code + Nimrod Desktop toolkit (skills, agent, hooks).

    Community mixelpixx
    icesixgod

    Codex Trajectory

    Privacy-aware trajectory viewer for local Codex task logs

    Community icesixgod
    Minima-AI-Inc

    minima

    On-premises conversational RAG with configurable containers

    Community Minima-AI-Inc