deepwork 0.4.0__py3-none-any.whl → 0.5.1__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.
- deepwork/core/adapters.py +4 -0
- deepwork/templates/claude/AGENTS.md +38 -0
- deepwork/templates/claude/skill-job-step.md.jinja +73 -89
- {deepwork-0.4.0.dist-info → deepwork-0.5.1.dist-info}/METADATA +1 -1
- {deepwork-0.4.0.dist-info → deepwork-0.5.1.dist-info}/RECORD +8 -7
- {deepwork-0.4.0.dist-info → deepwork-0.5.1.dist-info}/WHEEL +0 -0
- {deepwork-0.4.0.dist-info → deepwork-0.5.1.dist-info}/entry_points.txt +0 -0
- {deepwork-0.4.0.dist-info → deepwork-0.5.1.dist-info}/licenses/LICENSE.md +0 -0
deepwork/core/adapters.py
CHANGED
|
@@ -469,7 +469,11 @@ class ClaudeAdapter(AgentAdapter):
|
|
|
469
469
|
"Write(./.deepwork/**)",
|
|
470
470
|
# All deepwork CLI commands
|
|
471
471
|
"Bash(deepwork:*)",
|
|
472
|
+
# Job scripts that need to be executable
|
|
473
|
+
"Bash(./.deepwork/jobs/deepwork_jobs/make_new_job.sh:*)",
|
|
472
474
|
]
|
|
475
|
+
# NOTE: When modifying required_permissions, update the test assertion in
|
|
476
|
+
# tests/unit/test_adapters.py::TestClaudeAdapter::test_sync_permissions_idempotent
|
|
473
477
|
|
|
474
478
|
# Load settings once, add all permissions, then save once
|
|
475
479
|
settings = self._load_settings(project_path)
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# Claude Templates - Agent Notes
|
|
2
|
+
|
|
3
|
+
Notes for AI agents working on Claude Code jinja templates.
|
|
4
|
+
|
|
5
|
+
## Prompt-Based Stop Hooks - NOT WORKING
|
|
6
|
+
|
|
7
|
+
**IMPORTANT: Prompt-based stop hooks (`type: prompt` for Stop/SubagentStop events) do not currently work properly in Claude Code.**
|
|
8
|
+
|
|
9
|
+
Reference: https://github.com/anthropics/claude-code/issues/20221
|
|
10
|
+
|
|
11
|
+
### What This Means
|
|
12
|
+
|
|
13
|
+
- Do NOT use `type: prompt` hooks for Stop or SubagentStop events in templates
|
|
14
|
+
- The quality validation loop pattern that relies on prompt hooks will not function as expected
|
|
15
|
+
- Instead, instruct agents to use a sub-agent (e.g., Haiku) to review their work against quality criteria
|
|
16
|
+
|
|
17
|
+
### Workaround
|
|
18
|
+
|
|
19
|
+
Instead of prompt-based stop hooks, templates should include explicit instructions in the command content directing the agent to:
|
|
20
|
+
|
|
21
|
+
1. Have a sub-agent using Haiku review the work against the specified quality criteria
|
|
22
|
+
2. Fix any valid issues raised by the sub-agent
|
|
23
|
+
3. Have the sub-agent review again until all valid feedback is handled
|
|
24
|
+
|
|
25
|
+
### Future Reversal
|
|
26
|
+
|
|
27
|
+
If prompt-based stop hooks are fixed in Claude Code (check the issue above for updates), this guidance should be reversed and prompt hooks can be re-enabled in templates.
|
|
28
|
+
|
|
29
|
+
## Historical Context (Prompt Hooks - When They Work)
|
|
30
|
+
|
|
31
|
+
The following guidance applies IF prompt hooks start working again:
|
|
32
|
+
|
|
33
|
+
When writing prompt-based hooks (e.g., Stop hooks with `type: prompt`):
|
|
34
|
+
|
|
35
|
+
- **Do NOT include instructions on how to return responses** (e.g., "respond with JSON", "return `{"ok": true}`"). Claude Code's internal instructions already specify the expected response format for prompt hooks.
|
|
36
|
+
- Adding redundant response format instructions can cause conflicts or confusion with the built-in behavior. i.e. the hook will not block the agent from stopping.
|
|
37
|
+
|
|
38
|
+
Reference: https://github.com/anthropics/claude-code/issues/11786
|
|
@@ -40,72 +40,51 @@ Template Variables:
|
|
|
40
40
|
---
|
|
41
41
|
name: {{ job_name }}.{{ step_id }}
|
|
42
42
|
description: "{{ step_description }}"
|
|
43
|
-
{
|
|
43
|
+
{%- if not exposed %}
|
|
44
44
|
user-invocable: false
|
|
45
|
-
{
|
|
46
|
-
{
|
|
45
|
+
{%- endif %}{#- if not exposed #}
|
|
46
|
+
{#-
|
|
47
|
+
NOTE: Prompt-based stop hooks do not currently work in Claude Code.
|
|
48
|
+
See: https://github.com/anthropics/claude-code/issues/20221
|
|
49
|
+
Only command/script hooks are generated here. Prompt hooks are filtered out.
|
|
50
|
+
Quality validation is handled via sub-agent review in the instructions section.
|
|
51
|
+
#}
|
|
52
|
+
{%- if hooks -%}
|
|
53
|
+
{%- set has_command_hooks = namespace(value=false) -%}
|
|
54
|
+
{%- for event_name, event_hooks in hooks.items() -%}
|
|
55
|
+
{%- for hook in event_hooks -%}
|
|
56
|
+
{%- if hook.type == "script" -%}
|
|
57
|
+
{%- set has_command_hooks.value = true -%}
|
|
58
|
+
{%- endif -%}{#- if hook.type == "script" #}
|
|
59
|
+
{%- endfor -%}{#- for hook in event_hooks #}
|
|
60
|
+
{%- endfor -%}{#- for event_name, event_hooks in hooks.items() #}
|
|
61
|
+
{%- if has_command_hooks.value %}
|
|
47
62
|
hooks:
|
|
48
|
-
{
|
|
49
|
-
{
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
You must evaluate whether Claude has met all the below quality criteria for the request.
|
|
55
|
-
|
|
56
|
-
## Quality Criteria
|
|
57
|
-
|
|
58
|
-
{% for criterion in quality_criteria %}
|
|
59
|
-
{{ loop.index }}. {{ criterion }}
|
|
60
|
-
{% endfor %}
|
|
61
|
-
|
|
62
|
-
## Instructions
|
|
63
|
-
|
|
64
|
-
Review the conversation and determine if ALL quality criteria above have been satisfied.
|
|
65
|
-
Look for evidence that each criterion has been addressed.
|
|
66
|
-
|
|
67
|
-
If the agent has included `<promise>✓ Quality Criteria Met</promise>` in their response OR
|
|
68
|
-
all criteria appear to be met, respond with: {"ok": true}
|
|
69
|
-
|
|
70
|
-
If criteria are NOT met AND the promise tag is missing, respond with:
|
|
71
|
-
{"ok": false, "reason": "**AGENT: TAKE ACTION** - [which criteria failed and why]"}
|
|
72
|
-
{% endfor %}
|
|
73
|
-
{% endif %}
|
|
74
|
-
{% for event_name, event_hooks in hooks.items() %}
|
|
75
|
-
{% if not (event_name == "Stop" and quality_criteria) and not (event_name == "SubagentStop" and "Stop" in hooks) %}
|
|
76
|
-
{# For Stop events, generate both Stop and SubagentStop blocks #}
|
|
77
|
-
{% if event_name == "Stop" %}
|
|
78
|
-
{% for stop_event in ["Stop", "SubagentStop"] %}
|
|
63
|
+
{%- for event_name, event_hooks in hooks.items() %}
|
|
64
|
+
{%- set script_hooks = event_hooks | selectattr("type", "equalto", "script") | list %}
|
|
65
|
+
{%- if script_hooks -%}
|
|
66
|
+
{#- For Stop events, generate both Stop and SubagentStop blocks #}
|
|
67
|
+
{%- if event_name == "Stop" %}
|
|
68
|
+
{%- for stop_event in ["Stop", "SubagentStop"] %}
|
|
79
69
|
{{ stop_event }}:
|
|
80
70
|
- hooks:
|
|
81
|
-
{
|
|
82
|
-
{% if hook.type == "script" %}
|
|
71
|
+
{%- for hook in script_hooks %}
|
|
83
72
|
- type: command
|
|
84
73
|
command: ".deepwork/jobs/{{ job_name }}/{{ hook.path }}"
|
|
85
|
-
{
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
{{ hook.content | indent(12) }}
|
|
89
|
-
{% endif %}
|
|
90
|
-
{% endfor %}
|
|
91
|
-
{% endfor %}
|
|
92
|
-
{% else %}
|
|
74
|
+
{%- endfor %}{#- for hook in script_hooks #}
|
|
75
|
+
{%- endfor %}{#- for stop_event in ["Stop", "SubagentStop"] #}
|
|
76
|
+
{%- elif event_name != "SubagentStop" or "Stop" not in hooks %}
|
|
93
77
|
{{ event_name }}:
|
|
94
78
|
- hooks:
|
|
95
|
-
{
|
|
96
|
-
{% if hook.type == "script" %}
|
|
79
|
+
{%- for hook in script_hooks %}
|
|
97
80
|
- type: command
|
|
98
81
|
command: ".deepwork/jobs/{{ job_name }}/{{ hook.path }}"
|
|
99
|
-
{
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
{
|
|
104
|
-
{
|
|
105
|
-
{% endif %}
|
|
106
|
-
{% endif %}
|
|
107
|
-
{% endfor %}
|
|
108
|
-
{% endif %}
|
|
82
|
+
{%- endfor %}{#- for hook in script_hooks #}
|
|
83
|
+
{%- endif %}{#- if event_name == "Stop" #}
|
|
84
|
+
{%- endif %}{#- if script_hooks #}
|
|
85
|
+
{%- endfor %}{#- for event_name, event_hooks in hooks.items() #}
|
|
86
|
+
{%- endif %}{#- if has_command_hooks.value #}
|
|
87
|
+
{%- endif %}{#- if hooks #}
|
|
109
88
|
---
|
|
110
89
|
|
|
111
90
|
# {{ job_name }}.{{ step_id }}
|
|
@@ -114,7 +93,7 @@ hooks:
|
|
|
114
93
|
**Standalone skill** - can be run anytime
|
|
115
94
|
{% else %}
|
|
116
95
|
**Step {{ step_number }}/{{ total_steps }}** in **{{ job_name }}** workflow
|
|
117
|
-
{% endif %}
|
|
96
|
+
{% endif %}{#- if is_standalone #}
|
|
118
97
|
|
|
119
98
|
> {{ job_summary }}
|
|
120
99
|
|
|
@@ -124,8 +103,8 @@ hooks:
|
|
|
124
103
|
Before proceeding, confirm these steps are complete:
|
|
125
104
|
{% for dep in dependencies %}
|
|
126
105
|
- `/{{ job_name }}.{{ dep }}`
|
|
127
|
-
{% endfor %}
|
|
128
|
-
{% endif %}
|
|
106
|
+
{% endfor %}{#- for dep in dependencies #}
|
|
107
|
+
{% endif %}{#- if dependencies #}
|
|
129
108
|
|
|
130
109
|
## Instructions
|
|
131
110
|
|
|
@@ -137,7 +116,7 @@ Before proceeding, confirm these steps are complete:
|
|
|
137
116
|
### Job Context
|
|
138
117
|
|
|
139
118
|
{{ job_description }}
|
|
140
|
-
{% endif %}
|
|
119
|
+
{% endif %}{#- if job_description #}
|
|
141
120
|
|
|
142
121
|
{% if user_inputs or file_inputs %}
|
|
143
122
|
## Required Inputs
|
|
@@ -146,16 +125,16 @@ Before proceeding, confirm these steps are complete:
|
|
|
146
125
|
**User Parameters** - Gather from user before starting:
|
|
147
126
|
{% for input in user_inputs %}
|
|
148
127
|
- **{{ input.name }}**: {{ input.description }}
|
|
149
|
-
{% endfor %}
|
|
150
|
-
{% endif %}
|
|
128
|
+
{% endfor %}{#- for input in user_inputs #}
|
|
129
|
+
{% endif %}{#- if user_inputs #}
|
|
151
130
|
|
|
152
131
|
{% if file_inputs %}
|
|
153
132
|
**Files from Previous Steps** - Read these first:
|
|
154
133
|
{% for input in file_inputs %}
|
|
155
134
|
- `{{ input.file }}` (from `{{ input.from_step }}`)
|
|
156
|
-
{% endfor %}
|
|
157
|
-
{% endif %}
|
|
158
|
-
{% endif %}
|
|
135
|
+
{% endfor %}{#- for input in file_inputs #}
|
|
136
|
+
{% endif %}{#- if file_inputs #}
|
|
137
|
+
{% endif %}{#- if user_inputs or file_inputs #}
|
|
159
138
|
|
|
160
139
|
## Work Branch
|
|
161
140
|
|
|
@@ -177,13 +156,13 @@ Use branch format: `deepwork/{{ job_name }}-[instance]-YYYYMMDD`
|
|
|
177
156
|
**Definition**: `{{ output.doc_spec.path }}`
|
|
178
157
|
{% if output.doc_spec.target_audience %}
|
|
179
158
|
**Target Audience**: {{ output.doc_spec.target_audience }}
|
|
180
|
-
{% endif %}
|
|
159
|
+
{% endif %}{#- if output.doc_spec.target_audience #}
|
|
181
160
|
{% if output.doc_spec.quality_criteria %}
|
|
182
161
|
**Quality Criteria**:
|
|
183
162
|
{% for criterion in output.doc_spec.quality_criteria %}
|
|
184
163
|
{{ loop.index }}. **{{ criterion.name }}**: {{ criterion.description }}
|
|
185
|
-
{% endfor %}
|
|
186
|
-
{% endif %}
|
|
164
|
+
{% endfor %}{#- for criterion in output.doc_spec.quality_criteria #}
|
|
165
|
+
{% endif %}{#- if output.doc_spec.quality_criteria #}
|
|
187
166
|
{% if output.doc_spec.example_document %}
|
|
188
167
|
|
|
189
168
|
<details>
|
|
@@ -194,12 +173,12 @@ Use branch format: `deepwork/{{ job_name }}-[instance]-YYYYMMDD`
|
|
|
194
173
|
```
|
|
195
174
|
|
|
196
175
|
</details>
|
|
197
|
-
{% endif %}
|
|
198
|
-
{% endif %}
|
|
199
|
-
{% endfor %}
|
|
176
|
+
{% endif %}{#- if output.doc_spec.example_document #}
|
|
177
|
+
{% endif %}{#- if output.has_doc_spec and output.doc_spec #}
|
|
178
|
+
{% endfor %}{#- for output in outputs #}
|
|
200
179
|
{% else %}
|
|
201
180
|
No specific file outputs required.
|
|
202
|
-
{% endif %}
|
|
181
|
+
{% endif %}{#- if outputs #}
|
|
203
182
|
|
|
204
183
|
## Guardrails
|
|
205
184
|
|
|
@@ -208,27 +187,32 @@ No specific file outputs required.
|
|
|
208
187
|
- Do NOT proceed without required inputs; ask the user if any are missing
|
|
209
188
|
- Do NOT modify files outside the scope of this step's defined outputs
|
|
210
189
|
|
|
211
|
-
{% if quality_criteria
|
|
190
|
+
{% if quality_criteria %}
|
|
212
191
|
## Quality Validation
|
|
213
192
|
|
|
214
|
-
|
|
193
|
+
**Before completing this step, you MUST have your work reviewed against the quality criteria below.**
|
|
194
|
+
|
|
195
|
+
Use a sub-agent (Haiku model) to review your work against these criteria:
|
|
215
196
|
|
|
216
|
-
{% if quality_criteria %}
|
|
217
197
|
**Criteria (all must be satisfied)**:
|
|
218
|
-
{% for criterion in quality_criteria
|
|
198
|
+
{% for criterion in quality_criteria -%}
|
|
219
199
|
{{ loop.index }}. {{ criterion }}
|
|
220
|
-
{% endfor %}
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
200
|
+
{% endfor %}{#- for criterion in quality_criteria #}
|
|
201
|
+
**Review Process**:
|
|
202
|
+
1. Once you believe your work is complete, spawn a sub-agent using Haiku to review your work against the quality criteria above
|
|
203
|
+
2. The sub-agent should examine your outputs and verify each criterion is met
|
|
204
|
+
3. If the sub-agent identifies valid issues, fix them
|
|
205
|
+
4. Have the sub-agent review again until all valid feedback has been addressed
|
|
206
|
+
5. Only mark the step complete when the sub-agent confirms all criteria are satisfied
|
|
207
|
+
|
|
208
|
+
{% endif %}{#- if quality_criteria #}
|
|
209
|
+
{% if stop_hooks -%}
|
|
210
|
+
{% for hook in stop_hooks -%}
|
|
211
|
+
{% if hook.type == "script" -%}
|
|
225
212
|
**Validation script**: `.deepwork/jobs/{{ job_name }}/{{ hook.path }}` (runs automatically)
|
|
226
|
-
{% endif
|
|
227
|
-
{% endfor %}
|
|
228
|
-
|
|
229
|
-
**To complete**: Include `<promise>✓ Quality Criteria Met</promise>` in your final response only after verifying ALL criteria are satisfied.
|
|
230
|
-
|
|
231
|
-
{% endif %}
|
|
213
|
+
{% endif -%}{#- if hook.type == "script" #}
|
|
214
|
+
{% endfor %}{#- for hook in stop_hooks #}
|
|
215
|
+
{% endif %}{#- if stop_hooks #}
|
|
232
216
|
## On Completion
|
|
233
217
|
|
|
234
218
|
{% if is_standalone %}
|
|
@@ -243,8 +227,8 @@ This standalone skill can be re-run anytime.
|
|
|
243
227
|
3. **Continue workflow**: Use Skill tool to invoke `/{{ job_name }}.{{ next_step }}`
|
|
244
228
|
{% else %}
|
|
245
229
|
3. **Workflow complete**: All steps finished. Consider creating a PR to merge the work branch.
|
|
246
|
-
{% endif %}
|
|
247
|
-
{% endif %}
|
|
230
|
+
{% endif %}{#- if next_step #}
|
|
231
|
+
{% endif %}{#- if is_standalone #}
|
|
248
232
|
|
|
249
233
|
---
|
|
250
234
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: deepwork
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.5.1
|
|
4
4
|
Summary: Framework for enabling AI agents to perform complex, multi-step work tasks
|
|
5
5
|
Project-URL: Homepage, https://github.com/deepwork/deepwork
|
|
6
6
|
Project-URL: Documentation, https://github.com/deepwork/deepwork#readme
|
|
@@ -6,7 +6,7 @@ deepwork/cli/main.py,sha256=ohWspMA5yVjOPZDiFWt7yT4aH4o8MiOJfU67fuDkklM,616
|
|
|
6
6
|
deepwork/cli/rules.py,sha256=hLv751CwAAHK1LaggBhfPbTVpPRUBbEON73ldYWijo8,760
|
|
7
7
|
deepwork/cli/sync.py,sha256=BH3kuheDZMfRQOem0D09RzJJYDp0egbAW6Huu_YBS9M,7554
|
|
8
8
|
deepwork/core/__init__.py,sha256=1g869QuwsYzNjQONneng2OMc6HKt-tlBCaxJbMMfoho,36
|
|
9
|
-
deepwork/core/adapters.py,sha256=
|
|
9
|
+
deepwork/core/adapters.py,sha256=kQ6VcXrB4AcQBwMFhw0808h-3LWNbUV6mPTMvkzQwq8,21829
|
|
10
10
|
deepwork/core/command_executor.py,sha256=O3LBdwT0Jshgw6l7I9va0tJbjIYO_wSnC6COz1RynrU,5373
|
|
11
11
|
deepwork/core/detector.py,sha256=PThpFLH-ZVL8UqjVdGSnGA0mFbhc6_rp6V3_Yzw97kI,2466
|
|
12
12
|
deepwork/core/doc_spec_parser.py,sha256=DF1B3Ku9XHxTjRN12b1DatkwTa0HlwpPbeJCL4teobU,5739
|
|
@@ -55,8 +55,9 @@ deepwork/standard_jobs/deepwork_rules/rules/skill-md-validation.md,sha256=H-o8X9
|
|
|
55
55
|
deepwork/standard_jobs/deepwork_rules/rules/source-test-pairing.md.example,sha256=Uwg0l85nB69yY8MWwF46EUwx3UJ3qIHXb2ywxp_VNW0,320
|
|
56
56
|
deepwork/standard_jobs/deepwork_rules/steps/define.md,sha256=TP3j90bh0zsGQniAo2GkX9xbLtB_XkaA4IudcbAZ0YY,8349
|
|
57
57
|
deepwork/templates/__init__.py,sha256=APvjx_u7eRUerw9yA_fJ1ZqCzYA-FWUCV9HCz0RgjOc,50
|
|
58
|
+
deepwork/templates/claude/AGENTS.md,sha256=7ickAhY8fNWhNCXPMG5nm6Jmv-XJvDM0PKC41EiQKyU,1828
|
|
58
59
|
deepwork/templates/claude/skill-job-meta.md.jinja,sha256=SsK-_Tz5eeieaYGg9Q7S-MuaqbG7alWbKA0p2RcxhAg,2363
|
|
59
|
-
deepwork/templates/claude/skill-job-step.md.jinja,sha256=
|
|
60
|
+
deepwork/templates/claude/skill-job-step.md.jinja,sha256=L42OQbD1HCq8idIH5kYIZQY9rwuO3DTRrsfn_6jkLPU,8549
|
|
60
61
|
deepwork/templates/gemini/skill-job-meta.toml.jinja,sha256=FOkRNP3pGbvwcwwt3k6WF_qsCIkj1AbLYtF3mlkqAsA,2157
|
|
61
62
|
deepwork/templates/gemini/skill-job-step.toml.jinja,sha256=GFVsHdPet5buy3TM6CcZ9pepVT2re0G4WABJ1CCS5y8,4845
|
|
62
63
|
deepwork/utils/__init__.py,sha256=AtvE49IFI8Rg36O4cNIlzB-oxvkW3apFgXExn8GSk6s,38
|
|
@@ -64,8 +65,8 @@ deepwork/utils/fs.py,sha256=TbkcGGqck4lborFerbBLrpVMDUz3E5ZaW6X0_B2t76k,4821
|
|
|
64
65
|
deepwork/utils/git.py,sha256=J4tAB1zE6-WMAEHbarevhmSvvPLkeKBpiRv1UxUVwYk,3748
|
|
65
66
|
deepwork/utils/validation.py,sha256=SyFg9fIu1JCDMbssQgJRCTUNToDNcINccn8lje-tjts,851
|
|
66
67
|
deepwork/utils/yaml_utils.py,sha256=INHhOmzC38fh7HYKLrq7vmS3dcuNsigH7_U71erS-hw,3127
|
|
67
|
-
deepwork-0.
|
|
68
|
-
deepwork-0.
|
|
69
|
-
deepwork-0.
|
|
70
|
-
deepwork-0.
|
|
71
|
-
deepwork-0.
|
|
68
|
+
deepwork-0.5.1.dist-info/METADATA,sha256=y8X5xPFKdLEdrEqg5Hhx4KvRYXqE8r7R9VH3EaW-lT4,13363
|
|
69
|
+
deepwork-0.5.1.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
|
|
70
|
+
deepwork-0.5.1.dist-info/entry_points.txt,sha256=RhJBySzm619kh-yIdsAyfFXInAlY8Jm-39FLIBcOj2s,51
|
|
71
|
+
deepwork-0.5.1.dist-info/licenses/LICENSE.md,sha256=W0EtJVYf0cQ_awukOCW1ETwNSpV2RKqnAGfoOjyz_K8,4126
|
|
72
|
+
deepwork-0.5.1.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|