agentharnesses-cli 0.1.0__tar.gz → 0.1.2__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.
- {agentharnesses_cli-0.1.0 → agentharnesses_cli-0.1.2}/.github/workflows/pypi.yaml +6 -3
- agentharnesses_cli-0.1.2/PKG-INFO +80 -0
- agentharnesses_cli-0.1.2/README.md +69 -0
- {agentharnesses_cli-0.1.0 → agentharnesses_cli-0.1.2}/pyproject.toml +5 -2
- {agentharnesses_cli-0.1.0 → agentharnesses_cli-0.1.2}/src/ahar/commands/init.py +87 -24
- agentharnesses_cli-0.1.0/PKG-INFO +0 -62
- agentharnesses_cli-0.1.0/README.md +0 -51
- {agentharnesses_cli-0.1.0 → agentharnesses_cli-0.1.2}/.gitignore +0 -0
- {agentharnesses_cli-0.1.0 → agentharnesses_cli-0.1.2}/src/ahar/__init__.py +0 -0
- {agentharnesses_cli-0.1.0 → agentharnesses_cli-0.1.2}/src/ahar/commands/__init__.py +0 -0
- {agentharnesses_cli-0.1.0 → agentharnesses_cli-0.1.2}/src/ahar/main.py +0 -0
|
@@ -1,21 +1,24 @@
|
|
|
1
1
|
name: Publish to PyPI
|
|
2
2
|
|
|
3
3
|
on:
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- 'v*'
|
|
6
7
|
|
|
7
8
|
jobs:
|
|
8
9
|
build:
|
|
9
10
|
runs-on: ubuntu-latest
|
|
10
11
|
steps:
|
|
11
12
|
- uses: actions/checkout@v4
|
|
13
|
+
with:
|
|
14
|
+
fetch-depth: 0
|
|
12
15
|
|
|
13
16
|
- uses: actions/setup-python@v5
|
|
14
17
|
with:
|
|
15
18
|
python-version: "3.11"
|
|
16
19
|
|
|
17
20
|
- name: Install hatch
|
|
18
|
-
run: pip install hatch
|
|
21
|
+
run: pip install hatch hatch-vcs
|
|
19
22
|
|
|
20
23
|
- name: Build
|
|
21
24
|
run: hatch build
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: agentharnesses-cli
|
|
3
|
+
Version: 0.1.2
|
|
4
|
+
Summary: CLI tools for agentharnesses.io
|
|
5
|
+
Project-URL: Homepage, https://agentharnesses.io
|
|
6
|
+
Project-URL: Repository, https://github.com/agentharnesses/cli
|
|
7
|
+
License-Expression: Apache-2.0
|
|
8
|
+
Requires-Python: >=3.10
|
|
9
|
+
Requires-Dist: click>=8.1
|
|
10
|
+
Description-Content-Type: text/markdown
|
|
11
|
+
|
|
12
|
+
# agentharnesses-cli
|
|
13
|
+
|
|
14
|
+
CLI for [agentharnesses.io](https://agentharnesses.io) — scaffold and manage Agent Harnesses.
|
|
15
|
+
|
|
16
|
+
## Installation
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
pip install agentharnesses-cli
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Usage
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
ahar --help
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
### `ahar init`
|
|
29
|
+
|
|
30
|
+
Initialize a new harness in the current directory:
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
ahar init
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
Optionally specify a name (defaults to the directory name):
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
ahar init my-harness
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
Scaffolds the following structure:
|
|
43
|
+
|
|
44
|
+
```
|
|
45
|
+
my-harness/
|
|
46
|
+
├── HARNESS.md # entry point and agent identity
|
|
47
|
+
├── README.md # human-facing description
|
|
48
|
+
├── .gitignore
|
|
49
|
+
├── .claude/settings.json # registers the harness as a Claude Code plugin
|
|
50
|
+
├── skills/
|
|
51
|
+
│ └── SKILLS.md # skill index
|
|
52
|
+
└── references/
|
|
53
|
+
└── REFERENCES.md # reference index
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
When using the `claude` preset (default), also installs:
|
|
57
|
+
|
|
58
|
+
```
|
|
59
|
+
├── .claude/skills/agent-harnesses/ # metaskill for progressive harness exploration
|
|
60
|
+
└── skills/
|
|
61
|
+
└── maintenance/
|
|
62
|
+
├── SKILLS.md
|
|
63
|
+
└── modify-harness/
|
|
64
|
+
└── SKILL.md
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## Publishing
|
|
68
|
+
|
|
69
|
+
Releases are published to PyPI automatically when a version tag is pushed:
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
git tag v1.0.0
|
|
73
|
+
git push origin v1.0.0
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
The GitHub Actions workflow builds the package and publishes it via trusted publishing (no API token required). The version is derived from the tag via `hatch-vcs`.
|
|
77
|
+
|
|
78
|
+
## License
|
|
79
|
+
|
|
80
|
+
Apache 2.0
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# agentharnesses-cli
|
|
2
|
+
|
|
3
|
+
CLI for [agentharnesses.io](https://agentharnesses.io) — scaffold and manage Agent Harnesses.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pip install agentharnesses-cli
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Usage
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
ahar --help
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
### `ahar init`
|
|
18
|
+
|
|
19
|
+
Initialize a new harness in the current directory:
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
ahar init
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Optionally specify a name (defaults to the directory name):
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
ahar init my-harness
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Scaffolds the following structure:
|
|
32
|
+
|
|
33
|
+
```
|
|
34
|
+
my-harness/
|
|
35
|
+
├── HARNESS.md # entry point and agent identity
|
|
36
|
+
├── README.md # human-facing description
|
|
37
|
+
├── .gitignore
|
|
38
|
+
├── .claude/settings.json # registers the harness as a Claude Code plugin
|
|
39
|
+
├── skills/
|
|
40
|
+
│ └── SKILLS.md # skill index
|
|
41
|
+
└── references/
|
|
42
|
+
└── REFERENCES.md # reference index
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
When using the `claude` preset (default), also installs:
|
|
46
|
+
|
|
47
|
+
```
|
|
48
|
+
├── .claude/skills/agent-harnesses/ # metaskill for progressive harness exploration
|
|
49
|
+
└── skills/
|
|
50
|
+
└── maintenance/
|
|
51
|
+
├── SKILLS.md
|
|
52
|
+
└── modify-harness/
|
|
53
|
+
└── SKILL.md
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## Publishing
|
|
57
|
+
|
|
58
|
+
Releases are published to PyPI automatically when a version tag is pushed:
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
git tag v1.0.0
|
|
62
|
+
git push origin v1.0.0
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
The GitHub Actions workflow builds the package and publishes it via trusted publishing (no API token required). The version is derived from the tag via `hatch-vcs`.
|
|
66
|
+
|
|
67
|
+
## License
|
|
68
|
+
|
|
69
|
+
Apache 2.0
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "agentharnesses-cli"
|
|
3
|
-
|
|
3
|
+
dynamic = ["version"]
|
|
4
4
|
description = "CLI tools for agentharnesses.io"
|
|
5
5
|
license = "Apache-2.0"
|
|
6
6
|
readme = "README.md"
|
|
@@ -17,8 +17,11 @@ Repository = "https://github.com/agentharnesses/cli"
|
|
|
17
17
|
ahar = "ahar.main:cli"
|
|
18
18
|
|
|
19
19
|
[build-system]
|
|
20
|
-
requires = ["hatchling"]
|
|
20
|
+
requires = ["hatchling", "hatch-vcs"]
|
|
21
21
|
build-backend = "hatchling.build"
|
|
22
22
|
|
|
23
|
+
[tool.hatch.version]
|
|
24
|
+
source = "vcs"
|
|
25
|
+
|
|
23
26
|
[tool.hatch.build.targets.wheel]
|
|
24
27
|
packages = ["src/ahar"]
|
|
@@ -1,21 +1,33 @@
|
|
|
1
1
|
import os
|
|
2
|
+
import shutil
|
|
2
3
|
import subprocess
|
|
3
4
|
import sys
|
|
5
|
+
import tempfile
|
|
4
6
|
import click
|
|
5
7
|
|
|
6
|
-
_METASKILL_REPO = "https://github.com/agentharnesses/metaskill"
|
|
7
|
-
_METASKILL_DEST = ".claude/
|
|
8
|
-
|
|
8
|
+
_METASKILL_REPO = "https://github.com/agentharnesses/metaskill"
|
|
9
|
+
_METASKILL_DEST = ".claude/skills/agent-harnesses"
|
|
10
|
+
|
|
11
|
+
_MAINTAIN_SKILL_DEST = "skills/maintenance/modify-harness/SKILL.md"
|
|
12
|
+
_MAINTAIN_SKILLS_INDEX_DEST = "skills/maintenance/SKILLS.md"
|
|
9
13
|
|
|
10
14
|
_MAINTAIN_SKILL = """\
|
|
11
15
|
---
|
|
12
|
-
name:
|
|
13
|
-
description:
|
|
16
|
+
name: modify-harness
|
|
17
|
+
description: Use when asked to maintain, update, or extend this harness — updating HARNESS.md, adding skills and references, managing the skill index.
|
|
14
18
|
---
|
|
15
19
|
|
|
16
20
|
## Maintaining the Harness
|
|
17
21
|
|
|
18
|
-
When asked to maintain, update, or extend this harness, follow these conventions
|
|
22
|
+
When asked to maintain, update, or extend this harness, follow these conventions.
|
|
23
|
+
|
|
24
|
+
When **maintaining the harness** (adding, moving, or renaming files), use `reverse_disclose.py` to find every `.md` file above the target that links to it — so you can update all references that would break:
|
|
25
|
+
|
|
26
|
+
```
|
|
27
|
+
python3 .claude/skills/agent-harnesses/scripts/reverse_disclose.py <target_path>
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
Run this before and after any structural change. The output lists each ancestor `.md` file that references the target, with line numbers and link text, so nothing is left pointing to a stale path.
|
|
19
31
|
|
|
20
32
|
### HARNESS.md
|
|
21
33
|
- Keep the `## Skills` section in sync with entries in `skills/SKILLS.md`
|
|
@@ -23,9 +35,10 @@ When asked to maintain, update, or extend this harness, follow these conventions
|
|
|
23
35
|
- Update the `description` frontmatter field when the harness scope changes
|
|
24
36
|
|
|
25
37
|
### Adding a skill bucket
|
|
26
|
-
1. Create `skills/<bucket-name>/<
|
|
27
|
-
2. Add an entry to `skills
|
|
28
|
-
3.
|
|
38
|
+
1. Create `skills/<bucket-name>/<skill-name>/SKILL.md` with a frontmatter `name` and `description`
|
|
39
|
+
2. Add an entry to `skills/<bucket-name>/SKILLS.md` summarizing when to use the skill
|
|
40
|
+
3. Ensure `skills/SKILLS.md` references the bucket
|
|
41
|
+
4. Add a bullet to the `## Skills` section in `HARNESS.md`
|
|
29
42
|
|
|
30
43
|
### Adding a reference document
|
|
31
44
|
1. Add the document to `references/`
|
|
@@ -38,6 +51,14 @@ When asked to maintain, update, or extend this harness, follow these conventions
|
|
|
38
51
|
- Prefer updating existing skill buckets over creating new ones when scope overlaps
|
|
39
52
|
"""
|
|
40
53
|
|
|
54
|
+
_MAINTAIN_SKILLS_INDEX = """\
|
|
55
|
+
---
|
|
56
|
+
description: Harness upkeep skills — for modifying the harness structure, adding skills and references.
|
|
57
|
+
---
|
|
58
|
+
|
|
59
|
+
- [modify-harness](modify-harness/SKILL.md) — Use when maintaining or extending this harness
|
|
60
|
+
"""
|
|
61
|
+
|
|
41
62
|
|
|
42
63
|
def _write(path, content):
|
|
43
64
|
os.makedirs(os.path.dirname(path), exist_ok=True)
|
|
@@ -58,6 +79,20 @@ description: TODO: describe what this harness does and the role it gives Claude.
|
|
|
58
79
|
|
|
59
80
|
TODO: write the entry message Claude should internalize when this harness loads.
|
|
60
81
|
|
|
82
|
+
## How to Find Information for Claude
|
|
83
|
+
|
|
84
|
+
Use the `agent-harnesses` skill to explore the harness, just in time, based on prompts from the user. Run `disclose.py` with `python3` against this harness directory to progressively explore its contents — select only what is relevant and repeat until the session is complete, then read the returned resources.
|
|
85
|
+
|
|
86
|
+
Do not load skills or references speculatively. Use `disclose.py` to find resources when necessary. Any time you need to find anything in the harness, and you don't already know where it exists, use `disclose.py`.
|
|
87
|
+
|
|
88
|
+
When **maintaining the harness** (adding, moving, or renaming files), use `reverse_disclose.py` to find every `.md` file above the target that links to it — so you can update all references that would break:
|
|
89
|
+
|
|
90
|
+
```
|
|
91
|
+
python3 .claude/skills/agent-harnesses/scripts/reverse_disclose.py <target_path>
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
Run this before and after any structural change. The output lists each ancestor `.md` file that references the target, with line numbers and link text, so nothing is left pointing to a stale path.
|
|
95
|
+
|
|
61
96
|
## Skills
|
|
62
97
|
|
|
63
98
|
TODO: list skill buckets here as they are created.
|
|
@@ -79,6 +114,21 @@ TODO: brief description of this harness.
|
|
|
79
114
|
""",
|
|
80
115
|
)
|
|
81
116
|
|
|
117
|
+
_write(
|
|
118
|
+
f"{root}/.gitignore",
|
|
119
|
+
"""\
|
|
120
|
+
# Claude settings contain absolute paths — keep local
|
|
121
|
+
.claude/settings.json
|
|
122
|
+
.claude/settings.local.json
|
|
123
|
+
|
|
124
|
+
# Metaskill session state
|
|
125
|
+
.claude/skills/agent-harnesses/sessions/
|
|
126
|
+
|
|
127
|
+
# Mac
|
|
128
|
+
.DS_Store
|
|
129
|
+
""",
|
|
130
|
+
)
|
|
131
|
+
|
|
82
132
|
_write(
|
|
83
133
|
f"{root}/.claude/settings.json",
|
|
84
134
|
f"""\
|
|
@@ -145,6 +195,7 @@ def init(name):
|
|
|
145
195
|
click.echo(f"Initialized harness '{name}' in {cwd}")
|
|
146
196
|
click.echo(" HARNESS.md")
|
|
147
197
|
click.echo(" README.md")
|
|
198
|
+
click.echo(" .gitignore")
|
|
148
199
|
click.echo(" .claude/settings.json")
|
|
149
200
|
click.echo(" skills/SKILLS.md")
|
|
150
201
|
click.echo(" references/REFERENCES.md")
|
|
@@ -175,26 +226,38 @@ def _configure_claude(root, preset):
|
|
|
175
226
|
def _install_metaskill(root):
|
|
176
227
|
dest = os.path.join(root, _METASKILL_DEST)
|
|
177
228
|
if os.path.exists(dest):
|
|
178
|
-
click.echo(f"Metaskill already present at {_METASKILL_DEST} — skipping
|
|
229
|
+
click.echo(f"Metaskill already present at {_METASKILL_DEST} — skipping.")
|
|
179
230
|
return
|
|
180
231
|
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
232
|
+
click.echo("Cloning metaskill...")
|
|
233
|
+
with tempfile.TemporaryDirectory() as tmp:
|
|
234
|
+
clone_dir = os.path.join(tmp, "metaskill")
|
|
235
|
+
result = subprocess.run(
|
|
236
|
+
["git", "clone", _METASKILL_REPO, clone_dir],
|
|
237
|
+
capture_output=True,
|
|
238
|
+
text=True,
|
|
239
|
+
)
|
|
240
|
+
if result.returncode != 0:
|
|
241
|
+
click.echo(f"Clone failed:\n{result.stderr.strip()}", err=True)
|
|
242
|
+
sys.exit(1)
|
|
243
|
+
|
|
244
|
+
src = os.path.join(clone_dir, "agent-harnesses")
|
|
245
|
+
os.makedirs(os.path.dirname(dest), exist_ok=True)
|
|
246
|
+
shutil.copytree(src, dest)
|
|
247
|
+
|
|
191
248
|
click.echo(f" {_METASKILL_DEST}")
|
|
192
249
|
|
|
193
250
|
|
|
194
251
|
def _install_maintain_skill(root):
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
252
|
+
skill_dest = os.path.join(root, _MAINTAIN_SKILL_DEST)
|
|
253
|
+
index_dest = os.path.join(root, _MAINTAIN_SKILLS_INDEX_DEST)
|
|
254
|
+
|
|
255
|
+
if os.path.exists(skill_dest):
|
|
256
|
+
click.echo(f"maintain-harness skill already present — skipping.")
|
|
198
257
|
return
|
|
199
|
-
|
|
258
|
+
|
|
259
|
+
_write(index_dest, _MAINTAIN_SKILLS_INDEX)
|
|
260
|
+
click.echo(f" {_MAINTAIN_SKILLS_INDEX_DEST}")
|
|
261
|
+
|
|
262
|
+
_write(skill_dest, _MAINTAIN_SKILL)
|
|
200
263
|
click.echo(f" {_MAINTAIN_SKILL_DEST}")
|
|
@@ -1,62 +0,0 @@
|
|
|
1
|
-
Metadata-Version: 2.4
|
|
2
|
-
Name: agentharnesses-cli
|
|
3
|
-
Version: 0.1.0
|
|
4
|
-
Summary: CLI tools for agentharnesses.io
|
|
5
|
-
Project-URL: Homepage, https://agentharnesses.io
|
|
6
|
-
Project-URL: Repository, https://github.com/agentharnesses/cli
|
|
7
|
-
License-Expression: Apache-2.0
|
|
8
|
-
Requires-Python: >=3.10
|
|
9
|
-
Requires-Dist: click>=8.1
|
|
10
|
-
Description-Content-Type: text/markdown
|
|
11
|
-
|
|
12
|
-
# agentharnesses-cli
|
|
13
|
-
|
|
14
|
-
Command line tools for [agentharnesses.io](http://agentharnesses.io).
|
|
15
|
-
|
|
16
|
-
## Installation
|
|
17
|
-
|
|
18
|
-
### From PyPI (once published)
|
|
19
|
-
|
|
20
|
-
```bash
|
|
21
|
-
pip install agentharnesses-cli
|
|
22
|
-
```
|
|
23
|
-
|
|
24
|
-
### From source
|
|
25
|
-
|
|
26
|
-
```bash
|
|
27
|
-
git clone https://github.com/your-org/cli.git
|
|
28
|
-
cd cli
|
|
29
|
-
pip install .
|
|
30
|
-
```
|
|
31
|
-
|
|
32
|
-
### Development install
|
|
33
|
-
|
|
34
|
-
```bash
|
|
35
|
-
git clone https://github.com/your-org/cli.git
|
|
36
|
-
cd cli
|
|
37
|
-
pip install -e .
|
|
38
|
-
```
|
|
39
|
-
|
|
40
|
-
The `-e` flag installs in editable mode so changes to the source are reflected immediately without reinstalling.
|
|
41
|
-
|
|
42
|
-
## Usage
|
|
43
|
-
|
|
44
|
-
```bash
|
|
45
|
-
ahar --help
|
|
46
|
-
```
|
|
47
|
-
|
|
48
|
-
### `ahar init`
|
|
49
|
-
|
|
50
|
-
Initialize a new harness in the current directory:
|
|
51
|
-
|
|
52
|
-
```bash
|
|
53
|
-
ahar init
|
|
54
|
-
```
|
|
55
|
-
|
|
56
|
-
Optionally specify a name (defaults to the directory name):
|
|
57
|
-
|
|
58
|
-
```bash
|
|
59
|
-
ahar init my-harness
|
|
60
|
-
```
|
|
61
|
-
|
|
62
|
-
This creates a `harness.yaml` file in the current directory.
|
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
# agentharnesses-cli
|
|
2
|
-
|
|
3
|
-
Command line tools for [agentharnesses.io](http://agentharnesses.io).
|
|
4
|
-
|
|
5
|
-
## Installation
|
|
6
|
-
|
|
7
|
-
### From PyPI (once published)
|
|
8
|
-
|
|
9
|
-
```bash
|
|
10
|
-
pip install agentharnesses-cli
|
|
11
|
-
```
|
|
12
|
-
|
|
13
|
-
### From source
|
|
14
|
-
|
|
15
|
-
```bash
|
|
16
|
-
git clone https://github.com/your-org/cli.git
|
|
17
|
-
cd cli
|
|
18
|
-
pip install .
|
|
19
|
-
```
|
|
20
|
-
|
|
21
|
-
### Development install
|
|
22
|
-
|
|
23
|
-
```bash
|
|
24
|
-
git clone https://github.com/your-org/cli.git
|
|
25
|
-
cd cli
|
|
26
|
-
pip install -e .
|
|
27
|
-
```
|
|
28
|
-
|
|
29
|
-
The `-e` flag installs in editable mode so changes to the source are reflected immediately without reinstalling.
|
|
30
|
-
|
|
31
|
-
## Usage
|
|
32
|
-
|
|
33
|
-
```bash
|
|
34
|
-
ahar --help
|
|
35
|
-
```
|
|
36
|
-
|
|
37
|
-
### `ahar init`
|
|
38
|
-
|
|
39
|
-
Initialize a new harness in the current directory:
|
|
40
|
-
|
|
41
|
-
```bash
|
|
42
|
-
ahar init
|
|
43
|
-
```
|
|
44
|
-
|
|
45
|
-
Optionally specify a name (defaults to the directory name):
|
|
46
|
-
|
|
47
|
-
```bash
|
|
48
|
-
ahar init my-harness
|
|
49
|
-
```
|
|
50
|
-
|
|
51
|
-
This creates a `harness.yaml` file in the current directory.
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|