clouds-coder 2026.3.16__tar.gz → 2026.3.17__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.
- {clouds_coder-2026.3.16 → clouds_coder-2026.3.17}/Clouds_Coder.py +58 -31
- {clouds_coder-2026.3.16/clouds_coder.egg-info → clouds_coder-2026.3.17}/PKG-INFO +1 -5
- {clouds_coder-2026.3.16 → clouds_coder-2026.3.17}/README.md +0 -4
- {clouds_coder-2026.3.16 → clouds_coder-2026.3.17/clouds_coder.egg-info}/PKG-INFO +1 -5
- {clouds_coder-2026.3.16 → clouds_coder-2026.3.17}/pyproject.toml +1 -1
- {clouds_coder-2026.3.16 → clouds_coder-2026.3.17}/LICENSE +0 -0
- {clouds_coder-2026.3.16 → clouds_coder-2026.3.17}/clouds_coder.egg-info/SOURCES.txt +0 -0
- {clouds_coder-2026.3.16 → clouds_coder-2026.3.17}/clouds_coder.egg-info/dependency_links.txt +0 -0
- {clouds_coder-2026.3.16 → clouds_coder-2026.3.17}/clouds_coder.egg-info/entry_points.txt +0 -0
- {clouds_coder-2026.3.16 → clouds_coder-2026.3.17}/clouds_coder.egg-info/requires.txt +0 -0
- {clouds_coder-2026.3.16 → clouds_coder-2026.3.17}/clouds_coder.egg-info/top_level.txt +0 -0
- {clouds_coder-2026.3.16 → clouds_coder-2026.3.17}/setup.cfg +0 -0
- {clouds_coder-2026.3.16 → clouds_coder-2026.3.17}/tests/test_smoke.py +0 -0
|
@@ -75,6 +75,8 @@ AGENT_MAX_OUTPUT_TOKENS = 16384
|
|
|
75
75
|
OLLAMA_THINKING_TOOL_BUFFER = 4096
|
|
76
76
|
WATCHDOG_INTENT_NO_TOOL_THRESHOLD = 2
|
|
77
77
|
WATCHDOG_REPEAT_NO_TOOL_THRESHOLD = 2
|
|
78
|
+
WATCHDOG_INTENT_NO_TOOL_THRESHOLD_SINGLE = 4
|
|
79
|
+
WATCHDOG_REPEAT_NO_TOOL_THRESHOLD_SINGLE = 4
|
|
78
80
|
WATCHDOG_STATE_STALL_THRESHOLD = 6
|
|
79
81
|
WATCHDOG_CONTEXT_STALL_THRESHOLD = 2
|
|
80
82
|
WATCHDOG_REPEAT_SIMILARITY_THRESHOLD = 0.85
|
|
@@ -2354,7 +2356,7 @@ def try_read_text(path: Path, max_bytes: int = 400_000) -> str | None:
|
|
|
2354
2356
|
except Exception:
|
|
2355
2357
|
return None
|
|
2356
2358
|
|
|
2357
|
-
def make_unified_diff(path: str, old_text: str, new_text: str, max_lines: int = 400) -> str:
|
|
2359
|
+
def make_unified_diff(path: str, old_text: str, new_text: str, max_lines: int = 400) -> tuple[str, int, int]:
|
|
2358
2360
|
old_lines = old_text.splitlines()
|
|
2359
2361
|
new_lines = new_text.splitlines()
|
|
2360
2362
|
diff = list(
|
|
@@ -2366,9 +2368,12 @@ def make_unified_diff(path: str, old_text: str, new_text: str, max_lines: int =
|
|
|
2366
2368
|
lineterm="",
|
|
2367
2369
|
)
|
|
2368
2370
|
)
|
|
2369
|
-
if
|
|
2371
|
+
added = sum(1 for ln in diff if ln.startswith("+") and not ln.startswith("+++"))
|
|
2372
|
+
deleted = sum(1 for ln in diff if ln.startswith("-") and not ln.startswith("---"))
|
|
2373
|
+
if max_lines and len(diff) > max_lines:
|
|
2370
2374
|
diff = diff[:max_lines] + [f"... diff truncated, total lines={len(diff)}"]
|
|
2371
|
-
|
|
2375
|
+
text = "\n".join(diff) if diff else f"@@ no textual diff for {path}"
|
|
2376
|
+
return text, added, deleted
|
|
2372
2377
|
|
|
2373
2378
|
def _skip_row(text: str) -> dict:
|
|
2374
2379
|
msg = str(text or "").strip() or "⋮"
|
|
@@ -7226,6 +7231,7 @@ class SessionState:
|
|
|
7226
7231
|
self.multimodal_capability_cache: dict[str, dict] = {}
|
|
7227
7232
|
self.failed_selections: list[str] = []
|
|
7228
7233
|
self.todo = TodoManager()
|
|
7234
|
+
self.single_advance_prompt_enhance = False
|
|
7229
7235
|
self.skills = SkillStore(skills_root)
|
|
7230
7236
|
self.skill_load_cache: dict[str, dict] = {}
|
|
7231
7237
|
self.skills_last_refresh_ts = 0.0
|
|
@@ -8900,6 +8906,19 @@ class SessionState:
|
|
|
8900
8906
|
budget = int(self.runtime_round_budget or 0)
|
|
8901
8907
|
html_block = f"{html_hint}\n\n" if html_hint else ""
|
|
8902
8908
|
research_block = f"{research_hint}\n\n" if research_hint else ""
|
|
8909
|
+
_is_single_no_enhance = (
|
|
8910
|
+
runtime_mode == EXECUTION_MODE_SINGLE
|
|
8911
|
+
and not self.single_advance_prompt_enhance
|
|
8912
|
+
)
|
|
8913
|
+
skill_hint = (
|
|
8914
|
+
"Use load_skill for workspace-paths and tool-best-practices if needed. "
|
|
8915
|
+
if _is_single_no_enhance
|
|
8916
|
+
else (
|
|
8917
|
+
"Use load_skill for guidance on specific topics "
|
|
8918
|
+
"(workspace-paths, task-management, tool-best-practices, context-management). "
|
|
8919
|
+
"If execution stalls, load_skill('execution-degradation-recovery'). "
|
|
8920
|
+
)
|
|
8921
|
+
)
|
|
8903
8922
|
return (
|
|
8904
8923
|
f"You are a coding agent. Workspace: {self.files_root}. "
|
|
8905
8924
|
f"Task level={runtime_level}, mode={runtime_mode}, "
|
|
@@ -8908,9 +8927,7 @@ class SessionState:
|
|
|
8908
8927
|
f"{_detect_os_shell_instruction()} "
|
|
8909
8928
|
"Use tools to inspect, edit, and execute. "
|
|
8910
8929
|
"Call finish_current_task when done. "
|
|
8911
|
-
"
|
|
8912
|
-
"(workspace-paths, task-management, tool-best-practices, context-management). "
|
|
8913
|
-
"If execution stalls, load_skill('execution-degradation-recovery'). "
|
|
8930
|
+
f"{skill_hint}"
|
|
8914
8931
|
f"{html_block}"
|
|
8915
8932
|
f"{research_block}"
|
|
8916
8933
|
f"{model_language_instruction(self.ui_language)}\n\n"
|
|
@@ -14005,10 +14022,13 @@ class SessionState:
|
|
|
14005
14022
|
bb = self._ensure_blackboard()
|
|
14006
14023
|
dq = self._normalize_decomposition_queue_state(bb.get("decomposition_queue", {}))
|
|
14007
14024
|
trigger_reason = ""
|
|
14025
|
+
_is_single = self._effective_execution_mode() == EXECUTION_MODE_SINGLE
|
|
14026
|
+
_intent_th = WATCHDOG_INTENT_NO_TOOL_THRESHOLD_SINGLE if _is_single else WATCHDOG_INTENT_NO_TOOL_THRESHOLD
|
|
14027
|
+
_repeat_th = WATCHDOG_REPEAT_NO_TOOL_THRESHOLD_SINGLE if _is_single else WATCHDOG_REPEAT_NO_TOOL_THRESHOLD
|
|
14008
14028
|
if not bool(dq.get("active", False)):
|
|
14009
|
-
if int(wd.get("intent_no_tool_streak", 0) or 0) >= int(
|
|
14029
|
+
if int(wd.get("intent_no_tool_streak", 0) or 0) >= int(_intent_th):
|
|
14010
14030
|
trigger_reason = "intent-without-tool-call"
|
|
14011
|
-
elif int(wd.get("repeat_no_tool_streak", 0) or 0) >= int(
|
|
14031
|
+
elif int(wd.get("repeat_no_tool_streak", 0) or 0) >= int(_repeat_th):
|
|
14012
14032
|
trigger_reason = "repeated-no-tool-reply"
|
|
14013
14033
|
elif (
|
|
14014
14034
|
self._watchdog_context_near_limit()
|
|
@@ -18582,11 +18602,9 @@ class SessionState:
|
|
|
18582
18602
|
self._emit("status", {"summary": summary})
|
|
18583
18603
|
out = f"{out}\n{summary}"
|
|
18584
18604
|
after_text = try_read_text(fp, max_bytes=CODE_PREVIEW_STAGE_MAX_BYTES) or ""
|
|
18585
|
-
diff = make_unified_diff(rel, before_text, after_text)
|
|
18605
|
+
diff, added, deleted = make_unified_diff(rel, before_text, after_text)
|
|
18586
18606
|
numbered = make_numbered_diff(before_text, after_text)
|
|
18587
18607
|
numbered_text = render_numbered_diff_text(numbered)
|
|
18588
|
-
added = sum(1 for ln in diff.splitlines() if ln.startswith("+") and not ln.startswith("+++"))
|
|
18589
|
-
deleted = sum(1 for ln in diff.splitlines() if ln.startswith("-") and not ln.startswith("---"))
|
|
18590
18608
|
code_stage = self._record_code_preview_stage(
|
|
18591
18609
|
rel_path=rel,
|
|
18592
18610
|
before_text=before_text,
|
|
@@ -18635,11 +18653,9 @@ class SessionState:
|
|
|
18635
18653
|
self._emit("status", {"summary": summary})
|
|
18636
18654
|
out = f"{out}\n{summary}"
|
|
18637
18655
|
after_text = try_read_text(fp, max_bytes=CODE_PREVIEW_STAGE_MAX_BYTES) or ""
|
|
18638
|
-
diff = make_unified_diff(rel, before_text, after_text)
|
|
18656
|
+
diff, added, deleted = make_unified_diff(rel, before_text, after_text)
|
|
18639
18657
|
numbered = make_numbered_diff(before_text, after_text)
|
|
18640
18658
|
numbered_text = render_numbered_diff_text(numbered)
|
|
18641
|
-
added = sum(1 for ln in diff.splitlines() if ln.startswith("+") and not ln.startswith("+++"))
|
|
18642
|
-
deleted = sum(1 for ln in diff.splitlines() if ln.startswith("-") and not ln.startswith("---"))
|
|
18643
18659
|
code_stage = self._record_code_preview_stage(
|
|
18644
18660
|
rel_path=rel,
|
|
18645
18661
|
before_text=before_text,
|
|
@@ -19265,7 +19281,7 @@ class SessionState:
|
|
|
19265
19281
|
for tc in tool_calls
|
|
19266
19282
|
]
|
|
19267
19283
|
self._append_agent_context_message(role_key, assistant, mirror_to_global=True)
|
|
19268
|
-
if text.strip() or thinking_text:
|
|
19284
|
+
if (text.strip() or thinking_text) and not tool_calls:
|
|
19269
19285
|
emit_text = text if text.strip() else "[thinking-only output]"
|
|
19270
19286
|
self._emit_agent_message(role_key, emit_text, summary=f"{self._agent_display_name(role_key)} response")
|
|
19271
19287
|
if not tool_calls:
|
|
@@ -20251,7 +20267,7 @@ class SessionState:
|
|
|
20251
20267
|
for tc in tool_calls
|
|
20252
20268
|
]
|
|
20253
20269
|
self.messages.append(assistant)
|
|
20254
|
-
if text.strip() or thinking_text:
|
|
20270
|
+
if (text.strip() or thinking_text) and not tool_calls:
|
|
20255
20271
|
emit_text = text if text.strip() else "[thinking-only output]"
|
|
20256
20272
|
emit_summary = "assistant message" if text.strip() else "assistant thinking-only message"
|
|
20257
20273
|
self._emit(
|
|
@@ -20409,6 +20425,8 @@ class SessionState:
|
|
|
20409
20425
|
fault_counter = 0
|
|
20410
20426
|
last_fault_reason = ""
|
|
20411
20427
|
self._prune_runtime_retry_hints()
|
|
20428
|
+
if self.todo.has_open_items():
|
|
20429
|
+
self._mark_all_done_silently("single-mode endpoint exit")
|
|
20412
20430
|
self._emit(
|
|
20413
20431
|
"status",
|
|
20414
20432
|
{
|
|
@@ -20426,6 +20444,8 @@ class SessionState:
|
|
|
20426
20444
|
fault_counter = 0
|
|
20427
20445
|
last_fault_reason = ""
|
|
20428
20446
|
self._prune_runtime_retry_hints()
|
|
20447
|
+
if self.todo.has_open_items():
|
|
20448
|
+
self._mark_all_done_silently("single-mode conclusive/substantial exit")
|
|
20429
20449
|
self._emit(
|
|
20430
20450
|
"status",
|
|
20431
20451
|
{
|
|
@@ -21014,6 +21034,10 @@ class SessionState:
|
|
|
21014
21034
|
except Exception as exc:
|
|
21015
21035
|
self._emit("error", {"summary": f"agent error: {exc}", "trace": traceback.format_exc()})
|
|
21016
21036
|
finally:
|
|
21037
|
+
if self.todo.has_open_items() and not self.cancel_requested:
|
|
21038
|
+
_last = self._latest_agent_assistant_text(single_role) or ""
|
|
21039
|
+
if self._looks_like_conclusive_reply(_last):
|
|
21040
|
+
self._mark_all_done_silently(f"single-mode conclusive exit by {single_role}")
|
|
21017
21041
|
dropped_pending_inputs = 0
|
|
21018
21042
|
removed_runtime_hints = 0
|
|
21019
21043
|
with self.lock:
|
|
@@ -21526,6 +21550,7 @@ class SessionManager:
|
|
|
21526
21550
|
self.arbiter_max_tokens = max(24, min(256, int(arbiter_max_tokens or ARBITER_DEFAULT_MAX_TOKENS)))
|
|
21527
21551
|
self.arbiter_temperature = max(0.0, min(1.0, float(arbiter_temperature if arbiter_temperature is not None else ARBITER_DEFAULT_TEMPERATURE)))
|
|
21528
21552
|
self.execution_mode = normalize_execution_mode(execution_mode, default=EXECUTION_MODE_SYNC)
|
|
21553
|
+
self.single_advance_prompt_enhance = False
|
|
21529
21554
|
env_ok, env_tags, _ = probe_ollama_environment(ollama_base)
|
|
21530
21555
|
self.ollama_env_available = bool(env_ok)
|
|
21531
21556
|
self.ollama_env_tags: list[str] = list(env_tags)
|
|
@@ -21792,6 +21817,7 @@ class SessionManager:
|
|
|
21792
21817
|
min(1.0, float(self.arbiter_temperature if self.arbiter_temperature is not None else ARBITER_DEFAULT_TEMPERATURE)),
|
|
21793
21818
|
)
|
|
21794
21819
|
sess.execution_mode = normalize_execution_mode(self.execution_mode, default=EXECUTION_MODE_SYNC)
|
|
21820
|
+
sess.single_advance_prompt_enhance = bool(self.single_advance_prompt_enhance)
|
|
21795
21821
|
sess._apply_active_profile()
|
|
21796
21822
|
sess.updated_at = now_ts()
|
|
21797
21823
|
sess._persist()
|
|
@@ -22889,6 +22915,7 @@ function _deltaScheduleRender(flags={}){
|
|
|
22889
22915
|
if(S.deltaRenderRaf)return;
|
|
22890
22916
|
S.deltaRenderRaf=requestAnimationFrame(()=>{
|
|
22891
22917
|
S.deltaRenderRaf=0;
|
|
22918
|
+
if(S.refreshInFlight)return;
|
|
22892
22919
|
const needChat=!!S.deltaRenderChat;
|
|
22893
22920
|
const needBoards=!!S.deltaRenderBoards;
|
|
22894
22921
|
const needSessions=!!S.deltaRenderSessions;
|
|
@@ -23048,7 +23075,7 @@ function onRuntimeEvent(evt){
|
|
|
23048
23075
|
const typ=String(evt.type||'');
|
|
23049
23076
|
if(typ==='render_frame'){_renderBridgeEnqueue(evt.data||{});return{handled:true,needsSnapshot:false}}
|
|
23050
23077
|
if(typ==='render_bridge'){const d=evt.data||{};const summary=String(d?.summary||'').trim();if(summary){_renderBridgeShow();_renderBridgeUpdateMeta(summary,true);_renderBridgeHideLater(30000)}return{handled:true,needsSnapshot:false}}
|
|
23051
|
-
if(typ==='compact'){scheduleCompactRefreshBurst(COMPACT_AUTO_REFRESH_COUNT);const reason=parseCompactReason(evt.data||{});if(reason==='auto'||reason.startsWith('truncation-rescue')){const pct=Number(evt.data?.context_left_percent_before);const left=Number(evt.data?.context_left_before);const limit=Number(evt.data?.context_limit_before);const pctTxt=Number.isFinite(pct)?pct.toFixed(1):'-';const leftTxt=Number.isFinite(left)&&Number.isFinite(limit)?`${left}/${limit}`:'-';showCompactToast(`${t('compact_auto')}:${pctTxt}% left (${leftTxt}) · delta-sync`)}_deltaAppendActivity(typ,evt.data||{},Number(evt?.ts||Date.now()/1000));
|
|
23078
|
+
if(typ==='compact'){scheduleCompactRefreshBurst(COMPACT_AUTO_REFRESH_COUNT);const reason=parseCompactReason(evt.data||{});if(reason==='auto'||reason.startsWith('truncation-rescue')){const pct=Number(evt.data?.context_left_percent_before);const left=Number(evt.data?.context_left_before);const limit=Number(evt.data?.context_limit_before);const pctTxt=Number.isFinite(pct)?pct.toFixed(1):'-';const leftTxt=Number.isFinite(left)&&Number.isFinite(limit)?`${left}/${limit}`:'-';showCompactToast(`${t('compact_auto')}:${pctTxt}% left (${leftTxt}) · delta-sync`)}_deltaAppendActivity(typ,evt.data||{},Number(evt?.ts||Date.now()/1000));return{handled:true,needsSnapshot:false}}
|
|
23052
23079
|
return _deltaApplyRuntimeEvent(evt);
|
|
23053
23080
|
}
|
|
23054
23081
|
function _deltaStartWatchdog(){
|
|
@@ -24909,23 +24936,21 @@ async function refreshSnapshot(opt={}){
|
|
|
24909
24936
|
const chatEl=E('chat');
|
|
24910
24937
|
const scrolling=_chatVirtIsUserScrolling(chatEl);
|
|
24911
24938
|
const feedSig=feedSignature(S.snap);
|
|
24912
|
-
if(forceFull||feedSig!==S.lastFeedSig){
|
|
24913
|
-
S.lastFeedSig=feedSig;
|
|
24914
|
-
if(scrolling&&chatEl){
|
|
24915
|
-
_chatVirtDebounceWhileScrolling(chatEl,'_virtScrollSyncTimer',()=>renderChat('snapshot'));
|
|
24916
|
-
}else{
|
|
24917
|
-
if(chatEl)_chatVirtCancelDebounce(chatEl,'_virtScrollSyncTimer');
|
|
24918
|
-
renderChat();
|
|
24919
|
-
}
|
|
24920
|
-
}
|
|
24921
24939
|
const boardSig=boardsSignature(S.snap);
|
|
24922
|
-
|
|
24923
|
-
|
|
24940
|
+
const needChat=forceFull||feedSig!==S.lastFeedSig;
|
|
24941
|
+
const needBoards=forceFull||boardSig!==S.lastBoardsSig;
|
|
24942
|
+
if(needChat)S.lastFeedSig=feedSig;
|
|
24943
|
+
if(needBoards)S.lastBoardsSig=boardSig;
|
|
24944
|
+
if(needChat||needBoards){
|
|
24945
|
+
const doRender=()=>{
|
|
24946
|
+
if(needChat)renderChat('snapshot');
|
|
24947
|
+
if(needBoards)renderBoards();
|
|
24948
|
+
};
|
|
24924
24949
|
if(scrolling&&chatEl){
|
|
24925
|
-
_chatVirtDebounceWhileScrolling(chatEl,'
|
|
24950
|
+
_chatVirtDebounceWhileScrolling(chatEl,'_virtScrollSyncTimer',doRender);
|
|
24926
24951
|
}else{
|
|
24927
|
-
if(chatEl)_chatVirtCancelDebounce(chatEl,'_virtBoardsSyncTimer');
|
|
24928
|
-
|
|
24952
|
+
if(chatEl){_chatVirtCancelDebounce(chatEl,'_virtScrollSyncTimer');_chatVirtCancelDebounce(chatEl,'_virtBoardsSyncTimer');}
|
|
24953
|
+
doRender();
|
|
24929
24954
|
}
|
|
24930
24955
|
}
|
|
24931
24956
|
renderActivePreview(false);
|
|
@@ -26027,6 +26052,8 @@ class AppContext:
|
|
|
26027
26052
|
cfg_max_output_tokens = cfg.get("max_output_tokens")
|
|
26028
26053
|
if cfg_max_output_tokens is not None:
|
|
26029
26054
|
self.max_output_tokens = max(256, int(cfg_max_output_tokens))
|
|
26055
|
+
if "single_advance_prompt_enhance" in cfg:
|
|
26056
|
+
self.single_advance_prompt_enhance = bool(cfg["single_advance_prompt_enhance"])
|
|
26030
26057
|
|
|
26031
26058
|
def normalized_profiles() -> tuple[dict[str, dict], str]:
|
|
26032
26059
|
rows: dict[str, dict] = {}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: clouds-coder
|
|
3
|
-
Version: 2026.3.
|
|
3
|
+
Version: 2026.3.17
|
|
4
4
|
Summary: Clouds Coder: local-first Cloud CLI coder runtime with Web UI and Skills Studio.
|
|
5
5
|
Author: Clouds Coder Contributors
|
|
6
6
|
License: MIT
|
|
@@ -801,7 +801,3 @@ flowchart TD
|
|
|
801
801
|
## 13. License
|
|
802
802
|
|
|
803
803
|
This project is released under the MIT License. See [LICENSE](./LICENSE).
|
|
804
|
-
|
|
805
|
-
---
|
|
806
|
-
|
|
807
|
-
If you plan to publish on GitHub, recommended next step is to add a small `CHANGELOG.md` and one architecture diagram image under `docs/` for faster onboarding.
|
|
@@ -774,7 +774,3 @@ flowchart TD
|
|
|
774
774
|
## 13. License
|
|
775
775
|
|
|
776
776
|
This project is released under the MIT License. See [LICENSE](./LICENSE).
|
|
777
|
-
|
|
778
|
-
---
|
|
779
|
-
|
|
780
|
-
If you plan to publish on GitHub, recommended next step is to add a small `CHANGELOG.md` and one architecture diagram image under `docs/` for faster onboarding.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: clouds-coder
|
|
3
|
-
Version: 2026.3.
|
|
3
|
+
Version: 2026.3.17
|
|
4
4
|
Summary: Clouds Coder: local-first Cloud CLI coder runtime with Web UI and Skills Studio.
|
|
5
5
|
Author: Clouds Coder Contributors
|
|
6
6
|
License: MIT
|
|
@@ -801,7 +801,3 @@ flowchart TD
|
|
|
801
801
|
## 13. License
|
|
802
802
|
|
|
803
803
|
This project is released under the MIT License. See [LICENSE](./LICENSE).
|
|
804
|
-
|
|
805
|
-
---
|
|
806
|
-
|
|
807
|
-
If you plan to publish on GitHub, recommended next step is to add a small `CHANGELOG.md` and one architecture diagram image under `docs/` for faster onboarding.
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "clouds-coder"
|
|
7
|
-
version = "2026.3.
|
|
7
|
+
version = "2026.3.17"
|
|
8
8
|
description = "Clouds Coder: local-first Cloud CLI coder runtime with Web UI and Skills Studio."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.10"
|
|
File without changes
|
|
File without changes
|
{clouds_coder-2026.3.16 → clouds_coder-2026.3.17}/clouds_coder.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|