devops-bot-sdk 1.4.66__tar.gz → 1.4.67__tar.gz

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.
Files changed (38) hide show
  1. {devops_bot_sdk-1.4.66 → devops_bot_sdk-1.4.67}/PKG-INFO +1 -1
  2. {devops_bot_sdk-1.4.66 → devops_bot_sdk-1.4.67}/devops_bot_sdk.egg-info/PKG-INFO +1 -1
  3. {devops_bot_sdk-1.4.66 → devops_bot_sdk-1.4.67}/pyproject.toml +1 -1
  4. {devops_bot_sdk-1.4.66 → devops_bot_sdk-1.4.67}/sdk/__init__.py +2 -2
  5. {devops_bot_sdk-1.4.66 → devops_bot_sdk-1.4.67}/sdk/client.py +1 -1
  6. {devops_bot_sdk-1.4.66 → devops_bot_sdk-1.4.67}/sdk/ipc/handlers.py +60 -0
  7. {devops_bot_sdk-1.4.66 → devops_bot_sdk-1.4.67}/README.md +0 -0
  8. {devops_bot_sdk-1.4.66 → devops_bot_sdk-1.4.67}/devops_bot_sdk.egg-info/SOURCES.txt +0 -0
  9. {devops_bot_sdk-1.4.66 → devops_bot_sdk-1.4.67}/devops_bot_sdk.egg-info/dependency_links.txt +0 -0
  10. {devops_bot_sdk-1.4.66 → devops_bot_sdk-1.4.67}/devops_bot_sdk.egg-info/entry_points.txt +0 -0
  11. {devops_bot_sdk-1.4.66 → devops_bot_sdk-1.4.67}/devops_bot_sdk.egg-info/requires.txt +0 -0
  12. {devops_bot_sdk-1.4.66 → devops_bot_sdk-1.4.67}/devops_bot_sdk.egg-info/top_level.txt +0 -0
  13. {devops_bot_sdk-1.4.66 → devops_bot_sdk-1.4.67}/sdk/collectors/__init__.py +0 -0
  14. {devops_bot_sdk-1.4.66 → devops_bot_sdk-1.4.67}/sdk/collectors/files.py +0 -0
  15. {devops_bot_sdk-1.4.66 → devops_bot_sdk-1.4.67}/sdk/collectors/process.py +0 -0
  16. {devops_bot_sdk-1.4.66 → devops_bot_sdk-1.4.67}/sdk/collectors/screenshot.py +0 -0
  17. {devops_bot_sdk-1.4.66 → devops_bot_sdk-1.4.67}/sdk/config.py +0 -0
  18. {devops_bot_sdk-1.4.66 → devops_bot_sdk-1.4.67}/sdk/crucial.py +0 -0
  19. {devops_bot_sdk-1.4.66 → devops_bot_sdk-1.4.67}/sdk/exceptions.py +0 -0
  20. {devops_bot_sdk-1.4.66 → devops_bot_sdk-1.4.67}/sdk/git_ops.py +0 -0
  21. {devops_bot_sdk-1.4.66 → devops_bot_sdk-1.4.67}/sdk/graphify.py +0 -0
  22. {devops_bot_sdk-1.4.66 → devops_bot_sdk-1.4.67}/sdk/hooks/__init__.py +0 -0
  23. {devops_bot_sdk-1.4.66 → devops_bot_sdk-1.4.67}/sdk/hooks/crucial_guard.py +0 -0
  24. {devops_bot_sdk-1.4.66 → devops_bot_sdk-1.4.67}/sdk/ipc/__init__.py +0 -0
  25. {devops_bot_sdk-1.4.66 → devops_bot_sdk-1.4.67}/sdk/ipc/electron_bridge.py +0 -0
  26. {devops_bot_sdk-1.4.66 → devops_bot_sdk-1.4.67}/sdk/local_exec.py +0 -0
  27. {devops_bot_sdk-1.4.66 → devops_bot_sdk-1.4.67}/sdk/models/__init__.py +0 -0
  28. {devops_bot_sdk-1.4.66 → devops_bot_sdk-1.4.67}/sdk/models/envelope.py +0 -0
  29. {devops_bot_sdk-1.4.66 → devops_bot_sdk-1.4.67}/sdk/models/requests.py +0 -0
  30. {devops_bot_sdk-1.4.66 → devops_bot_sdk-1.4.67}/sdk/models/responses.py +0 -0
  31. {devops_bot_sdk-1.4.66 → devops_bot_sdk-1.4.67}/sdk/models/snapshots.py +0 -0
  32. {devops_bot_sdk-1.4.66 → devops_bot_sdk-1.4.67}/sdk/py.typed +0 -0
  33. {devops_bot_sdk-1.4.66 → devops_bot_sdk-1.4.67}/sdk/run_auto.py +0 -0
  34. {devops_bot_sdk-1.4.66 → devops_bot_sdk-1.4.67}/sdk/sse.py +0 -0
  35. {devops_bot_sdk-1.4.66 → devops_bot_sdk-1.4.67}/sdk/test.py +0 -0
  36. {devops_bot_sdk-1.4.66 → devops_bot_sdk-1.4.67}/sdk/test_pipeline.py +0 -0
  37. {devops_bot_sdk-1.4.66 → devops_bot_sdk-1.4.67}/sdk/updater.py +0 -0
  38. {devops_bot_sdk-1.4.66 → devops_bot_sdk-1.4.67}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: devops-bot-sdk
3
- Version: 1.4.66
3
+ Version: 1.4.67
4
4
  Summary: DevOps Bot Desktop SDK — thin client for the AgentOS Electron desktop app
5
5
  Author: noumanaziz2128
6
6
  License-Expression: LicenseRef-Proprietary
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: devops-bot-sdk
3
- Version: 1.4.66
3
+ Version: 1.4.67
4
4
  Summary: DevOps Bot Desktop SDK — thin client for the AgentOS Electron desktop app
5
5
  Author: noumanaziz2128
6
6
  License-Expression: LicenseRef-Proprietary
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "devops-bot-sdk"
7
- version = "1.4.66"
7
+ version = "1.4.67"
8
8
  description = "DevOps Bot Desktop SDK — thin client for the AgentOS Electron desktop app"
9
9
  readme = "README.md"
10
10
  license = "LicenseRef-Proprietary"
@@ -1,6 +1,6 @@
1
1
  """AgentOS Desktop SDK — thin HTTPS/SSE client for the Electron app.
2
2
 
3
- Version: 1.4.66
3
+ Version: 1.4.67
4
4
 
5
5
  Public surface:
6
6
  BackendClient.from_config() — create client from ~/.agentos/config.toml
@@ -30,7 +30,7 @@ Rules:
30
30
  - All data egress through submit_webhook only
31
31
  """
32
32
 
33
- __version__ = "1.4.66"
33
+ __version__ = "1.4.67"
34
34
  __author__ = "AgentOS"
35
35
 
36
36
  from sdk.client import BackendClient
@@ -58,7 +58,7 @@ def _notify_status(task_id: str, status: str) -> None:
58
58
  pass
59
59
 
60
60
 
61
- SDK_VERSION = "1.4.66"
61
+ SDK_VERSION = "1.4.67"
62
62
  _POLL_INTERVAL = 3.0
63
63
  _POLL_TIMEOUT = 600.0
64
64
  _ORCHESTRATE_TIMEOUT = 2700.0 # 45 min — covers approval wait + VPS execution time
@@ -594,6 +594,34 @@ def _epic_inherited_fields(task: dict) -> dict:
594
594
  return {k: v for k, v in fields.items() if v}
595
595
 
596
596
 
597
+ # Lines that name a directory to WRITE the generated user stories into (distinct
598
+ # from a code repo path). Matches story/file/folder/directory/mkdir/write hints
599
+ # and skips repo lines (github URL / "path:").
600
+ _STORIES_DIR_HINT = re.compile(
601
+ r"\b(user\s+stor|stories|mkdir|directory|folder|write|\.md)\b", re.I,
602
+ )
603
+
604
+
605
+ def _extract_stories_dir(text: str | None) -> str | None:
606
+ """A directory the instructions ask the user stories to be WRITTEN into, or None.
607
+
608
+ Scans lines that mention stories/files/a directory (but not code-repo lines that
609
+ carry a GitHub URL or a "path:" repo label) and returns the first filesystem path
610
+ found — e.g. "Create a new directory at /home/me/new_tasks and write the stories".
611
+ """
612
+ if not text:
613
+ return None
614
+ for line in text.splitlines():
615
+ low = line.lower()
616
+ if "github.com" in low or "path:" in low:
617
+ continue # a code repo line, not a stories-output directory
618
+ if _STORIES_DIR_HINT.search(line):
619
+ p = _extract_path_from_text(line)
620
+ if p:
621
+ return p
622
+ return None
623
+
624
+
597
625
  # ── Ticket validation gate (Epics + USER-driven Stories) ────────────────────
598
626
  # A strict quality gate: before the bot actions an Epic or a USER-created Story it
599
627
  # checks the ticket meets the required standard. On failure it posts a harsh,
@@ -839,6 +867,38 @@ async def _handle_epic(
839
867
  data={"current_step": f" ↳ created To Do task: {fields['summary']}"},
840
868
  ).model_dump())
841
869
 
870
+ # 3b. Optionally ALSO write each story as a Markdown file to a directory named in
871
+ # the instructions (e.g. "create /home/me/new_tasks and write the user stories
872
+ # there"). This is IN ADDITION to the Story tickets. Best-effort — a file-write
873
+ # failure never fails the Epic.
874
+ stories_dir = _extract_stories_dir(human)
875
+ if stories_dir:
876
+ from pathlib import Path
877
+ try:
878
+ d = Path(stories_dir).expanduser()
879
+ d.mkdir(parents=True, exist_ok=True) # create from scratch
880
+ written = 0
881
+ for i, st in enumerate(stories[:_MAX_EPIC_STORIES], 1):
882
+ if not isinstance(st, dict) or not (st.get("summary") or "").strip():
883
+ continue
884
+ title = str(st.get("summary", "")).strip()
885
+ slug = re.sub(r"[^a-z0-9]+", "-", title.lower()).strip("-")[:50] or f"story-{i}"
886
+ content = f"# {title}\n\n{str(st.get('description', '') or '').strip()}\n"
887
+ (d / f"{i:02d}-{slug}.md").write_text(content, encoding="utf-8")
888
+ written += 1
889
+ await client.log_activity(f"Epic {jira_key}: wrote {written} user-story file(s) to {stories_dir}")
890
+ await send(Envelope(
891
+ type="step_update", thread_id=thread_id,
892
+ data={"jira_task_id": tid,
893
+ "current_step": f"Epic {jira_key}: wrote {written} user-story file(s) to {stories_dir}"},
894
+ ).model_dump())
895
+ except Exception as exc: # noqa: BLE001
896
+ await send(Envelope(
897
+ type="step_update", thread_id=thread_id,
898
+ data={"jira_task_id": tid,
899
+ "current_step": f"Epic {jira_key}: could not write story files to {stories_dir} — {str(exc)[:120]}"},
900
+ ).model_dump())
901
+
842
902
  await client.log_activity(
843
903
  f"Epic {jira_key}: Done — created {len(created)}/{len(stories)} To Do user Story(ies)"
844
904
  )