@tiens.nguyen/gu-cli 1.0.726 → 1.0.727

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.
@@ -1757,15 +1757,15 @@ def _load_prompt_scaffold(api_base: str, worker_key: str):
1757
1757
  file is NOT quietly replaced by the database version, or an edit that broke it would look like
1758
1758
  it had no effect."""
1759
1759
  if os.path.isfile(_LOCAL_SCAFFOLD_PATH):
1760
- where = "~/.gonext/prompt-scaffolds/code-agent.txt"
1760
+ where = _psc.LOCAL_SCAFFOLD_LABEL # never the path — see prompt_scaffold_check.py
1761
1761
  try:
1762
1762
  with open(_LOCAL_SCAFFOLD_PATH, encoding="utf-8") as f:
1763
1763
  text = f.read()
1764
1764
  except Exception as e: # noqa: BLE001
1765
1765
  raise _AgentConfigError(
1766
- f"The agent couldn't start: your local scaffold {where} could not be read "
1766
+ f"The agent couldn't start: {where} could not be read "
1767
1767
  f"({type(e).__name__}). Fix it, or delete it to use the gu service's.") from None
1768
- problem = _scaffold_problem(text, f"your local scaffold {where}")
1768
+ problem = _scaffold_problem(text, where)
1769
1769
  if problem:
1770
1770
  raise _AgentConfigError(
1771
1771
  f"The agent couldn't start: {problem}. Fix it, or delete it to use the gu service's.")
@@ -2356,7 +2356,8 @@ def _render_prompt(messages, max_chars: int = 400_000) -> str:
2356
2356
  # the API and shown on the token-usage page — so it would hand the hidden text to
2357
2357
  # anyone who opens a step. Its size stays visible, the text does not.
2358
2358
  v = _PROMPT_SCAFFOLD_VERSION["v"]
2359
- label = " (your local file)" if v == "local" else (f" v{v}" if v is not None else "")
2359
+ # The same words whatever the source — a local file is never announced (the user's call).
2360
+ label = f" v{v}" if isinstance(v, int) else ""
2360
2361
  text = (f"[prompt scaffold{label} with the tool signatures — "
2361
2362
  f"{len(text)} characters, not shown]")
2362
2363
  out.append(f"───── {role or 'message'} ─────\n{text}")
@@ -12177,10 +12178,8 @@ def run_agent_chat(cfg):
12177
12178
  # TURN_FAILED) instead of quietly running on a different prompt. The version is
12178
12179
  # logged; the text never is.
12179
12180
  _scaffold, _scaffold_version, _scaffold_source = _load_prompt_scaffold(worker_api_base, worker_api_key)
12180
- if _scaffold_source != "api":
12181
- # SAID, every turn it applies: an old file left lying around must never quietly
12182
- # change the agent. One line in the thinking area, not a banner.
12183
- _emit({"type": "step", "text": f"using your local prompt scaffold ({_scaffold_source})"})
12181
+ # A LOCAL FILE IS USED SILENTLY — no line, no location (the user's call: "if it is on
12182
+ # .gonext location, not say anything"). Only a BROKEN one speaks, and without the path.
12184
12183
  try:
12185
12184
  import yaml as _yaml
12186
12185
  import os as _os
package/gu-repl.mjs CHANGED
@@ -8744,14 +8744,14 @@ const wrapThought = (s, width, maxLines) => {
8744
8744
  * own conversation.
8745
8745
  */
8746
8746
  /**
8747
- * WHERE THIS SESSION'S SCAFFOLD COMES FROM, said at `gu` start (task #246) — "scaffold loaded" from
8748
- * the user's own ~/.gonext/prompt-scaffolds/code-agent.txt, or "scaffold fetched" from the gu
8749
- * service. Background: startup never waits on it (an offline private-mode machine would otherwise
8747
+ * WHERE THIS SESSION'S SCAFFOLD COMES FROM, said at `gu` start (task #246) — "scaffold fetched" from
8748
+ * the gu service; NOTHING at all when it is the user's own local file (by request — its location is
8749
+ * never printed), unless that file is broken. Background: startup never waits on it (an offline private-mode machine would otherwise
8750
8750
  * sit for 10s); the line prints when the answer arrives, or at the next prompt if a turn is running.
8751
8751
  *
8752
8752
  * · A LOCAL FILE is checked with the worker's OWN checker (prompt_scaffold_check.py — size,
8753
- * placeholders, a trial render), so "loaded" means it passed, not merely that it exists. The API
8754
- * is not asked: turns use the file.
8753
+ * placeholders, a trial render); a good one is silent, a broken one is reported. The API is not
8754
+ * asked: turns use the file.
8755
8755
  * · Otherwise the API is asked to REFRESH — the fetch that the rest of the session then reuses
8756
8756
  * ("keep in cache until the user type gu").
8757
8757
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tiens.nguyen/gu-cli",
3
- "version": "1.0.726",
3
+ "version": "1.0.727",
4
4
  "description": "Gu CLI — the gu terminal plus the local worker that runs agent / OCR / PDF / embedding jobs on your Mac (Ollama / MLX / OpenAI-compatible).",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -6,9 +6,9 @@ at startup (`python3 prompt_scaffold_check.py`) so the "scaffold loaded" line it
6
6
  file really passed — not just that a file exists. Needs only jinja2 (a smolagents dependency), so
7
7
  the startup check is quick.
8
8
 
9
- python3 prompt_scaffold_check.py [path] → one JSON line: {"exists", "path", "chars", "problem"}
9
+ python3 prompt_scaffold_check.py [path] → one JSON line: {"exists", "chars", "problem"}
10
10
 
11
- It never prints the scaffold text.
11
+ It never prints the scaffold text, nor where the file is.
12
12
  """
13
13
  import json
14
14
  import os
@@ -19,7 +19,10 @@ import sys
19
19
  # file — the scaffold stays off users' disks unless they put it there themselves — so it is an
20
20
  # override for trying a wording before inserting it into production, not a cache.
21
21
  LOCAL_SCAFFOLD_PATH = os.path.join(os.path.expanduser("~"), ".gonext", "prompt-scaffolds", "code-agent.txt")
22
- LOCAL_SCAFFOLD_LABEL = "~/.gonext/prompt-scaffolds/code-agent.txt"
22
+ # How the file is NAMED in anything a person reads: never its location. Asked for: "dont say out loud
23
+ # where is the location of the scaffold file … not say anything". The deploy app's own Commands
24
+ # window is the one place the path is written down, for its owner.
25
+ LOCAL_SCAFFOLD_LABEL = "your local scaffold file"
23
26
 
24
27
  # What a scaffold must keep — the same list the API and the deploy app use.
25
28
  SCAFFOLD_REQUIRED = (
@@ -97,18 +100,18 @@ def scaffold_problem(template, source: str) -> str:
97
100
  def check_file(path: str = LOCAL_SCAFFOLD_PATH, label: str = LOCAL_SCAFFOLD_LABEL) -> dict:
98
101
  """The local override's state, for `gu` at startup. Never includes the text."""
99
102
  if not os.path.isfile(path):
100
- return {"exists": False, "path": label}
103
+ return {"exists": False}
101
104
  try:
102
105
  with open(path, encoding="utf-8") as f:
103
106
  text = f.read()
104
107
  except Exception as e: # noqa: BLE001
105
- return {"exists": True, "path": label, "chars": 0,
106
- "problem": f"your local scaffold {label} could not be read ({type(e).__name__})"}
107
- return {"exists": True, "path": label, "chars": len(text),
108
- "problem": scaffold_problem(text, f"your local scaffold {label}")}
108
+ return {"exists": True, "chars": 0,
109
+ "problem": f"{label} could not be read ({type(e).__name__})"}
110
+ return {"exists": True, "chars": len(text),
111
+ "problem": scaffold_problem(text, label)}
109
112
 
110
113
 
111
114
  if __name__ == "__main__":
112
115
  target = sys.argv[1] if len(sys.argv) > 1 else LOCAL_SCAFFOLD_PATH
113
- label = LOCAL_SCAFFOLD_LABEL if len(sys.argv) <= 1 else target
116
+ label = LOCAL_SCAFFOLD_LABEL
114
117
  print(json.dumps(check_file(target, label)))
@@ -1770,20 +1770,22 @@ export function lazyModuleNames(text) {
1770
1770
 
1771
1771
  /**
1772
1772
  * The one line `gu` prints at startup about the agent's prompt scaffold (task #246) — asked for so
1773
- * the user KNOWS where this session's scaffold came from: "scaffold is loaded" (their own file) or
1774
- * "scaffold is fetched" (the gu service). Pure; gu-repl gathers the facts.
1773
+ * the user knows where this session's scaffold came from — the gu service ("fetched") — and hears
1774
+ * NOTHING when it is their own local file (by request). Pure; gu-repl gathers the facts.
1775
1775
  *
1776
1776
  * local — prompt_scaffold_check.py's answer: { exists, path, chars, problem } (null = not run)
1777
1777
  * refresh — POST /api/worker/prompt-scaffold/refresh: { status, ok, version, error, kept }
1778
1778
  * private — private mode (the local API), which decides what "update" advice means
1779
- * Returns { kind: "ok" | "warn" | "err", text }.
1779
+ * Returns { kind: "ok" | "warn" | "err", text }, or null when there is nothing to say.
1780
1780
  */
1781
1781
  export function scaffoldStartupNotice({ local = null, refresh = null, private: privateMode = false } = {}) {
1782
- const n = (x) => Number(x ?? 0).toLocaleString("en-US");
1782
+ // YOUR LOCAL FILE, WORKING: nothing is said — no line, no location (the user's call: "dont say
1783
+ // out loud where is the location of the scaffold file … not say anything"). null = print nothing.
1784
+ // A BROKEN one still speaks, without the path: otherwise every turn fails with no explanation.
1783
1785
  if (local?.exists) {
1784
1786
  return local.problem
1785
1787
  ? { kind: "err", text: `scaffold: ${local.problem} — fix it, or delete it to use the gu service's` }
1786
- : { kind: "ok", text: `scaffold loaded from ${local.path} (${n(local.chars)} chars)` };
1788
+ : null;
1787
1789
  }
1788
1790
  if (!refresh) return { kind: "warn", text: "scaffold: couldn't ask the API — the first turn will try again" };
1789
1791
  if (refresh.status === 404) {