devflow-cli 10.2.1__py3-none-any.whl → 10.2.3__py3-none-any.whl
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.
- devflow_cli/__init__.py +1 -1
- devflow_cli/core/activity_contracts.py +8 -9
- devflow_cli/core/automatic_evidence.py +10 -3
- devflow_cli/utils/logging.py +5 -4
- {devflow_cli-10.2.1.dist-info → devflow_cli-10.2.3.dist-info}/METADATA +1 -1
- {devflow_cli-10.2.1.dist-info → devflow_cli-10.2.3.dist-info}/RECORD +9 -9
- {devflow_cli-10.2.1.dist-info → devflow_cli-10.2.3.dist-info}/WHEEL +0 -0
- {devflow_cli-10.2.1.dist-info → devflow_cli-10.2.3.dist-info}/entry_points.txt +0 -0
- {devflow_cli-10.2.1.dist-info → devflow_cli-10.2.3.dist-info}/licenses/LICENSE +0 -0
devflow_cli/__init__.py
CHANGED
|
@@ -41,6 +41,7 @@ DOCUMENT_ARTIFACTS = {
|
|
|
41
41
|
"preflight-evidence": "preflight-evidence.md",
|
|
42
42
|
}
|
|
43
43
|
DOCUMENT_ACTIVITIES = set(DOCUMENT_ARTIFACTS)
|
|
44
|
+
READ_ONLY_ACTIVITIES = {"prepare", "verify", "review", "rollback-check"}
|
|
44
45
|
ActivityStatus = Literal["completed", "blocked"]
|
|
45
46
|
|
|
46
47
|
REMOVED_RESULT_FIELDS = ("omissionRecommendations", "reviewedOmissions")
|
|
@@ -456,7 +457,13 @@ def build_activity_contract(
|
|
|
456
457
|
if activity in DOCUMENT_ACTIVITIES:
|
|
457
458
|
artifact = f"{feature_path}/{document_artifact_name(activity, reopened=reopened)}"
|
|
458
459
|
already_changed = [artifact] if artifact in already_changed else []
|
|
459
|
-
if already_changed:
|
|
460
|
+
if already_changed and activity in READ_ONLY_ACTIVITIES:
|
|
461
|
+
constraints.append(
|
|
462
|
+
"Fichiers deja modifies depuis le debut de l'activite, avant son lancement : "
|
|
463
|
+
+ ", ".join(already_changed)
|
|
464
|
+
+ " ; les inspecter, sans les declarer : changedFiles reste vide."
|
|
465
|
+
)
|
|
466
|
+
elif already_changed:
|
|
460
467
|
constraints.append(
|
|
461
468
|
"Fichiers deja modifies depuis le debut de l'activite (comptes dans son "
|
|
462
469
|
"resultat) : " + ", ".join(already_changed)
|
|
@@ -618,8 +625,6 @@ def parse_activity_result(payload: dict[str, Any], contract: ActivityContract) -
|
|
|
618
625
|
raise ValueError("un resultat complete ne peut pas contenir de blockers")
|
|
619
626
|
if contract.activity == "implement" and status == "completed" and not changed_files:
|
|
620
627
|
raise ValueError("implement complete requiert au moins un fichier modifie")
|
|
621
|
-
if contract.activity == "prepare" and changed_files:
|
|
622
|
-
raise ValueError("prepare ne peut pas modifier de fichiers")
|
|
623
628
|
if contract.activity == "prepare" and status == "completed" and not validation_plan:
|
|
624
629
|
raise ValueError("prepare complete requiert un plan de validation")
|
|
625
630
|
if contract.activity in DOCUMENT_ACTIVITIES and status == "completed":
|
|
@@ -636,8 +641,6 @@ def parse_activity_result(payload: dict[str, Any], contract: ActivityContract) -
|
|
|
636
641
|
]
|
|
637
642
|
if unexpected_evidence:
|
|
638
643
|
raise ValueError(f"preuves inattendues : {', '.join(unexpected_evidence)}")
|
|
639
|
-
if changed_files:
|
|
640
|
-
raise ValueError("verify ne peut pas modifier de fichiers source")
|
|
641
644
|
if not checks:
|
|
642
645
|
raise ValueError("verify complete requiert au moins un check execute")
|
|
643
646
|
failed_checks = [check.command for check in checks if check.status == "failed"]
|
|
@@ -655,8 +658,6 @@ def parse_activity_result(payload: dict[str, Any], contract: ActivityContract) -
|
|
|
655
658
|
if failed:
|
|
656
659
|
raise ValueError(f"preuves echouees dans le resultat : {', '.join(failed)}")
|
|
657
660
|
if contract.activity == "review" and status == "completed":
|
|
658
|
-
if changed_files:
|
|
659
|
-
raise ValueError("review ne peut pas modifier de fichiers")
|
|
660
661
|
evidence_by_id = {item.id: item for item in evidence}
|
|
661
662
|
review_id = contract.requiredEvidence[0]
|
|
662
663
|
# Le contrat de review demande explicitement de controler les preuves source=devflow deja
|
|
@@ -678,8 +679,6 @@ def parse_activity_result(payload: dict[str, Any], contract: ActivityContract) -
|
|
|
678
679
|
if review is None or review.outcome != "passed":
|
|
679
680
|
raise ValueError(f"{review_id} passed est requise")
|
|
680
681
|
if contract.activity == "rollback-check" and status == "completed":
|
|
681
|
-
if changed_files:
|
|
682
|
-
raise ValueError("rollback-check ne peut pas modifier de fichiers")
|
|
683
682
|
evidence_by_id = {item.id: item for item in evidence}
|
|
684
683
|
unexpected = [item.id for item in evidence if item.id != "rollback-plan"]
|
|
685
684
|
if unexpected:
|
|
@@ -713,7 +713,9 @@ def run_automatic_verification(
|
|
|
713
713
|
and not security_findings
|
|
714
714
|
)
|
|
715
715
|
diff_payload = _inspect_diff(
|
|
716
|
-
project_root,
|
|
716
|
+
project_root,
|
|
717
|
+
document_batch if document_batch is not None else changed_files,
|
|
718
|
+
feature_dir,
|
|
717
719
|
)
|
|
718
720
|
final_snapshot = snapshot_worktree(project_root)
|
|
719
721
|
try:
|
|
@@ -1007,11 +1009,16 @@ def _test_execution_finding(command: list[str], output: str) -> str | None:
|
|
|
1007
1009
|
return None
|
|
1008
1010
|
|
|
1009
1011
|
|
|
1010
|
-
def _inspect_diff(project_root: Path, changed_files: list[str]) -> dict:
|
|
1012
|
+
def _inspect_diff(project_root: Path, changed_files: list[str], feature_dir: Path) -> dict:
|
|
1011
1013
|
findings: list[str] = []
|
|
1012
1014
|
snapshot = snapshot_worktree(project_root)
|
|
1013
1015
|
dirty = set(snapshot.files)
|
|
1014
|
-
|
|
1016
|
+
# Les fichiers du dossier de la feature peuvent etre ignores par git : ils ne sont pas
|
|
1017
|
+
# exiges dans le diff courant.
|
|
1018
|
+
feature_prefix = _feature_subtree(feature_dir, project_root) + "/"
|
|
1019
|
+
missing = sorted(
|
|
1020
|
+
path for path in set(changed_files) - dirty if not path.startswith(feature_prefix)
|
|
1021
|
+
)
|
|
1015
1022
|
if missing:
|
|
1016
1023
|
findings.append(
|
|
1017
1024
|
"fichiers implementes absents du diff courant : " + ", ".join(missing)
|
devflow_cli/utils/logging.py
CHANGED
|
@@ -5,9 +5,9 @@ from __future__ import annotations
|
|
|
5
5
|
import logging
|
|
6
6
|
import sys
|
|
7
7
|
from logging.handlers import RotatingFileHandler
|
|
8
|
-
from pathlib import Path
|
|
9
8
|
|
|
10
|
-
|
|
9
|
+
from devflow_cli.core.telemetry import telemetry_file
|
|
10
|
+
|
|
11
11
|
_LOG_FILE = "devflow.log"
|
|
12
12
|
_MAX_BYTES = 1_048_576 # 1 Mo
|
|
13
13
|
_BACKUP_COUNT = 1
|
|
@@ -19,7 +19,8 @@ _configured = False
|
|
|
19
19
|
def setup_logging(verbose: bool = False) -> None:
|
|
20
20
|
"""Configure le logging une seule fois.
|
|
21
21
|
|
|
22
|
-
- Fichier :
|
|
22
|
+
- Fichier : devflow.log a cote de la telemetrie, sous DEVFLOW_HOME ou ~/.devflow
|
|
23
|
+
(RotatingFileHandler, 1 Mo, 1 backup)
|
|
23
24
|
- Console : stderr uniquement si verbose=True
|
|
24
25
|
- Fallback : NullHandler si le fichier ne peut pas etre cree
|
|
25
26
|
"""
|
|
@@ -35,7 +36,7 @@ def setup_logging(verbose: bool = False) -> None:
|
|
|
35
36
|
|
|
36
37
|
# File handler avec rotation
|
|
37
38
|
try:
|
|
38
|
-
log_dir =
|
|
39
|
+
log_dir = telemetry_file().parent
|
|
39
40
|
log_dir.mkdir(parents=True, exist_ok=True)
|
|
40
41
|
file_handler = RotatingFileHandler(
|
|
41
42
|
log_dir / _LOG_FILE,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: devflow-cli
|
|
3
|
-
Version: 10.2.
|
|
3
|
+
Version: 10.2.3
|
|
4
4
|
Summary: Workflow adaptatif pour Claude Code : profils, preuves et contrats d'activité
|
|
5
5
|
Project-URL: Homepage, https://github.com/sopequenoteck/devflow
|
|
6
6
|
Project-URL: Repository, https://github.com/sopequenoteck/devflow
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
devflow_cli/__init__.py,sha256=
|
|
1
|
+
devflow_cli/__init__.py,sha256=NgbjejcRAc4t-0o25LN9aj6PfgdWhDCMiKix9eB9f5M,871
|
|
2
2
|
devflow_cli/cli.py,sha256=QQktLkHK1cEAj0ZlEuGKYumm3xJUHM-aeC-E2RgfcEY,2136
|
|
3
3
|
devflow_cli/adapters/__init__.py,sha256=z1J7_YJHcgak2a6dTZpOUKKwf-K7UwRqGzS8XY9duC0,299
|
|
4
4
|
devflow_cli/adapters/agents.py,sha256=-9zmNlFmQfP2pOGxA3_SSKij8ScR76J4-sgv4GMBWEI,18530
|
|
@@ -16,13 +16,13 @@ devflow_cli/commands/status.py,sha256=Votdh_sZkRuC_iui1krrdXE9cZ5dpY2OO2au4PVa7I
|
|
|
16
16
|
devflow_cli/commands/upgrade_cmd.py,sha256=7GYe1T7SWzkDSYW9x1G-Dznw9qwKT2uI1gJUcWr9_2M,6093
|
|
17
17
|
devflow_cli/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
18
18
|
devflow_cli/core/activity_base.py,sha256=eEC_YIr5O7WhCglA7xAEPypVzhcdC6f2h9d-SDDecVA,20475
|
|
19
|
-
devflow_cli/core/activity_contracts.py,sha256=
|
|
19
|
+
devflow_cli/core/activity_contracts.py,sha256=wL0Y0OnyTptQtFZ1d4BpPiJA2eCK0-8h9cksYdnUAfU,40278
|
|
20
20
|
devflow_cli/core/adaptive_runner.py,sha256=AkXtcE-lOjxDnabKdxvv5knx9giZXvvhzuv9LKLS7Mc,49727
|
|
21
21
|
devflow_cli/core/adaptive_workflow.py,sha256=DU8iciNOeEDco5uwQUeX9E9Kc2WwaVPoRfWxdpRJyJ4,14416
|
|
22
22
|
devflow_cli/core/agent_failure.py,sha256=iX4q249lAHeVdD_ZF1aObmU-FX6sjfYP9dfLSnWGAD0,3771
|
|
23
23
|
devflow_cli/core/agent_run_marker.py,sha256=QW3ScA2ZpqfQdUo5ANTbenDVyY2iHpB_wTaN6VUKlzc,3451
|
|
24
24
|
devflow_cli/core/assessment.py,sha256=ACtJbXq1qZjVfeERjy8Qg6-ioLfSMUBVQm2l-mtGwgI,11522
|
|
25
|
-
devflow_cli/core/automatic_evidence.py,sha256=
|
|
25
|
+
devflow_cli/core/automatic_evidence.py,sha256=MraC57_P_ZqPkmQJNoVyBi6oBj9lCr-WZdmWwOUZXGk,42875
|
|
26
26
|
devflow_cli/core/contract_schemas.py,sha256=M0Twbt_SVVfuPa7udC-EJuR3pTl9pWrxQUCohIsg1h0,8477
|
|
27
27
|
devflow_cli/core/decisions.py,sha256=tFYKNDaztMvnhLfVGJKIux5zaSjEPx2nwXs5nb2qv4U,6308
|
|
28
28
|
devflow_cli/core/docgen.py,sha256=47JoVDWetkcctgHwJZC67AVebOKgl10VB9hZ3Xr63mo,3908
|
|
@@ -52,14 +52,14 @@ devflow_cli/schemas/reconcile-log-v3.schema.json,sha256=TNxw6xnv3dcwdUDqi0-SAlQn
|
|
|
52
52
|
devflow_cli/schemas/workflow-state-v6.schema.json,sha256=fYyJS-6Aq-Ea7y2bVqJYSmKzdF2DvL3Nb6IdDNgFGfY,3239
|
|
53
53
|
devflow_cli/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
54
54
|
devflow_cli/utils/console.py,sha256=t7cpyeEluWj4v_O_KFSI59iqXK4GiSXPuxlsr8q5zoQ,771
|
|
55
|
-
devflow_cli/utils/logging.py,sha256=
|
|
55
|
+
devflow_cli/utils/logging.py,sha256=ZL7DYB7rQn_94KKG7A6_IqONddR-XubJ4MhG3bGPKRI,1840
|
|
56
56
|
devflow_cli/utils/paths.py,sha256=CH81dZZTI2vjgl8mck6QcAChxoBpujmKZ0vVKhKmXEY,8176
|
|
57
57
|
devflow_cli/utils/strings.py,sha256=bfFXCwBDnFxshgZOYfy6mtysnjiaWO1wFnqBf7HLg4o,351
|
|
58
58
|
devflow_cli/resources/commands/devflow.md,sha256=5MjahTVYXAT_zrjEQmM25KH9s6DbRmyI1TdJCxYlrKk,3464
|
|
59
59
|
devflow_cli/resources/commands/devflow.status.md,sha256=tqjQ1IboU99ztG6C4nunBHGJCvMn3qDqx3AoF4SPjCk,338
|
|
60
60
|
devflow_cli/resources/templates/constitution-template.md,sha256=uSzNuwF-xIRx8cHt9gloynRjNgDGmnN5z2Xck6fCOsI,2102
|
|
61
|
-
devflow_cli-10.2.
|
|
62
|
-
devflow_cli-10.2.
|
|
63
|
-
devflow_cli-10.2.
|
|
64
|
-
devflow_cli-10.2.
|
|
65
|
-
devflow_cli-10.2.
|
|
61
|
+
devflow_cli-10.2.3.dist-info/METADATA,sha256=ZR0PMgciE_gEiCSBria9YqjTqUmdI3n9_pniHbDO_K0,6674
|
|
62
|
+
devflow_cli-10.2.3.dist-info/WHEEL,sha256=2iZrJkDIkeDh0k9SikKMqFuRP-ua6mb4Ir1AsER4BEw,87
|
|
63
|
+
devflow_cli-10.2.3.dist-info/entry_points.txt,sha256=GVJ6bMvFpqyO5589iC4nFKeGTpGIW8aKn_QPPpSZ6kU,48
|
|
64
|
+
devflow_cli-10.2.3.dist-info/licenses/LICENSE,sha256=v79PvnmqOdKhQiOa_QcWxng4q8GuGscLOwi7ygUpwpo,1070
|
|
65
|
+
devflow_cli-10.2.3.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|