feat: interactive update checker + REPL/telemetry/cloud polish#58
Merged
Conversation
An empty __release_date__ indicates an unpackaged local source build, which should not pollute production observability. Treat it the same as DISABLE_TELEMETRY=1, gating both the default ARMS exporters and any user-configured OTLP endpoint. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Identify and triage iac-code traffic server-side. Format: iac-code/<version>+<release_date|dev> (<os>; <arch>; Python/<py_ver>). Centralized in user_agent.build_user_agent() and wired into every Config branch in aliyun_api and ros_client; local source builds carry "+dev" so production logs can filter them. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The / trigger continues to surface both built-in commands and skills. The new $ trigger lists/invokes skills only; typing $<built-in> shows a clear error pointing at the / equivalent so users aren't left guessing. - token_extractor: recognize $ as a trigger character at token start - skill_provider: new SuggestionProvider that filters matches to PromptCommand instances (skills only) - registry: is_command()/parse() accept the $ prefix - repl: wire SkillProvider into the aggregator; route $<local> and $<unknown> to a clear, translated error - i18n: translate the two new strings in zh, es, fr, de, ja, pt Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
When a tool's input is still being streamed (tool_input={}, partial_input
accumulating JSON fragments), the renderer used to show '● Read' with no
detail until the full JSON was parsed at content_block_stop. Now it shows
e.g. '● Read(src/foo.py)' as soon as the path field's closing quote has
streamed, by extracting opt-in string fields from partial_input.
- utils/json_utils: new extract_partial_string_fields() helper. The regex
matches only fully-closed "key": "value" pairs, so truncated values
never leak. JSON escapes decoded via json.loads.
- tools/base: add opt-in Tool.streaming_preview_fields() hook (default []).
- tools/read_file, write_file, edit_file: override to return ["path"].
- ui/renderer: _render_tool_header derives an effective_input from
partial_input when tool_input is empty and the tool opted in. Once the
real ToolUseEndEvent arrives, the real dict takes over.
- tools/write_file, edit_file: schema description on 'path' nudges the
model to emit this field FIRST in the JSON arguments, so the streaming
preview kicks in early instead of waiting for the large content/
old_string field to finish streaming.
Tests: 12 new unit tests (9 for the helper, 3 for the renderer fallback).
Out of scope: full JSON parse failure, history/transcript region,
sub-agent child branch, and bash/grep/glob tools.
The spinner runs while the agent is actively executing tools, so "Thinking..." misrepresents what's happening. Keep "Processing" and "Working", which describe action. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Member
|
Please update the description of skills in the documentation. |
50faab3 to
7a0cb46
Compare
Bundles four follow-up fixes on top of the original update checker and $-trigger commits: - i18n: rebase took --theirs on .po files for the update-checker commit, dropping the 10 Windows-compat / A2A translations that PR #28 had added on main. Backfill them per-locale from origin/main. - skills: discovery._find_git_root spawned subprocess.run(["git", "rev-parse", "--show-toplevel"], timeout=2.0) inside discover_all_skills, which is reached inline from ACP/A2A async handlers via create_agent_runtime — exactly the path that an earlier commit had to rewrite for project_paths._read_git_head because git-for-windows leaves grandchild processes holding the captured stdout/stderr pipes; after timeout fires, subprocess.run's second communicate() blocks forever and freezes the event loop. Extract find_git_worktree_root() in project_paths (pure filesystem walk, handles linked-worktree/submodule .git files) and have both _read_git_head and discovery use it. Regression tests assert no subprocess on either path. - docs(cli): document the new $ trigger alongside / in commands.md and skills.md. zh-Hans translated; ja/pt/de/fr/es commands.md translated; skills.md in those 5 locales was already English so just synced. - review: three regressions surfaced by code review on the update checker / streaming preview work: * edit_file streaming preview briefly rendered Create operations as "Update" until the full input arrived — return a neutral "Edit" when old_string is absent (translated per locale). * _handle_startup_update's SystemExit(0) on Update-now bypassed run()'s finally graceful_shutdown(); flush telemetry explicitly before exiting. * Select prompt blocked forever on non-TTY stdin (CI shells, container wrappers); short-circuit at the top via sys.stdin.isatty(); existing tests get an autouse fixture that forces isatty=True since pytest captures stdin by default. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
4b3010e to
0b4e7f6
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Bundles the new interactive update checker with a batch of REPL UX polish,
telemetry/cloud fixes, and a banner version line.
Interactive update checker (new)
iac_code.services.update_checker: cross-process state at~/.iac-code/update-state.ymlwith atomic write +fcntladvisory lock,2h success-throttle, PEP 440 version compare, source priority
(official PyPI > configured pip).
update_now(runs upgrade then exits),skip_until_next(suppresses until a newer version appears),skip(default).startup has fresh state.
render_update_prompt_header/render_update_noticereuse the banner'sGroup/Panel style.
REPL UX
$trigger lists/invokes skills only (the/trigger still mixesbuilt-ins and skills); typing
$<built-in>errors clearly pointing at the/equivalent.(
● Read(src/foo.py)) instead of waiting for full JSON parse — newextract_partial_string_fields()helper + opt-inTool.streaming_preview_fields()hook (Read/Write/Edit opt in).iac-code v<version>in the dim metadata block.Telemetry & cloud integrations
__release_date__is empty(unpackaged local source), gating both ARMS exporters and any
user-configured OTLP endpoint.
iac-code/<version>+<release_date|dev> (<os>; <arch>; Python/<py>)User-Agent, plumbed centrally in
tools/cloud/aliyun/user_agent.pyandwired through every
Configbranch inaliyun_apiandros_client.Skill discovery fix
or user-global skills of the same name; project-local scan now walks from
git root toward cwd (
skills/then.iac-code/skills/at each level).Test plan
make lintcleanmake test(full suite) greeniac-code v0.3.0line in welcome banner~/.iac-code/update-state.ymlwith a pending entry,confirm interactive prompt appears with
skipas defaultupdate_now, verify pip runs and process exits 0skip_until_next, restart, confirm prompt is suppresseduntil a newer version appears
/helpworks;$helperrors with hint;$<unknown>errors● Read(<path>)appearsduring streaming (before the full JSON arrives)
User-Agent: iac-code/...reaches the server-side log🤖 Generated with Claude Code