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 CHANGED
@@ -1,6 +1,6 @@
1
1
  """devflow CLI — workflow de développement adaptatif."""
2
2
 
3
- VERSION = "10.2.1"
3
+ VERSION = "10.2.3"
4
4
 
5
5
  ACTIVITY_LINEAR_MAPPING = {
6
6
  "assess": "Backlog",
@@ -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, document_batch if document_batch is not None else changed_files
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
- missing = sorted(set(changed_files) - dirty)
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)
@@ -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
- _LOG_DIR = ".devflow"
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 : .devflow/devflow.log (RotatingFileHandler, 1 Mo, 1 backup)
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 = Path(_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.1
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=GfdbMSaR8vRKpS7fDKPzUQlONRjRpZ-Q_M4Jdu5g5UY,871
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=Sxu7b6lBQNNrtid0D3b9az8zPI8W4UHVgTQsNc0Y2uI,40328
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=pqSnNXe6RHthII6fgoHlCNkGiFTKQ4yyRtErGUwbvas,42559
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=I7U9_IVvYAFnUAWi7xs5F_WGR0uSz6DmRvZ_B3xLFbs,1769
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.1.dist-info/METADATA,sha256=BtCN9bbyNd1J-gilXl1ttacuw_7B1grlcfpMKaTsjH4,6674
62
- devflow_cli-10.2.1.dist-info/WHEEL,sha256=2iZrJkDIkeDh0k9SikKMqFuRP-ua6mb4Ir1AsER4BEw,87
63
- devflow_cli-10.2.1.dist-info/entry_points.txt,sha256=GVJ6bMvFpqyO5589iC4nFKeGTpGIW8aKn_QPPpSZ6kU,48
64
- devflow_cli-10.2.1.dist-info/licenses/LICENSE,sha256=v79PvnmqOdKhQiOa_QcWxng4q8GuGscLOwi7ygUpwpo,1070
65
- devflow_cli-10.2.1.dist-info/RECORD,,
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,,