nanocode-cli 0.1.0__tar.gz → 0.2.1__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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: nanocode-cli
3
- Version: 0.1.0
3
+ Version: 0.2.1
4
4
  Summary: A lightweight terminal-based AI coding assistant
5
5
  Author-email: hit9 <hit9@icloud.com>
6
6
  License-Expression: BSD-3-Clause
@@ -30,12 +30,15 @@ Dynamic: license-file
30
30
 
31
31
  # nanocode
32
32
 
33
+ A lightweight terminal-based AI coding assistant.
34
+
35
+ nanocode is used to help building itself, including features such as `@file` path completion.
33
36
 
34
37
  ## Screenshots
35
38
 
36
39
  | | |
37
40
  |---|---|
38
- | ![Screenshot 1](https://raw.githubusercontent.com/hit9/nanocode/main/snapshots/nanocode-snapshot1.png) | ![Screenshot 2](https://raw.githubusercontent.com/hit9/nanocode/main/snapshots/nanocode-snapshot2.png) |
41
+ | ![Screenshot 1](https://raw.githubusercontent.com/hit9/nanocode/master/snapshots/nanocode-snapshot1.png) | ![Screenshot 2](https://raw.githubusercontent.com/hit9/nanocode/master/snapshots/nanocode-snapshot2.png) |
39
42
 
40
43
  ## Install
41
44
 
@@ -43,6 +46,12 @@ Dynamic: license-file
43
46
  uv tool install nanocode-cli
44
47
  ```
45
48
 
49
+ Upgrade an existing install:
50
+
51
+ ```sh
52
+ uv tool upgrade nanocode-cli
53
+ ```
54
+
46
55
  For local development:
47
56
 
48
57
  ```sh
@@ -55,7 +64,7 @@ uv run nanocode
55
64
  Required:
56
65
 
57
66
  ```sh
58
- export NANOCODE_API_URL="https://api.example.com/v1/chat/completions"
67
+ export NANOCODE_API_URL="https://api.example.com/v1"
59
68
  export NANOCODE_API_KEY="your-api-key"
60
69
  export NANOCODE_MODEL="your-model"
61
70
  ```
@@ -72,6 +81,26 @@ export NANOCODE_SHELL_TIMEOUT="60"
72
81
  export NANOCODE_COMPACT_AT="100"
73
82
  ```
74
83
 
84
+ ## Usage
85
+
86
+ Start nanocode:
87
+
88
+ ```sh
89
+ nanocode
90
+ ```
91
+
92
+ Show available commands:
93
+
94
+ ```text
95
+ /help
96
+ ```
97
+
98
+ Ask a source-aware question about nanocode itself:
99
+
100
+ ```text
101
+ /help how does compact work?
102
+ ```
103
+
75
104
  ## Safety
76
105
 
77
106
  nanocode does not provide sandbox protection. It can run shell commands and edit files in the environment where you start it.
@@ -1,11 +1,14 @@
1
1
  # nanocode
2
2
 
3
+ A lightweight terminal-based AI coding assistant.
4
+
5
+ nanocode is used to help building itself, including features such as `@file` path completion.
3
6
 
4
7
  ## Screenshots
5
8
 
6
9
  | | |
7
10
  |---|---|
8
- | ![Screenshot 1](https://raw.githubusercontent.com/hit9/nanocode/main/snapshots/nanocode-snapshot1.png) | ![Screenshot 2](https://raw.githubusercontent.com/hit9/nanocode/main/snapshots/nanocode-snapshot2.png) |
11
+ | ![Screenshot 1](https://raw.githubusercontent.com/hit9/nanocode/master/snapshots/nanocode-snapshot1.png) | ![Screenshot 2](https://raw.githubusercontent.com/hit9/nanocode/master/snapshots/nanocode-snapshot2.png) |
9
12
 
10
13
  ## Install
11
14
 
@@ -13,6 +16,12 @@
13
16
  uv tool install nanocode-cli
14
17
  ```
15
18
 
19
+ Upgrade an existing install:
20
+
21
+ ```sh
22
+ uv tool upgrade nanocode-cli
23
+ ```
24
+
16
25
  For local development:
17
26
 
18
27
  ```sh
@@ -25,7 +34,7 @@ uv run nanocode
25
34
  Required:
26
35
 
27
36
  ```sh
28
- export NANOCODE_API_URL="https://api.example.com/v1/chat/completions"
37
+ export NANOCODE_API_URL="https://api.example.com/v1"
29
38
  export NANOCODE_API_KEY="your-api-key"
30
39
  export NANOCODE_MODEL="your-model"
31
40
  ```
@@ -42,6 +51,26 @@ export NANOCODE_SHELL_TIMEOUT="60"
42
51
  export NANOCODE_COMPACT_AT="100"
43
52
  ```
44
53
 
54
+ ## Usage
55
+
56
+ Start nanocode:
57
+
58
+ ```sh
59
+ nanocode
60
+ ```
61
+
62
+ Show available commands:
63
+
64
+ ```text
65
+ /help
66
+ ```
67
+
68
+ Ask a source-aware question about nanocode itself:
69
+
70
+ ```text
71
+ /help how does compact work?
72
+ ```
73
+
45
74
  ## Safety
46
75
 
47
76
  nanocode does not provide sandbox protection. It can run shell commands and edit files in the environment where you start it.
@@ -32,7 +32,7 @@ from enum import StrEnum
32
32
  from typing import Any, Callable, ClassVar, final, Iterator, Protocol, Self, Type, TypeAlias
33
33
  from typing_extensions import override
34
34
  from prompt_toolkit import PromptSession, print_formatted_text
35
- from prompt_toolkit.completion import WordCompleter
35
+ from prompt_toolkit.completion import Completer, Completion, WordCompleter
36
36
  from prompt_toolkit.formatted_text import FormattedText
37
37
  from prompt_toolkit.history import FileHistory
38
38
  from prompt_toolkit.output.defaults import create_output
@@ -41,7 +41,7 @@ from prompt_toolkit.patch_stdout import patch_stdout
41
41
 
42
42
  JsonValue: TypeAlias = Any
43
43
  Json: TypeAlias = dict[str, JsonValue]
44
- __version__ = "0.1.0"
44
+ __version__ = "0.2.1"
45
45
 
46
46
 
47
47
  class Error(Exception): ...
@@ -56,6 +56,34 @@ class LLMError(Exception): ...
56
56
  class Cancellation(Exception): ...
57
57
 
58
58
 
59
+ class ReferenceFileCompleter(Completer):
60
+ def __init__(self, cwd: str, command_completer: WordCompleter):
61
+ self.cwd = cwd
62
+ self.command_completer = command_completer
63
+
64
+ def get_completions(self, document, complete_event):
65
+ match = re.search(r"(?:^|\s)@([^\s]*)$", document.text_before_cursor)
66
+ if match is None:
67
+ yield from self.command_completer.get_completions(document, complete_event)
68
+ return
69
+
70
+ partial = match.group(1)
71
+ dirname, prefix = os.path.split(partial)
72
+ base_dir = os.path.abspath(os.path.join(self.cwd, dirname))
73
+ try:
74
+ names = sorted(os.listdir(base_dir))
75
+ except OSError:
76
+ return
77
+
78
+ for name in names:
79
+ if not name.startswith(prefix):
80
+ continue
81
+ full_path = os.path.join(base_dir, name)
82
+ suffix = "/" if os.path.isdir(full_path) else ""
83
+ candidate = os.path.join(dirname, name) + suffix if dirname else name + suffix
84
+ yield Completion(candidate, start_position=-len(partial), display="@" + candidate)
85
+
86
+
59
87
  class PromptItem:
60
88
  @abstractmethod
61
89
  def format(self, indent: str = "") -> str:
@@ -2665,13 +2693,19 @@ class Agent:
2665
2693
  for event, execution in zip(self.tool_runner.latest_events, self.tool_runner.latest_executions):
2666
2694
  if not event.summary:
2667
2695
  continue
2668
- if event.needs_raw_read and not self._has_read_result_file_call(tool_calls, event.result_file):
2696
+ is_reading_result_file = self._has_read_result_file_call(tool_calls, event.result_file)
2697
+ if event.needs_raw_read and not is_reading_result_file:
2669
2698
  needs_read.append(event)
2670
2699
  if event.outcome in {"failure", "partial"}:
2671
- if not event.key_details:
2700
+ if not event.key_details and not is_reading_result_file:
2672
2701
  missing_evidence.append(event)
2673
2702
  continue
2674
- if self._is_large_tool_output(execution.output) and not event.key_details and not event.needs_raw_read:
2703
+ if (
2704
+ self._is_large_tool_output(execution.output)
2705
+ and not event.key_details
2706
+ and not event.needs_raw_read
2707
+ and not is_reading_result_file
2708
+ ):
2675
2709
  missing_evidence.append(event)
2676
2710
  if not missing and not missing_evidence and not needs_read:
2677
2711
  return ""
@@ -2700,12 +2734,13 @@ class Agent:
2700
2734
  def _has_read_result_file_call(self, tool_calls: list[JsonValue], result_file: str) -> bool:
2701
2735
  if not result_file:
2702
2736
  return False
2737
+ expected = self.session.resolve_path(result_file)
2703
2738
  for raw_call in tool_calls:
2704
2739
  call = _json_dict(raw_call)
2705
2740
  if _json_str(call.get("name")) != ReadTool.name():
2706
2741
  continue
2707
2742
  args = [_json_str(arg) or "" for arg in _json_list(call.get("args"))]
2708
- if args and args[0] == result_file:
2743
+ if args and self.session.resolve_path(args[0]) == expected:
2709
2744
  return True
2710
2745
  return False
2711
2746
 
@@ -2806,6 +2841,8 @@ class CommandDispatcher:
2806
2841
  current_category = spec.category
2807
2842
  lines.append(current_category + ":")
2808
2843
  lines.append(" " + spec.display_name() + " - " + spec.description)
2844
+ lines.append("")
2845
+ lines.append("Tip: use @path to autocomplete file paths in prompts.")
2809
2846
  return "\n".join(lines)
2810
2847
 
2811
2848
  def _format_source_help_question(self, question: str) -> str:
@@ -3114,7 +3151,7 @@ class AgentLoop:
3114
3151
  os.makedirs(os.path.dirname(self.history_path), exist_ok=True)
3115
3152
  return PromptSession(
3116
3153
  history=FileHistory(self.history_path),
3117
- completer=self._command_completer(),
3154
+ completer=ReferenceFileCompleter(self.agent.session.cwd, self._command_completer()),
3118
3155
  complete_while_typing=True,
3119
3156
  )
3120
3157
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: nanocode-cli
3
- Version: 0.1.0
3
+ Version: 0.2.1
4
4
  Summary: A lightweight terminal-based AI coding assistant
5
5
  Author-email: hit9 <hit9@icloud.com>
6
6
  License-Expression: BSD-3-Clause
@@ -30,12 +30,15 @@ Dynamic: license-file
30
30
 
31
31
  # nanocode
32
32
 
33
+ A lightweight terminal-based AI coding assistant.
34
+
35
+ nanocode is used to help building itself, including features such as `@file` path completion.
33
36
 
34
37
  ## Screenshots
35
38
 
36
39
  | | |
37
40
  |---|---|
38
- | ![Screenshot 1](https://raw.githubusercontent.com/hit9/nanocode/main/snapshots/nanocode-snapshot1.png) | ![Screenshot 2](https://raw.githubusercontent.com/hit9/nanocode/main/snapshots/nanocode-snapshot2.png) |
41
+ | ![Screenshot 1](https://raw.githubusercontent.com/hit9/nanocode/master/snapshots/nanocode-snapshot1.png) | ![Screenshot 2](https://raw.githubusercontent.com/hit9/nanocode/master/snapshots/nanocode-snapshot2.png) |
39
42
 
40
43
  ## Install
41
44
 
@@ -43,6 +46,12 @@ Dynamic: license-file
43
46
  uv tool install nanocode-cli
44
47
  ```
45
48
 
49
+ Upgrade an existing install:
50
+
51
+ ```sh
52
+ uv tool upgrade nanocode-cli
53
+ ```
54
+
46
55
  For local development:
47
56
 
48
57
  ```sh
@@ -55,7 +64,7 @@ uv run nanocode
55
64
  Required:
56
65
 
57
66
  ```sh
58
- export NANOCODE_API_URL="https://api.example.com/v1/chat/completions"
67
+ export NANOCODE_API_URL="https://api.example.com/v1"
59
68
  export NANOCODE_API_KEY="your-api-key"
60
69
  export NANOCODE_MODEL="your-model"
61
70
  ```
@@ -72,6 +81,26 @@ export NANOCODE_SHELL_TIMEOUT="60"
72
81
  export NANOCODE_COMPACT_AT="100"
73
82
  ```
74
83
 
84
+ ## Usage
85
+
86
+ Start nanocode:
87
+
88
+ ```sh
89
+ nanocode
90
+ ```
91
+
92
+ Show available commands:
93
+
94
+ ```text
95
+ /help
96
+ ```
97
+
98
+ Ask a source-aware question about nanocode itself:
99
+
100
+ ```text
101
+ /help how does compact work?
102
+ ```
103
+
75
104
  ## Safety
76
105
 
77
106
  nanocode does not provide sandbox protection. It can run shell commands and edit files in the environment where you start it.
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "nanocode-cli"
7
- version = "0.1.0"
7
+ version = "0.2.1"
8
8
  description = "A lightweight terminal-based AI coding assistant"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.11"
File without changes
File without changes
File without changes