devflow-cli 7.0.1__py3-none-any.whl → 7.1.1__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/commands/adaptive.py +27 -10
- devflow_cli/core/run_progress.py +62 -0
- devflow_cli/resources/commands/devflow.md +10 -2
- {devflow_cli-7.0.1.dist-info → devflow_cli-7.1.1.dist-info}/METADATA +1 -1
- {devflow_cli-7.0.1.dist-info → devflow_cli-7.1.1.dist-info}/RECORD +9 -8
- {devflow_cli-7.0.1.dist-info → devflow_cli-7.1.1.dist-info}/WHEEL +0 -0
- {devflow_cli-7.0.1.dist-info → devflow_cli-7.1.1.dist-info}/entry_points.txt +0 -0
- {devflow_cli-7.0.1.dist-info → devflow_cli-7.1.1.dist-info}/licenses/LICENSE +0 -0
devflow_cli/__init__.py
CHANGED
devflow_cli/commands/adaptive.py
CHANGED
|
@@ -38,6 +38,7 @@ from devflow_cli.core.adaptive_runner import (
|
|
|
38
38
|
record_human_review,
|
|
39
39
|
run_current_activity,
|
|
40
40
|
)
|
|
41
|
+
from devflow_cli.core import run_progress
|
|
41
42
|
from devflow_cli.core.worktree_snapshot import changed_paths, snapshot_worktree
|
|
42
43
|
from devflow_cli.core.automatic_evidence import (
|
|
43
44
|
ensure_fresh_devflow_evidence,
|
|
@@ -381,17 +382,29 @@ def run_adaptive(
|
|
|
381
382
|
json.dumps(activity_contract.expectedOutput, ensure_ascii=False),
|
|
382
383
|
encoding="utf-8",
|
|
383
384
|
)
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
timeout,
|
|
388
|
-
|
|
389
|
-
output_file,
|
|
390
|
-
permission_mode,
|
|
391
|
-
"workspace-write"
|
|
392
|
-
if "write" in activity_contract.allowedActions
|
|
393
|
-
else "read-only",
|
|
385
|
+
stream = run_progress.progress_stream(json_output)
|
|
386
|
+
run_progress.emit_progress(
|
|
387
|
+
f"Activite '{activity_contract.activity}' demarree : "
|
|
388
|
+
f"agent {agent}, delai {timeout} s",
|
|
389
|
+
stream,
|
|
394
390
|
)
|
|
391
|
+
with run_progress.heartbeat(
|
|
392
|
+
activity_contract.activity,
|
|
393
|
+
agent,
|
|
394
|
+
stream,
|
|
395
|
+
run_progress.PROGRESS_INTERVAL_SECONDS,
|
|
396
|
+
):
|
|
397
|
+
execution = adapter.execute_structured(
|
|
398
|
+
prompt_text,
|
|
399
|
+
project_root,
|
|
400
|
+
timeout,
|
|
401
|
+
schema_file,
|
|
402
|
+
output_file,
|
|
403
|
+
permission_mode,
|
|
404
|
+
"workspace-write"
|
|
405
|
+
if "write" in activity_contract.allowedActions
|
|
406
|
+
else "read-only",
|
|
407
|
+
)
|
|
395
408
|
attempt["execution"] = execution
|
|
396
409
|
output = (
|
|
397
410
|
output_file.read_text(encoding="utf-8")
|
|
@@ -796,6 +809,10 @@ def _execute_local_verification(
|
|
|
796
809
|
feature_dir: Path, project_root: Path, issue_id: str, *,
|
|
797
810
|
refresh: bool = False, json_output: bool = False,
|
|
798
811
|
) -> None:
|
|
812
|
+
run_progress.emit_progress(
|
|
813
|
+
"Activite 'verify' demarree : verification locale",
|
|
814
|
+
run_progress.progress_stream(json_output),
|
|
815
|
+
)
|
|
799
816
|
outcome = run_automatic_verification(feature_dir, project_root, refresh=refresh)
|
|
800
817
|
if json_output:
|
|
801
818
|
_print_execution_json(
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
"""Avancement d'une activite : lignes horodatees, sans contenu de l'agent."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import sys
|
|
6
|
+
import threading
|
|
7
|
+
import time
|
|
8
|
+
from contextlib import contextmanager
|
|
9
|
+
from datetime import datetime, timezone
|
|
10
|
+
from typing import Iterator, TextIO
|
|
11
|
+
|
|
12
|
+
PROGRESS_INTERVAL_SECONDS = 60
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def emit_progress(message: str, stream: TextIO | None = None) -> None:
|
|
16
|
+
"""Ecrit une ligne complete horodatee (UTC), sans mise en forme terminal."""
|
|
17
|
+
target = stream if stream is not None else sys.stdout
|
|
18
|
+
stamp = datetime.now(timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ")
|
|
19
|
+
print(f"{stamp} [devflow] {message}", file=target, flush=True)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def progress_stream(json_output: bool) -> TextIO:
|
|
23
|
+
"""Flux d'avancement, lu a l'appel : stderr en --json, stdout sinon."""
|
|
24
|
+
return sys.stderr if json_output else sys.stdout
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def format_elapsed(seconds: float) -> str:
|
|
28
|
+
total = int(seconds)
|
|
29
|
+
minutes, secs = divmod(total, 60)
|
|
30
|
+
if minutes == 0:
|
|
31
|
+
return f"{secs} s"
|
|
32
|
+
return f"{minutes} min {secs:02d} s"
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
@contextmanager
|
|
36
|
+
def heartbeat(
|
|
37
|
+
activity: str,
|
|
38
|
+
agent: str,
|
|
39
|
+
stream: TextIO,
|
|
40
|
+
interval: float = PROGRESS_INTERVAL_SECONDS,
|
|
41
|
+
) -> Iterator[None]:
|
|
42
|
+
"""Emet une ligne toutes les `interval` secondes tant que le bloc s'execute."""
|
|
43
|
+
if interval <= 0:
|
|
44
|
+
raise ValueError("l'intervalle d'avancement doit etre positif")
|
|
45
|
+
started = time.monotonic()
|
|
46
|
+
stop = threading.Event()
|
|
47
|
+
|
|
48
|
+
def beat() -> None:
|
|
49
|
+
while not stop.wait(interval):
|
|
50
|
+
elapsed = format_elapsed(time.monotonic() - started)
|
|
51
|
+
emit_progress(
|
|
52
|
+
f"Activite '{activity}' en cours depuis {elapsed} (agent {agent})",
|
|
53
|
+
stream,
|
|
54
|
+
)
|
|
55
|
+
|
|
56
|
+
thread = threading.Thread(target=beat, daemon=True)
|
|
57
|
+
thread.start()
|
|
58
|
+
try:
|
|
59
|
+
yield
|
|
60
|
+
finally:
|
|
61
|
+
stop.set()
|
|
62
|
+
thread.join()
|
|
@@ -21,8 +21,16 @@ interpréter de `state.json`.
|
|
|
21
21
|
6. Enchaîner les activités avec
|
|
22
22
|
`devflow adaptive run ISSUE_ID --agent AGENT --until CIBLE`.
|
|
23
23
|
`--until` inclut l'activité ciblée.
|
|
24
|
-
La CLI s'arrête au premier refus
|
|
25
|
-
|
|
24
|
+
La CLI s'arrête au premier refus. Distinguer alors deux cas :
|
|
25
|
+
- refus justifié (gate non satisfaite par le travail de l'agent) :
|
|
26
|
+
corriger le travail, puis `devflow adaptive reconcile ISSUE_ID` si le
|
|
27
|
+
travail corrigé suffit, sinon relancer `devflow adaptive run` ;
|
|
28
|
+
- échec de Devflow (au sens de la section Retours d'usage) : consigner la
|
|
29
|
+
`friction` dès l'échec constaté, puis une relance au plus, après
|
|
30
|
+
correction de la cause identifiée. Si le même blocage revient, ou si la
|
|
31
|
+
CLI plante (traceback, commande inconnue), sortir du parcours : terminer
|
|
32
|
+
la feature hors Devflow, clôturer par un `bilan` dont `--what` indique
|
|
33
|
+
l'abandon et sa cause, et indiquer cette cause dans le compte rendu.
|
|
26
34
|
7. Afficher ensuite `devflow adaptive status ISSUE_ID`.
|
|
27
35
|
|
|
28
36
|
## Retours d'usage
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
devflow_cli/__init__.py,sha256=
|
|
1
|
+
devflow_cli/__init__.py,sha256=YRmOwDvGZfXzLf-ljn7cLGXMx2uLhcN-6E6OWUsRmsg,955
|
|
2
2
|
devflow_cli/cli.py,sha256=0_SmhJX_k7OQfp-jNV_jq9EOgWY4rTjStGIoc9pH6Ec,2686
|
|
3
3
|
devflow_cli/adapters/__init__.py,sha256=RkjHPU2Lp4hSVIq2iOmyTrv2zYU9NuiIF9wEMWzLdMI,377
|
|
4
4
|
devflow_cli/adapters/agents.py,sha256=8_y70AIhmtuR8kyPN3Wpj0-i76k9wd_uaycVKTqC96g,26503
|
|
5
5
|
devflow_cli/adapters/linear.py,sha256=MyqI2tHx7NNHY1KRfeYZ_Zjc-6_xhZPWD4oS-j7wnNY,2659
|
|
6
6
|
devflow_cli/commands/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
7
|
-
devflow_cli/commands/adaptive.py,sha256=
|
|
7
|
+
devflow_cli/commands/adaptive.py,sha256=NwJNXjJu8mDtn0epKjKrdBYsY_z0adNc4r5yHsXhdms,46241
|
|
8
8
|
devflow_cli/commands/assess.py,sha256=lyj6TI5hXUWX55dY589fG4bKJSMztvMPxZ0HZjo0O-w,5230
|
|
9
9
|
devflow_cli/commands/check.py,sha256=M_sbcH1L3FEa4DF9gm46LEADlJndRKlaEDoysIBHv8k,6668
|
|
10
10
|
devflow_cli/commands/context.py,sha256=hwTitOHxIpJMx1X8R1jHHy9CpE4HVZpJKkyeOujxAio,6246
|
|
@@ -40,6 +40,7 @@ devflow_cli/core/manifest.py,sha256=h058_m5-HJrYsNUdgfwnKts2riHiYPXUwMzPImHOs2g,
|
|
|
40
40
|
devflow_cli/core/operational.py,sha256=ZEWh6DKJfHYLpV9r3vZwaDFREQwlJF0wTtgB1VleXog,1204
|
|
41
41
|
devflow_cli/core/redaction.py,sha256=o_1MDtCyvRLrk_dWlV6_7E6_mPVB1B5a0cCfTBj9j0Q,1973
|
|
42
42
|
devflow_cli/core/remediation.py,sha256=HNi4ti-M7dybP23GGTCQTupzlTnHIn_15OIX3SSK1bM,13350
|
|
43
|
+
devflow_cli/core/run_progress.py,sha256=hawaMo5sGcxvugexeryMWanFajdf46SY6b37O7dToZM,1855
|
|
43
44
|
devflow_cli/core/scanner.py,sha256=bcoC91Nc0Hw2P7aHpL-9ITxynLZhLTEKpOXo553a-18,4395
|
|
44
45
|
devflow_cli/core/staleness.py,sha256=KnZBBCn5LHB_AK4UvTkQiT5yDNnIjjicRk-20YXkogQ,5130
|
|
45
46
|
devflow_cli/core/telemetry.py,sha256=emcYo6Qikc86TYKT5Mc_9-3Thkt3nztkPZrpTy9VlvA,6952
|
|
@@ -62,7 +63,7 @@ devflow_cli/utils/strings.py,sha256=bfFXCwBDnFxshgZOYfy6mtysnjiaWO1wFnqBf7HLg4o,
|
|
|
62
63
|
devflow_cli/resources/commands/devflow.context.md,sha256=SdvZ286cJKkgQIKYwnjd30v5zDeEXTFBhpEEsEOInoc,2048
|
|
63
64
|
devflow_cli/resources/commands/devflow.extension.md,sha256=w7hoFfxRS0y-3rsvUmQDx1fvZhtE9KhANmRgFDwYVaA,2373
|
|
64
65
|
devflow_cli/resources/commands/devflow.init.md,sha256=wplv3IiJrNkUoPXGZtOw9k6m3dzXBQDYAcPPN8d3EF8,2011
|
|
65
|
-
devflow_cli/resources/commands/devflow.md,sha256=
|
|
66
|
+
devflow_cli/resources/commands/devflow.md,sha256=ojhLIwQvl0pS7Zxct6RS2ihpiT9f9-F1yH7jRTO47Ng,2689
|
|
66
67
|
devflow_cli/resources/commands/devflow.regen.md,sha256=yjbMNAt6k0y6M9Y5HZDhCRgj_tb33Om6_-5OijmD5Bw,1169
|
|
67
68
|
devflow_cli/resources/commands/devflow.status.md,sha256=tqjQ1IboU99ztG6C4nunBHGJCvMn3qDqx3AoF4SPjCk,338
|
|
68
69
|
devflow_cli/resources/extensions/EXTENSION-API-REFERENCE.md,sha256=1wuAV-K8WI0BJ6SJ0HViieSHe3zazlfHemkKDT7bbKM,4478
|
|
@@ -85,8 +86,8 @@ devflow_cli/resources/templates/contracts/api-template.md,sha256=rC5v7JBz71PznCn
|
|
|
85
86
|
devflow_cli/resources/templates/contracts/components-template.md,sha256=XIWfEXfC72sNmL5OA3V-7xIywkNDU2DBPLfyiagOWcs,484
|
|
86
87
|
devflow_cli/resources/templates/contracts/interfaces-template.md,sha256=kf8B7b6HsmN7jyRlLNU7RnZl0rTMlI5s97yVRyI-6yc,336
|
|
87
88
|
devflow_cli/resources/templates/contracts/services-template.md,sha256=cFafKCyLmq_a7aR7G0LXAaMO2z4Fuflq6iKdxfVg0vg,477
|
|
88
|
-
devflow_cli-7.
|
|
89
|
-
devflow_cli-7.
|
|
90
|
-
devflow_cli-7.
|
|
91
|
-
devflow_cli-7.
|
|
92
|
-
devflow_cli-7.
|
|
89
|
+
devflow_cli-7.1.1.dist-info/METADATA,sha256=eVG11bf7WSfH7l5IOP8PHN_l5B4Mu4uaE5qZs36bClA,5742
|
|
90
|
+
devflow_cli-7.1.1.dist-info/WHEEL,sha256=W3fkpkm7-wf9vBI5Z-7s0eWkeM-spu78I8Neb98DeEg,87
|
|
91
|
+
devflow_cli-7.1.1.dist-info/entry_points.txt,sha256=GVJ6bMvFpqyO5589iC4nFKeGTpGIW8aKn_QPPpSZ6kU,48
|
|
92
|
+
devflow_cli-7.1.1.dist-info/licenses/LICENSE,sha256=v79PvnmqOdKhQiOa_QcWxng4q8GuGscLOwi7ygUpwpo,1070
|
|
93
|
+
devflow_cli-7.1.1.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|