mycode-cli 0.3.1__py3-none-any.whl → 0.3.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.
mycode/cli/render.py CHANGED
@@ -669,7 +669,11 @@ class ReplyRenderer:
669
669
  self._thinking_collapsed = True
670
670
 
671
671
  if self._live is not None:
672
+ # Rich's stop() refreshes the last renderable once more before
673
+ # restoring the cursor. Blank it first so a final spinner frame
674
+ # can't get stranded in terminals that occasionally miss the clear.
672
675
  self._live.transient = True
676
+ self._live.update(Text(""))
673
677
  self._live.stop()
674
678
  self._live = None
675
679
 
@@ -112,7 +112,9 @@ class GoogleGeminiAdapter(ProviderAdapter):
112
112
  api_version = "v1beta"
113
113
  if base_url and urlparse(base_url).path.rstrip("/").lower().endswith(("/v1", "/v1beta")):
114
114
  api_version = None
115
- return types.HttpOptions(base_url=base_url, api_version=api_version, timeout=int(DEFAULT_REQUEST_TIMEOUT))
115
+ # google-genai expects milliseconds here; DEFAULT_REQUEST_TIMEOUT is seconds.
116
+ timeout_ms = int(DEFAULT_REQUEST_TIMEOUT * 1000)
117
+ return types.HttpOptions(base_url=base_url, api_version=api_version, timeout=timeout_ms)
116
118
 
117
119
  def _build_contents(self, request: ProviderRequest) -> list[dict[str, Any]]:
118
120
  """Convert canonical replay messages into Gemini contents."""
@@ -219,8 +221,6 @@ class GoogleGeminiAdapter(ProviderAdapter):
219
221
 
220
222
  def _build_config(self, request: ProviderRequest) -> types.GenerateContentConfig:
221
223
  tools: list[types.Tool | Any] | None = None
222
- tool_config = None
223
- automatic_function_calling = None
224
224
  if request.tools:
225
225
  tools = [
226
226
  types.Tool(
@@ -234,10 +234,6 @@ class GoogleGeminiAdapter(ProviderAdapter):
234
234
  ]
235
235
  )
236
236
  ]
237
- automatic_function_calling = types.AutomaticFunctionCallingConfig(disable=True)
238
- tool_config = types.ToolConfig(
239
- function_calling_config=types.FunctionCallingConfig(stream_function_call_arguments=False)
240
- )
241
237
 
242
238
  thinking_config = types.ThinkingConfig(include_thoughts=True)
243
239
  if request.reasoning_effort and request.model.lower().startswith("gemini-3"):
@@ -260,8 +256,6 @@ class GoogleGeminiAdapter(ProviderAdapter):
260
256
  system_instruction=request.system or None,
261
257
  max_output_tokens=request.max_tokens,
262
258
  tools=tools,
263
- tool_config=tool_config,
264
- automatic_function_calling=automatic_function_calling,
265
259
  thinking_config=thinking_config,
266
260
  )
267
261
 
@@ -13,6 +13,7 @@ import logging
13
13
  import re
14
14
  from collections import deque
15
15
  from dataclasses import dataclass
16
+ from datetime import date
16
17
  from pathlib import Path
17
18
 
18
19
  import yaml
@@ -35,9 +36,8 @@ You have four tools: read, write, edit, bash.
35
36
  - Use bash for file operations and exploration like `ls`, `find`, `rg`, etc.
36
37
  - Always set offset/limit when reading large files.
37
38
  - Always read files before editing them.
38
- - Use write only for new files or complete rewrites
39
- - Your response should be concise and relevant.
40
- - When available skills match the current task, prefer them over manual alternatives. To use a skill: read its `SKILL.md`, then follow the instructions inside.\
39
+ - Use write only for new files or complete rewrites.
40
+ - Your response should be concise and relevant.\
41
41
  """
42
42
 
43
43
 
@@ -62,7 +62,7 @@ def build_system_prompt(cwd: str, settings: Settings | None = None) -> str:
62
62
  if skills_prompt:
63
63
  parts.append(skills_prompt)
64
64
 
65
- parts.append(f"Current working directory: {resolved_cwd}")
65
+ parts.append(f"Current working directory: {resolved_cwd}\nCurrent date: {date.today().strftime('%Y-%m')}")
66
66
  return "\n\n".join(parts)
67
67
 
68
68
 
@@ -108,7 +108,7 @@ def load_instructions_prompt(cwd: str, settings: Settings | None = None) -> str:
108
108
  continue
109
109
 
110
110
  if text:
111
- sections.append(f"## {path}\n{text}")
111
+ sections.append(f"Instructions from: {path}\n{text}")
112
112
 
113
113
  if not sections:
114
114
  return ""
@@ -116,7 +116,7 @@ def load_instructions_prompt(cwd: str, settings: Settings | None = None) -> str:
116
116
  return "\n".join(
117
117
  [
118
118
  "<workspace_instructions>",
119
- "Instructions are ordered from global to current cwd. Later files are more specific.",
119
+ "Ordered from global to project; later instructions take precedence.",
120
120
  "",
121
121
  "\n\n".join(sections),
122
122
  "</workspace_instructions>",
@@ -308,12 +308,17 @@ def format_skills_for_prompt(skills: list[Skill]) -> str:
308
308
  if not skills:
309
309
  return ""
310
310
 
311
- lines = ["<available_skills>"]
311
+ lines = [
312
+ "When a task matches a skill's description, prefer it over manual alternatives — use the read tool to load the file at <location> and follow the instructions inside.",
313
+ "Relative paths inside a skill file resolve against the skill's directory (dirname of <location>).",
314
+ "<available_skills>",
315
+ ]
312
316
  for skill in skills:
313
- lines.append(f"- name: {skill.name}")
314
- lines.append(f" path: {skill.path}")
315
- lines.append(f" description: {skill.description}")
316
- lines.append("")
317
+ lines.append(" <skill>")
318
+ lines.append(f" <name>{skill.name}</name>")
319
+ lines.append(f" <description>{skill.description}</description>")
320
+ lines.append(f" <location>{skill.path}</location>")
321
+ lines.append(" </skill>")
317
322
  lines.append("</available_skills>")
318
323
  return "\n".join(lines)
319
324
 
@@ -0,0 +1,12 @@
1
+ import{r as N,h as D,a as _,l as O,j as y,c as q,S as A}from"./index-CY827G4K.js";class R{diff(e,n,t={}){let l;typeof t=="function"?(l=t,t={}):"callback"in t&&(l=t.callback);const o=this.castInput(e,t),i=this.castInput(n,t),a=this.removeEmpty(this.tokenize(o,t)),s=this.removeEmpty(this.tokenize(i,t));return this.diffWithOptionsObj(a,s,t,l)}diffWithOptionsObj(e,n,t,l){var o;const i=m=>{if(m=this.postProcess(m,t),l){setTimeout(function(){l(m)},0);return}else return m},a=n.length,s=e.length;let r=1,d=a+s;t.maxEditLength!=null&&(d=Math.min(d,t.maxEditLength));const h=(o=t.timeout)!==null&&o!==void 0?o:1/0,x=Date.now()+h,f=[{oldPos:-1,lastComponent:void 0}];let p=this.extractCommon(f[0],n,e,0,t);if(f[0].oldPos+1>=s&&p+1>=a)return i(this.buildValues(f[0].lastComponent,n,e));let g=-1/0,P=1/0;const T=()=>{for(let m=Math.max(g,-r);m<=Math.min(P,r);m+=2){let v;const L=f[m-1],j=f[m+1];L&&(f[m-1]=void 0);let u=!1;if(j){const k=j.oldPos-m;u=j&&0<=k&&k<a}const w=L&&L.oldPos+1<s;if(!u&&!w){f[m]=void 0;continue}if(!w||u&&L.oldPos<j.oldPos?v=this.addToPath(j,!0,!1,0,t):v=this.addToPath(L,!1,!0,1,t),p=this.extractCommon(v,n,e,m,t),v.oldPos+1>=s&&p+1>=a)return i(this.buildValues(v.lastComponent,n,e))||!0;f[m]=v,v.oldPos+1>=s&&(P=Math.min(P,m-1)),p+1>=a&&(g=Math.max(g,m+1))}r++};if(l)(function m(){setTimeout(function(){if(r>d||Date.now()>x)return l(void 0);T()||m()},0)})();else for(;r<=d&&Date.now()<=x;){const m=T();if(m)return m}}addToPath(e,n,t,l,o){const i=e.lastComponent;return i&&!o.oneChangePerToken&&i.added===n&&i.removed===t?{oldPos:e.oldPos+l,lastComponent:{count:i.count+1,added:n,removed:t,previousComponent:i.previousComponent}}:{oldPos:e.oldPos+l,lastComponent:{count:1,added:n,removed:t,previousComponent:i}}}extractCommon(e,n,t,l,o){const i=n.length,a=t.length;let s=e.oldPos,r=s-l,d=0;for(;r+1<i&&s+1<a&&this.equals(t[s+1],n[r+1],o);)r++,s++,d++,o.oneChangePerToken&&(e.lastComponent={count:1,previousComponent:e.lastComponent,added:!1,removed:!1});return d&&!o.oneChangePerToken&&(e.lastComponent={count:d,previousComponent:e.lastComponent,added:!1,removed:!1}),e.oldPos=s,r}equals(e,n,t){return t.comparator?t.comparator(e,n):e===n||!!t.ignoreCase&&e.toLowerCase()===n.toLowerCase()}removeEmpty(e){const n=[];for(let t=0;t<e.length;t++)e[t]&&n.push(e[t]);return n}castInput(e,n){return e}tokenize(e,n){return Array.from(e)}join(e){return e.join("")}postProcess(e,n){return e}get useLongestToken(){return!1}buildValues(e,n,t){const l=[];let o;for(;e;)l.push(e),o=e.previousComponent,delete e.previousComponent,e=o;l.reverse();const i=l.length;let a=0,s=0,r=0;for(;a<i;a++){const d=l[a];if(d.removed)d.value=this.join(t.slice(r,r+d.count)),r+=d.count;else{if(!d.added&&this.useLongestToken){let h=n.slice(s,s+d.count);h=h.map(function(x,f){const p=t[r+f];return p.length>x.length?p:x}),d.value=this.join(h)}else d.value=this.join(n.slice(s,s+d.count));s+=d.count,d.added||(r+=d.count)}}return l}}class z extends R{constructor(){super(...arguments),this.tokenize=V}equals(e,n,t){return t.ignoreWhitespace?((!t.newlineIsToken||!e.includes(`
2
+ `))&&(e=e.trim()),(!t.newlineIsToken||!n.includes(`
3
+ `))&&(n=n.trim())):t.ignoreNewlineAtEof&&!t.newlineIsToken&&(e.endsWith(`
4
+ `)&&(e=e.slice(0,-1)),n.endsWith(`
5
+ `)&&(n=n.slice(0,-1))),super.equals(e,n,t)}}const B=new z;function W(c,e,n){return B.diff(c,e,n)}function V(c,e){e.stripTrailingCr&&(c=c.replace(/\r\n/g,`
6
+ `));const n=[],t=c.split(/(\n|\r\n)/);t[t.length-1]||t.pop();for(let l=0;l<t.length;l++){const o=t[l];l%2&&!e.newlineIsToken?n[n.length-1]+=o:n.push(o)}return n}const F={js:"javascript",mjs:"javascript",cjs:"javascript",jsx:"jsx",ts:"typescript",tsx:"tsx",py:"python",rb:"ruby",rs:"rust",go:"go",java:"java",kt:"kotlin",swift:"swift",c:"c",cpp:"cpp",h:"c",hpp:"cpp",cs:"csharp",php:"php",html:"html",css:"css",scss:"scss",less:"less",json:"json",jsonc:"jsonc",yaml:"yaml",yml:"yaml",toml:"toml",md:"markdown",mdx:"mdx",sh:"bash",bash:"bash",zsh:"bash",sql:"sql",graphql:"graphql",gql:"graphql",xml:"xml",svg:"xml",vue:"vue",svelte:"svelte"};function X(c){const e=c?.split(".").pop()?.toLowerCase();return e?F[e]??"text":"text"}function C(c){return c.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}function G(c){const e=c.indexOf("<code>"),n=c.lastIndexOf("</code>");return e===-1||n===-1?[]:c.slice(e+6,n).split('<span class="line">').slice(1).map(i=>{const a=i.lastIndexOf("</span>");return a===-1?i:i.slice(0,a)})}function E(c,e,n){const t=q(c,e,{lang:n,...A});return t?G(t):e.split(`
7
+ `).map(C)}const $=3;function H(c,e,n,t){const l=W(c||"",e||"");let o=0,i=0,a=0;const s=[];for(const h of l){const x=h.value.replace(/\n$/,"").split(`
8
+ `);if(h.removed)for(const f of x)s.push({key:`r-${i}`,type:"removed",ln:null,html:n[i++]??C(f)});else if(h.added)for(const f of x)s.push({key:`a-${a}`,type:"added",ln:o++,html:t[a++]??C(f)});else for(const f of x)s.push({key:`c-${o}-${i}`,type:"context",ln:o++,html:n[i++]??C(f)}),a++}const r=new Uint8Array(s.length);for(const[h,x]of s.entries()){if(x.type==="context")continue;const f=Math.max(0,h-$),p=Math.min(s.length-1,h+$);for(let g=f;g<=p;g++)r[g]=1}return s.some(h=>h.type!=="context")?s.filter((h,x)=>r[x]):s}function S(c,e,n,t,l,o){const i=l.join(`
9
+ `),a=o.join(`
10
+ `),s=[i,n||"",a].filter(Boolean).join(`
11
+ `),r=E(c,s,e),d=[i,t||"",a].filter(Boolean).join(`
12
+ `),h=E(c,d,e),x=l.length,f=o.length;return{oldHighlighted:r.slice(x,r.length-f),newHighlighted:h.slice(x,h.length-f),ctxBeforeHtml:l.map((p,g)=>r[g]??C(p)),ctxAfterHtml:o.map((p,g)=>r[r.length-f+g]??C(p))}}function J(c,e,n){const t=[];for(const[l,o]of c.entries()){l>0&&t.push({key:`sep-${l}`,type:"separator",ln:null,html:""});const{oldHighlighted:i,newHighlighted:a}=S(e,n,o.oldText,o.newText,[],[]),s=H(o.oldText,o.newText,i,a);for(const r of s)t.push({...r,key:`e${l}-${r.key}`})}return t}function K(c,e,n){if(!c.every(o=>o.meta!=null))return J(c,e,n);const t=[];let l=-1/0;for(const[o,i]of c.entries()){const a=i.meta;if(!a)continue;const s=a.start_line,r=a.new_line_count,d=a.context_before??[],h=a.context_after??[],x=s-d.length;let f=d;if(l>-1/0){const u=l-x;u>0?f=d.slice(u):u<0&&t.push({key:`sep-${o}`,type:"separator",ln:null,html:""})}let p=h;if(o<c.length-1){const u=c[o+1]?.meta??null,w=u?.start_line??1,k=u?.context_before??[],b=w-k.length,I=s+r;if(I+h.length>b){const M=Math.max(0,b-I);p=h.slice(0,M)}}const{oldHighlighted:g,newHighlighted:P,ctxBeforeHtml:T,ctxAfterHtml:m}=S(e,n,i.oldText,i.newText,f,p);let v=s-f.length;for(let u=0;u<f.length;u++){const w=f[u];w!==void 0&&t.push({key:`e${o}-cb-${v}`,type:"context",ln:v++,html:T[u]??C(w)})}const L=H(i.oldText,i.newText,g,P);for(const u of L)t.push({...u,key:`e${o}-${u.key}`,ln:u.ln!==null?u.ln+s:null});let j=s+r;for(let u=0;u<p.length;u++){const w=p[u];w!==void 0&&t.push({key:`e${o}-ca-${j}`,type:"context",ln:j++,html:m[u]??C(w)})}l=s+r+p.length}return t}function Y({path:c,edits:e}){const n=N.use(D),t=_(X(c));let o=n.getLoadedLanguages().includes(t)?t:"text";if(o==="text"&&t!=="text"){const s=O(n,t),r=N.use(s);r&&(o=r)}const i=K(e,n,o),a=e.some(s=>s.meta!=null);return y.jsxs("div",{className:"rounded-md bg-code overflow-hidden",children:[c&&y.jsx("div",{className:"px-3 pt-2",children:y.jsx("span",{className:"text-[11px] font-mono text-muted-foreground/30 tracking-wider select-none",children:c})}),y.jsx("div",{className:"overflow-x-auto scrollbar-subtle",children:y.jsx("table",{className:"w-full border-collapse",style:{fontFamily:'"DM Mono", "JetBrains Mono", monospace',fontSize:"13px",lineHeight:"1.5"},children:y.jsx("tbody",{children:i.map(s=>s.type==="separator"?y.jsx("tr",{children:y.jsx("td",{colSpan:a?3:2,className:"text-center text-muted-foreground/20 select-none py-0.5 text-xs",children:"···"})},s.key):y.jsxs("tr",{className:s.type==="removed"?"diff-line-removed":s.type==="added"?"diff-line-added":"",children:[a&&y.jsx("td",{className:"diff-ln select-none w-8 min-w-8 text-right align-top pr-2 text-muted-foreground/20 tabular-nums",children:s.ln??""}),y.jsx("td",{className:`select-none w-5 min-w-5 text-center align-top ${s.type==="removed"?"diff-gutter-removed":s.type==="added"?"diff-gutter-added":"text-transparent"}`,children:s.type==="removed"?"−":s.type==="added"?"+":" "}),y.jsx("td",{className:"pr-3 whitespace-pre",children:y.jsx("span",{className:"shiki",dangerouslySetInnerHTML:{__html:s.html}})})]},s.key))})})})]})}export{Y as default};