alissa-tools-github-devloop 0.8.34__py3-none-any.whl → 0.8.36__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.
- alissa/tools/github/devloop/alissa.py +57 -2
- alissa/tools/github/devloop/loop.py +30 -0
- alissa/tools/github/devloop/version +1 -1
- {alissa_tools_github_devloop-0.8.34.dist-info → alissa_tools_github_devloop-0.8.36.dist-info}/METADATA +1 -1
- {alissa_tools_github_devloop-0.8.34.dist-info → alissa_tools_github_devloop-0.8.36.dist-info}/RECORD +10 -10
- {alissa_tools_github_devloop-0.8.34.dist-info → alissa_tools_github_devloop-0.8.36.dist-info}/WHEEL +0 -0
- {alissa_tools_github_devloop-0.8.34.dist-info → alissa_tools_github_devloop-0.8.36.dist-info}/entry_points.txt +0 -0
- {alissa_tools_github_devloop-0.8.34.dist-info → alissa_tools_github_devloop-0.8.36.dist-info}/licenses/LICENSE +0 -0
- {alissa_tools_github_devloop-0.8.34.dist-info → alissa_tools_github_devloop-0.8.36.dist-info}/licenses/NOTICE +0 -0
- {alissa_tools_github_devloop-0.8.34.dist-info → alissa_tools_github_devloop-0.8.36.dist-info}/top_level.txt +0 -0
|
@@ -116,7 +116,49 @@ def send_keys_argv(name: str, keys: "tuple[str, ...]") -> "list[str]":
|
|
|
116
116
|
return ["tmux", "-S", tmux_socket(), "send-keys", "-t", tmux_target(name), *keys]
|
|
117
117
|
|
|
118
118
|
|
|
119
|
+
# The two spawn stamps of the Studio cost meter (loop-cost-meter.md §2.3,
|
|
120
|
+
# §2.4, issue #149): `--task` names the ORIGIN task the session serves and
|
|
121
|
+
# `--repo` the canonical lowercase `owner/name`, so the session row carries
|
|
122
|
+
# `focusTaskId` and `repo` from its first second. Each flag is matched as a
|
|
123
|
+
# whole option token in `alissa tmux queue add --help`.
|
|
124
|
+
_TASK_FLAG_RE = re.compile(r"(?<![\w-])--task(?![\w-])")
|
|
125
|
+
_REPO_FLAG_RE = re.compile(r"(?<![\w-])--repo(?![\w-])")
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
def queue_add_accepts_stamps(help_text: str) -> bool:
|
|
129
|
+
"""True when `alissa tmux queue add --help` lists BOTH `--task` and
|
|
130
|
+
`--repo`. Both or neither: a CLI with `--task` alone predates the stamp
|
|
131
|
+
(its `--task` links a queue item for shell write-back, and the session
|
|
132
|
+
row has no `repo` to fill), so it gets neither flag."""
|
|
133
|
+
text = help_text or ""
|
|
134
|
+
return bool(_TASK_FLAG_RE.search(text) and _REPO_FLAG_RE.search(text))
|
|
135
|
+
|
|
136
|
+
|
|
119
137
|
class Alissa:
|
|
138
|
+
def __init__(self) -> None:
|
|
139
|
+
# The stamp probe's verdict, read once per process (one Alissa per
|
|
140
|
+
# watcher, one watcher per daemon): None until a probe has answered.
|
|
141
|
+
self._stamps_accepted: "bool | None" = None
|
|
142
|
+
|
|
143
|
+
def accepts_spawn_stamps(self) -> bool:
|
|
144
|
+
"""Whether the installed CLI's `queue add` takes `--task`/`--repo`.
|
|
145
|
+
Probed once and cached; a probe that cannot run at all (a timeout,
|
|
146
|
+
a missing binary) reads as "no" for THIS spawn and is not cached, so
|
|
147
|
+
a transient failure never switches the stamps off for good."""
|
|
148
|
+
if self._stamps_accepted is None:
|
|
149
|
+
try:
|
|
150
|
+
out = run(["alissa", "tmux", "queue", "add", "--help"],
|
|
151
|
+
timeout=30, check=False)
|
|
152
|
+
except (CommandError, OSError) as exc:
|
|
153
|
+
log.warning("could not probe `alissa tmux queue add --help` "
|
|
154
|
+
"(%s); enqueuing without --task/--repo", exc)
|
|
155
|
+
return False
|
|
156
|
+
self._stamps_accepted = queue_add_accepts_stamps(out)
|
|
157
|
+
if not self._stamps_accepted:
|
|
158
|
+
log.info("the installed alissa CLI does not accept "
|
|
159
|
+
"`queue add --task/--repo`; spawns go unstamped")
|
|
160
|
+
return self._stamps_accepted
|
|
161
|
+
|
|
120
162
|
def enqueue_developer(
|
|
121
163
|
self,
|
|
122
164
|
*,
|
|
@@ -124,8 +166,14 @@ class Alissa:
|
|
|
124
166
|
directive: str,
|
|
125
167
|
cwd: Path,
|
|
126
168
|
agent: str,
|
|
169
|
+
task_ref: "str | None" = None,
|
|
170
|
+
repo: "str | None" = None,
|
|
127
171
|
dry_run: bool = False,
|
|
128
172
|
) -> None:
|
|
173
|
+
"""Enqueue the session. `task_ref` (the ORIGIN task, `TASK-<n>`) and
|
|
174
|
+
`repo` (`owner/name`, lowercased here) are passed as `--task` /
|
|
175
|
+
`--repo` only when the installed CLI accepts both; an older CLI gets
|
|
176
|
+
neither, so the enqueue never fails for want of a stamp."""
|
|
129
177
|
argv = [
|
|
130
178
|
"alissa",
|
|
131
179
|
"tmux",
|
|
@@ -136,13 +184,20 @@ class Alissa:
|
|
|
136
184
|
agent,
|
|
137
185
|
"--cwd",
|
|
138
186
|
str(cwd),
|
|
139
|
-
directive,
|
|
140
187
|
]
|
|
188
|
+
stamps: "list[str]" = []
|
|
189
|
+
if task_ref:
|
|
190
|
+
stamps += ["--task", task_ref]
|
|
191
|
+
if repo:
|
|
192
|
+
stamps += ["--repo", repo.lower()]
|
|
141
193
|
|
|
142
194
|
if dry_run:
|
|
143
|
-
log.info("[dry-run] would enqueue: %s", " ".join(argv
|
|
195
|
+
log.info("[dry-run] would enqueue: %s", " ".join(argv + stamps) + " <directive>")
|
|
144
196
|
return
|
|
145
197
|
|
|
198
|
+
if stamps and self.accepts_spawn_stamps():
|
|
199
|
+
argv += stamps
|
|
200
|
+
argv.append(directive)
|
|
146
201
|
run(argv, timeout=60)
|
|
147
202
|
|
|
148
203
|
# Developers are one-shot per attempt: a finished (or dead) session must
|
|
@@ -2366,6 +2366,28 @@ def revert_task_number(body: str) -> int:
|
|
|
2366
2366
|
return 0
|
|
2367
2367
|
|
|
2368
2368
|
|
|
2369
|
+
# The ORIGIN task as a PR body names it, for the spawn stamp (issue #149):
|
|
2370
|
+
# the `Alissa-Task:` trailer first, then the worker's own `Origin task:` /
|
|
2371
|
+
# `Origin Alissa task:` line (both spellings are on live bodies). Unlike
|
|
2372
|
+
# REVERT_TASK_KEYS there is NO `Implementation task:` fallback -- the stamp
|
|
2373
|
+
# claims the session serves the origin, and a downstream task is not one.
|
|
2374
|
+
_ORIGIN_TASK_RES = tuple(
|
|
2375
|
+
re.compile(rf"{key}\**\s*:\**\s*`?TASK-(\d+)", re.IGNORECASE)
|
|
2376
|
+
for key in (r"Alissa-Task", r"Origin(?:\s+Alissa)?\s+task")
|
|
2377
|
+
)
|
|
2378
|
+
|
|
2379
|
+
|
|
2380
|
+
def pr_origin_task_ref(body: str) -> "str | None":
|
|
2381
|
+
"""`TASK-<n>` for the origin task a PR body names, or None -- in which
|
|
2382
|
+
case the fix, maintain and revert edges spawn unstamped."""
|
|
2383
|
+
text = body or ""
|
|
2384
|
+
for pattern in _ORIGIN_TASK_RES:
|
|
2385
|
+
match = pattern.search(text)
|
|
2386
|
+
if match:
|
|
2387
|
+
return f"TASK-{match.group(1)}"
|
|
2388
|
+
return None
|
|
2389
|
+
|
|
2390
|
+
|
|
2369
2391
|
def revert_branch(task_number: int, pr_number: int) -> str:
|
|
2370
2392
|
"""`TASK-<n>-REVERT-PR<k>`: the revert branch's name, a `TASK-<n>-<DESC>`
|
|
2371
2393
|
shape by construction so the fix and maintain edges spawn on it."""
|
|
@@ -4065,6 +4087,8 @@ class DevWatcher:
|
|
|
4065
4087
|
directive=directive,
|
|
4066
4088
|
cwd=hub,
|
|
4067
4089
|
agent=self.config.agent_profile,
|
|
4090
|
+
task_ref=task_ref,
|
|
4091
|
+
repo=issue.full_name,
|
|
4068
4092
|
dry_run=self.config.dry_run,
|
|
4069
4093
|
)
|
|
4070
4094
|
|
|
@@ -7330,6 +7354,8 @@ class DevWatcher:
|
|
|
7330
7354
|
directive=directive,
|
|
7331
7355
|
cwd=hub,
|
|
7332
7356
|
agent=self.config.agent_profile,
|
|
7357
|
+
task_ref=pr_origin_task_ref(pr.body),
|
|
7358
|
+
repo=pr.full_name,
|
|
7333
7359
|
dry_run=self.config.dry_run,
|
|
7334
7360
|
)
|
|
7335
7361
|
|
|
@@ -7595,6 +7621,8 @@ class DevWatcher:
|
|
|
7595
7621
|
directive=directive,
|
|
7596
7622
|
cwd=hub,
|
|
7597
7623
|
agent=self.config.agent_profile,
|
|
7624
|
+
task_ref=pr_origin_task_ref(pr.body),
|
|
7625
|
+
repo=pr.full_name,
|
|
7598
7626
|
dry_run=self.config.dry_run,
|
|
7599
7627
|
)
|
|
7600
7628
|
|
|
@@ -7985,6 +8013,8 @@ class DevWatcher:
|
|
|
7985
8013
|
directive=directive,
|
|
7986
8014
|
cwd=hub,
|
|
7987
8015
|
agent=self.config.agent_profile,
|
|
8016
|
+
task_ref=pr_origin_task_ref(pr.body),
|
|
8017
|
+
repo=pr.full_name,
|
|
7988
8018
|
dry_run=self.config.dry_run,
|
|
7989
8019
|
)
|
|
7990
8020
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
0.8.
|
|
1
|
+
0.8.36
|
{alissa_tools_github_devloop-0.8.34.dist-info → alissa_tools_github_devloop-0.8.36.dist-info}/RECORD
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
alissa/tools/github/devloop/__init__.py,sha256=PQXfVmykwq6E1S3g0c49wW6v8jB3y8svslqXUWd2NRI,506
|
|
2
2
|
alissa/tools/github/devloop/__main__.py,sha256=5p_SjwpOvdyTA8pPr54gS-RP99itkydVcdAJc-9hH_g,26897
|
|
3
|
-
alissa/tools/github/devloop/alissa.py,sha256=
|
|
3
|
+
alissa/tools/github/devloop/alissa.py,sha256=TJU4eSZc2MvP35HewCwBKvhPAel32vKjtt3ApSPDLrM,18064
|
|
4
4
|
alissa/tools/github/devloop/alissa_client.py,sha256=wmpXYWf9ThcLeYnz6gGeDz7gj5BpYjduuVASMc-QOOY,14873
|
|
5
5
|
alissa/tools/github/devloop/bows.py,sha256=pzDNMRk_S78FX7vMNYMlXHxW6VPHPo1Xd2EzFMgVCUM,17325
|
|
6
6
|
alissa/tools/github/devloop/config.py,sha256=VKeyTsXfoRSDltuU1h9UqjrHGE6YvgCQDvimDt3BH58,73330
|
|
@@ -8,12 +8,12 @@ alissa/tools/github/devloop/fleet_vitals.py,sha256=lAlTxqhmz6IyOL5WXJqUyIcc2zJtW
|
|
|
8
8
|
alissa/tools/github/devloop/ghclient.py,sha256=tYUHwmoy9CBBt-jSOz9nuAl8lpMvm1LH4A-wHx25bss,71842
|
|
9
9
|
alissa/tools/github/devloop/hubs.py,sha256=yjnsnSHLG7GNNP8X2hILeAMV6P5n4JGc_IaAxpSP_YQ,18974
|
|
10
10
|
alissa/tools/github/devloop/janitor.py,sha256=R8REoHBeY2cfW7fYJVhKr-F5z9Mjlc-vmv-z4KtvBZc,27360
|
|
11
|
-
alissa/tools/github/devloop/loop.py,sha256=
|
|
11
|
+
alissa/tools/github/devloop/loop.py,sha256=tjiXMjX6qIftdAsv_XXP3HqL9RRXp04kLMZAkb7Tnvw,578068
|
|
12
12
|
alissa/tools/github/devloop/loop_events.py,sha256=kPjm440vrAfjQ8NCkkoG6JBZHtiNjRXTgRxHnvEAO9Q,37847
|
|
13
13
|
alissa/tools/github/devloop/proc.py,sha256=_dDr3g76WEf2DRyLUz1Dzl4KvLVptJant_UZOrRixNk,1649
|
|
14
14
|
alissa/tools/github/devloop/prompts.py,sha256=VzN6ec5eF2wwg7QSCRg52WLcxo-tGbGRgQbc4HSahUc,55169
|
|
15
15
|
alissa/tools/github/devloop/state.py,sha256=8G7ZYE3vDkcbqd-3BNEsZ6HJMuAad4tkrOkdd88Yzqk,82740
|
|
16
|
-
alissa/tools/github/devloop/version,sha256=
|
|
16
|
+
alissa/tools/github/devloop/version,sha256=x-VxE4tc86mAFbKxuaEDSgfa61wSt1IQnVhb7pyGioM,7
|
|
17
17
|
alissa/tools/github/devloop/version.py,sha256=znuuOaitXGrBpbskNy78_rlVpFdtmKmk_3k1ACxZrl0,1418
|
|
18
18
|
alissa/tools/github/devloop/webui/__init__.py,sha256=vdXYoyGYzD7BrJ5lV6XdH8Bpw_pej8-RK0hjfxop7-8,1513
|
|
19
19
|
alissa/tools/github/devloop/webui/__main__.py,sha256=FCkklWZLPUJtRPZTrPRkCdMInWPXLaLyCWm9hy3jhg8,5097
|
|
@@ -22,10 +22,10 @@ alissa/tools/github/devloop/webui/page.py,sha256=4OD3e01ByvVM4Wo04AZyFuyOYTFEMT2
|
|
|
22
22
|
alissa/tools/github/devloop/webui/server.py,sha256=cjrpxeFtYkwF4DqswF_J8-CanDQ5ih35xMfh8aUiomU,19391
|
|
23
23
|
alissa/tools/github/devloop/webui/sources.py,sha256=725iIw2phgEaxbIePAPkdQQ-d57T0mztPb-aVXVawxk,34366
|
|
24
24
|
alissa/tools/github/devloop/webui/sysinfo.py,sha256=ptlogH9alFv0vZ-pQfyUaA3w-K7LQS3tQHGv0d8Tdlk,9649
|
|
25
|
-
alissa_tools_github_devloop-0.8.
|
|
26
|
-
alissa_tools_github_devloop-0.8.
|
|
27
|
-
alissa_tools_github_devloop-0.8.
|
|
28
|
-
alissa_tools_github_devloop-0.8.
|
|
29
|
-
alissa_tools_github_devloop-0.8.
|
|
30
|
-
alissa_tools_github_devloop-0.8.
|
|
31
|
-
alissa_tools_github_devloop-0.8.
|
|
25
|
+
alissa_tools_github_devloop-0.8.36.dist-info/licenses/LICENSE,sha256=z8d0m5b2O9McPEK1xHG_dWgUBT6EfBDz6wA0F7xSPTA,11358
|
|
26
|
+
alissa_tools_github_devloop-0.8.36.dist-info/licenses/NOTICE,sha256=FKstNs3uw_tQod4_1XcFLD1FUTJQXf4FC0oXJAOA_HE,260
|
|
27
|
+
alissa_tools_github_devloop-0.8.36.dist-info/METADATA,sha256=Vu4c1sxJMxGTEMK_3r_KHJMKlDaqkfF6HLhp_UFfjyI,8093
|
|
28
|
+
alissa_tools_github_devloop-0.8.36.dist-info/WHEEL,sha256=YVMoNqKzERt-wjUZwJ33xBGAwnFl-4cqbYkTtWa4itE,91
|
|
29
|
+
alissa_tools_github_devloop-0.8.36.dist-info/entry_points.txt,sha256=8aC7Ajzx4bu9ZRR37a40IDfuStacvZP5KsAxY1dbFKU,145
|
|
30
|
+
alissa_tools_github_devloop-0.8.36.dist-info/top_level.txt,sha256=DodjDg-l-TWQnlxG-Vuc3G5sB4O7cWGQwe6XrVx3u-A,7
|
|
31
|
+
alissa_tools_github_devloop-0.8.36.dist-info/RECORD,,
|
{alissa_tools_github_devloop-0.8.34.dist-info → alissa_tools_github_devloop-0.8.36.dist-info}/WHEEL
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|