donna 0.2.0__py3-none-any.whl → 0.2.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.
- donna/artifacts/intro.md +39 -0
- donna/artifacts/research/specs/report.md +163 -0
- donna/artifacts/research/work/research.md +198 -0
- donna/artifacts/rfc/specs/request_for_change.md +271 -0
- donna/artifacts/rfc/work/create.md +120 -0
- donna/artifacts/rfc/work/do.md +109 -0
- donna/artifacts/rfc/work/plan.md +68 -0
- donna/artifacts/usage/artifacts.md +41 -6
- donna/artifacts/usage/cli.md +106 -37
- donna/artifacts/usage/worlds.md +8 -2
- donna/cli/__main__.py +1 -1
- donna/cli/commands/artifacts.py +104 -17
- donna/cli/commands/sessions.py +7 -7
- donna/cli/commands/workspaces.py +42 -0
- donna/cli/errors.py +18 -0
- donna/cli/types.py +16 -9
- donna/cli/utils.py +2 -2
- donna/core/errors.py +1 -11
- donna/core/result.py +5 -8
- donna/core/utils.py +0 -3
- donna/lib/__init__.py +4 -0
- donna/lib/sources.py +1 -1
- donna/lib/worlds.py +2 -2
- donna/machine/action_requests.py +0 -5
- donna/machine/artifacts.py +8 -6
- donna/machine/primitives.py +4 -4
- donna/machine/sessions.py +12 -4
- donna/machine/state.py +2 -2
- donna/machine/tasks.py +4 -18
- donna/machine/templates.py +4 -2
- donna/primitives/artifacts/specification.py +13 -2
- donna/primitives/artifacts/workflow.py +11 -2
- donna/primitives/directives/list.py +86 -0
- donna/primitives/directives/view.py +52 -11
- donna/primitives/operations/finish_workflow.py +13 -2
- donna/primitives/operations/output.py +87 -0
- donna/primitives/operations/request_action.py +3 -9
- donna/primitives/operations/run_script.py +2 -2
- donna/protocol/utils.py +22 -0
- donna/workspaces/artifacts.py +238 -0
- donna/{world → workspaces}/artifacts_discovery.py +1 -1
- donna/{world → workspaces}/config.py +13 -6
- donna/{world → workspaces}/errors.py +55 -45
- donna/workspaces/initialization.py +78 -0
- donna/{world → workspaces}/markdown.py +21 -26
- donna/{world → workspaces}/sources/base.py +2 -2
- donna/{world → workspaces}/sources/markdown.py +7 -6
- donna/{world → workspaces}/templates.py +4 -4
- donna/{world → workspaces}/tmp.py +19 -1
- donna/{world → workspaces}/worlds/base.py +5 -2
- donna/{world → workspaces}/worlds/filesystem.py +23 -9
- donna/{world → workspaces}/worlds/python.py +12 -9
- {donna-0.2.0.dist-info → donna-0.2.1.dist-info}/METADATA +4 -1
- donna-0.2.1.dist-info/RECORD +92 -0
- {donna-0.2.0.dist-info → donna-0.2.1.dist-info}/WHEEL +1 -1
- donna/artifacts/work/do_it.md +0 -142
- donna/artifacts/work/do_it_fast.md +0 -98
- donna/artifacts/work/planning.md +0 -245
- donna/cli/commands/projects.py +0 -49
- donna/world/artifacts.py +0 -122
- donna/world/initialization.py +0 -42
- donna/world/worlds/__init__.py +0 -0
- donna-0.2.0.dist-info/RECORD +0 -85
- /donna/{artifacts/work → workspaces}/__init__.py +0 -0
- /donna/{world → workspaces}/sources/__init__.py +0 -0
- /donna/{world → workspaces/worlds}/__init__.py +0 -0
- {donna-0.2.0.dist-info → donna-0.2.1.dist-info}/entry_points.txt +0 -0
- {donna-0.2.0.dist-info → donna-0.2.1.dist-info}/licenses/LICENSE +0 -0
donna/artifacts/work/planning.md
DELETED
|
@@ -1,245 +0,0 @@
|
|
|
1
|
-
# Session Planning Guidelines
|
|
2
|
-
|
|
3
|
-
```toml donna
|
|
4
|
-
kind = "donna.lib.specification"
|
|
5
|
-
```
|
|
6
|
-
|
|
7
|
-
This document describes how Donna MUST plan work on a session with the help of workflows. The
|
|
8
|
-
document describes the process of planning, kinds of involved entities and requirements for them.
|
|
9
|
-
|
|
10
|
-
**This requirements MUST be applied to all planning workflows that Donna uses.**
|
|
11
|
-
|
|
12
|
-
## Overview
|
|
13
|
-
|
|
14
|
-
Donna's workflows create a plan of work on a session by iteratively polishing the set of session-level artifacts.
|
|
15
|
-
|
|
16
|
-
Artifacts are:
|
|
17
|
-
|
|
18
|
-
- `session:work_scope` — a specification that describes the scope of work to be done on the session.
|
|
19
|
-
- `session:work_execution` — a workflow that describes the step-by-step plan of work to be done on the session.
|
|
20
|
-
|
|
21
|
-
The agent MUST create and iteratively polish these artifacts until they meet all quality criteria described in this document. After the plan is ready, the agent MUST run it as a workflow.
|
|
22
|
-
|
|
23
|
-
## Work Scope Specification
|
|
24
|
-
|
|
25
|
-
The work scope specification has a standard name `session:work_scope` and describes the work to be done in the context of the current session.
|
|
26
|
-
|
|
27
|
-
The specification MUST contain the following sections:
|
|
28
|
-
|
|
29
|
-
1. `Developer request` — a copy of the original description of the work from the developer.
|
|
30
|
-
2. `Work description` — a high-level description of the work to be done, created by Donna
|
|
31
|
-
based on the developer request.
|
|
32
|
-
3. `Goals` — a list of goals that work strives to achieve.
|
|
33
|
-
4. `Objectives` — a list of specific objectives that need to be completed to achieve the goals.
|
|
34
|
-
5. `Known constraints` — a list of constraints for the session.
|
|
35
|
-
6. `Acceptance criteria` — a list of acceptance criteria for the resulted work.
|
|
36
|
-
7. `Deliverables / Artifacts` — a list of concrete deliverables / artifacts that MUST be produced.
|
|
37
|
-
|
|
38
|
-
Sections `Developer request` and `Detailed work description` are free-form text sections.
|
|
39
|
-
Sections `Goals`, `Objectives` should contain lists of items.
|
|
40
|
-
|
|
41
|
-
### "Developer Request" section requirements
|
|
42
|
-
|
|
43
|
-
- This section MUST contain the original request from the developer. The request MUST NOT be modified by Donna.
|
|
44
|
-
|
|
45
|
-
### "Work Description" section requirements
|
|
46
|
-
|
|
47
|
-
- The section MUST contain a clear professional high-level description of the work to be done based
|
|
48
|
-
on the developer's request.
|
|
49
|
-
- The section MUST be limited to a single paragraph with a few sentences.
|
|
50
|
-
- The sectino MUST explain what someone gains after these changes and how they can see it working.
|
|
51
|
-
State the user-visible behavior the task will enable.
|
|
52
|
-
|
|
53
|
-
### "Goals" section requirements
|
|
54
|
-
|
|
55
|
-
- The section MUST contain a list of high-level goals that the work strives to achieve.
|
|
56
|
-
|
|
57
|
-
The goal quality criteria:
|
|
58
|
-
|
|
59
|
-
- A goal describes a desired end state, outcome or result.
|
|
60
|
-
- A goal defines what should ultimately be true, not how to achieve it.
|
|
61
|
-
- A goal must not be defined via listing cases, states, outcomes, etc. Instead, use one of the next
|
|
62
|
-
approaches:
|
|
63
|
-
a) summarize top-layer items into a single goal;
|
|
64
|
-
b) split the goal into multiple more specific goals;
|
|
65
|
-
c) reformulate to a list of second-layer items as required properties of the top-level goal.
|
|
66
|
-
- Each goal must has clear scope and boundaries.
|
|
67
|
-
|
|
68
|
-
### "Objectives" section requirements
|
|
69
|
-
|
|
70
|
-
- The section MUST contain a list of specific objectives that need to be completed to achieve the goals.
|
|
71
|
-
|
|
72
|
-
Objective quality criteria:
|
|
73
|
-
|
|
74
|
-
- An objective MUST describe an achieved state or capability not the act of describing it.
|
|
75
|
-
- An objective MUST be phrased as "X exists / is implemented / is defined / is executable /
|
|
76
|
-
is enforced / …"
|
|
77
|
-
- An objective MUST be atomic: it MUST result in exactly one concrete deliverable: one artifact,
|
|
78
|
-
one executable, one schema, one test suite, etc.
|
|
79
|
-
- An objective is a single clear, externally observable condition of the system (not a description,
|
|
80
|
-
explanation, or analysis) that, when met, moves you closer to achieving a specific goal.
|
|
81
|
-
- An objective is a top-level unit of work whose completion results in a concrete artifact,
|
|
82
|
-
behavior, or state change that can be independently verified without reading prose.
|
|
83
|
-
- Each goal MUST have a set of objectives that, when all achieved, ensure the goal is met.
|
|
84
|
-
- Each goal MUST have 2–6 objectives, unless the goal is demonstrably trivial (≤1 artifact, no dependencies).
|
|
85
|
-
|
|
86
|
-
### "Known Constraints" section requirements
|
|
87
|
-
|
|
88
|
-
- The section MUST contain a list of known constraints that the work MUST respect.
|
|
89
|
-
|
|
90
|
-
Constraint quality criteria:
|
|
91
|
-
|
|
92
|
-
- A known constraint describes a non-negotiable limitation or requirement that the work MUST
|
|
93
|
-
respect (technical, organizational, legal, temporal, compatibility, security, operational).
|
|
94
|
-
- Each constraint MUST be derived from explicitly available inputs (the developer request, existed
|
|
95
|
-
specifications, existed code, information provided by workflows). Donna MUST NOT invent
|
|
96
|
-
constraints.
|
|
97
|
-
- Each constraint MUST be phrased as a verifiable rule using normative language: "MUST / MUST NOT /
|
|
98
|
-
SHOULD / SHOULD NOT".
|
|
99
|
-
- Each constraint MUST be atomic: one rule per record (no "and/or" bundles). If multiple rules
|
|
100
|
-
exist, split into multiple constraint records.
|
|
101
|
-
- Each constraint MUST be externally binding (something the plan must accommodate), not an
|
|
102
|
-
internal preference.
|
|
103
|
-
- Constraints MUST NOT restate goals/objectives in different words. They are bounds, not outcomes.
|
|
104
|
-
- Constraints MUST NOT contain implementation steps, designs, or proposed solutions.
|
|
105
|
-
- Constraints MUST NOT include risks, unknowns, or speculative issues.
|
|
106
|
-
- Constraints MUST be written so a reviewer can answer true/false for compliance by inspecting
|
|
107
|
-
artifacts, behavior, or configuration (not by reading explanatory prose).
|
|
108
|
-
- The section MAY be empty only if no constraints are explicitly known.
|
|
109
|
-
|
|
110
|
-
Examples:
|
|
111
|
-
|
|
112
|
-
- Good: `MUST remain compatible with Python 3.10`
|
|
113
|
-
- Good: `MUST not change public CLI flags`
|
|
114
|
-
- Good: `MUST avoid network access`
|
|
115
|
-
- Good: `MUST run on Windows + Linux`
|
|
116
|
-
- Bad: `We should do it cleanly`
|
|
117
|
-
- Bad: `Prefer elegant code`
|
|
118
|
-
- Bad: `Try to keep it simple`
|
|
119
|
-
|
|
120
|
-
### "Acceptance criteria" section requirements
|
|
121
|
-
|
|
122
|
-
- The section MUST contain a list of acceptance criteria that define how to evaluate the session's results.
|
|
123
|
-
|
|
124
|
-
Acceptance criteria quality criteria:
|
|
125
|
-
|
|
126
|
-
- An acceptance criterion describes a pass/fail condition that determines whether the session's
|
|
127
|
-
results are acceptable to a reviewer, user, or automated gate.
|
|
128
|
-
- Each criterion MUST be derived from explicitly available inputs (developer request, previous
|
|
129
|
-
sections of the plan). Donna MUST NOT invent new scope, features, constraints, or assumptions.
|
|
130
|
-
- Each criterion MUST be phrased as an externally observable, verifiable rule, using normative
|
|
131
|
-
language ("MUST / MUST NOT / SHOULD / SHOULD NOT") or an equivalent test form such as
|
|
132
|
-
Given/When/Then (Gherkin-style).
|
|
133
|
-
- Each criterion MUST be independently checkable by inspecting artifacts, running a command,
|
|
134
|
-
executing tests, or observing runtime behavior/output — not by reading explanatory prose.
|
|
135
|
-
- Each criterion MUST be atomic: one condition per record (no "and/or" bundles). If multiple
|
|
136
|
-
conditions exist, split into multiple criteria records.
|
|
137
|
-
- Criteria MUST NOT describe implementation steps, internal design decisions, or "how" to achieve the result.
|
|
138
|
-
- Criteria MUST NOT restate goals/objectives verbatim. Instead, they must state how success is
|
|
139
|
-
demonstrated (e.g., observable behavior, produced files, enforced rules, test outcomes).
|
|
140
|
-
|
|
141
|
-
Coverage rules:
|
|
142
|
-
|
|
143
|
-
- Each objective MUST have ≥1 acceptance criterion that validates it.
|
|
144
|
-
- Each acceptance criterion MUST map to at least one objective (directly or via a goal that the objective serves).
|
|
145
|
-
- Where relevant, criteria SHOULD specify concrete evaluation conditions, such as:
|
|
146
|
-
- exact CLI output/exit codes, produced artifacts and their locations;
|
|
147
|
-
- supported platforms/versions, configuration prerequisites;
|
|
148
|
-
- measurable thresholds (latency, memory, size limits), if such requirements are explicitly implied or stated.
|
|
149
|
-
- etc.
|
|
150
|
-
|
|
151
|
-
Regression rules:
|
|
152
|
-
|
|
153
|
-
- If the developer request or known constraints imply preserving existing behavior, acceptance
|
|
154
|
-
criteria SHOULD include explicit non-regression checks (what must remain unchanged).
|
|
155
|
-
- The section MUST NOT be empty.
|
|
156
|
-
|
|
157
|
-
### "Deliverables / Artifacts" section requirements
|
|
158
|
-
|
|
159
|
-
- The section MUST contain a list of concrete deliverables/artifacts that MUST be produced by the work.
|
|
160
|
-
|
|
161
|
-
Deliverable/artifact quality criteria:
|
|
162
|
-
|
|
163
|
-
- A deliverable/artifact record MUST name a concrete output that will exist after the work is
|
|
164
|
-
complete (a file, module, package, binary, schema, configuration, test suite, generated report,
|
|
165
|
-
published document, metric in the metrics storage, dashbord, etc.).
|
|
166
|
-
- Each deliverable/artifact MUST be derived from explicitly available inputs (developer request,
|
|
167
|
-
prior sections of this plan). Donna MUST NOT invent new deliverables that introduce new scope.
|
|
168
|
-
- Each deliverable/artifact MUST be externally verifiable by inspecting the repository/workspace,
|
|
169
|
-
produced files, or runtime outputs — not by reading explanatory prose.
|
|
170
|
-
- Each deliverable/artifact record MUST be phrased as an existence statement using normative
|
|
171
|
-
language, e.g. "MUST include …", "MUST produce …", "MUST add …".
|
|
172
|
-
- Each deliverable/artifact record MUST be atomic: exactly one deliverable per record (no
|
|
173
|
-
"and/or", no bundles). If multiple outputs are required, split into multiple records.
|
|
174
|
-
- Each deliverable/artifact MUST specify at least one of:
|
|
175
|
-
- an exact path/location (preferred), or
|
|
176
|
-
- an exact artifact identifier (module/package name, command name, schema name, etc.).
|
|
177
|
-
- If the deliverable is generated by running a command, the record SHOULD specify the command
|
|
178
|
-
entrypoint (e.g., via a CLI (Command-Line Interface) command name) and the expected output
|
|
179
|
-
location, without describing internal implementation steps.
|
|
180
|
-
- Deliverables MUST NOT be vague (e.g., "updated code", "better docs"). They MUST be concrete
|
|
181
|
-
enough that a reviewer can confirm presence/absence.
|
|
182
|
-
- Deliverables MUST NOT restate goals, objectives, constraints, or acceptance criteria. They must
|
|
183
|
-
list *outputs*, not outcomes or pass/fail checks.
|
|
184
|
-
- The section MUST NOT be empty.
|
|
185
|
-
|
|
186
|
-
Source files as artifacts:
|
|
187
|
-
|
|
188
|
-
- Explicitly add source files (paths) as deliverables/artifacts only if the task is specifically
|
|
189
|
-
about creating or modifying those files (e.g., "MUST add docs/cli.md …").
|
|
190
|
-
- Do not add source files as deliverables/artifacts if they are unknown at planning time (i.e. we
|
|
191
|
-
do not know which files will be changed/added). In such cases, focus on higher-level deliverables
|
|
192
|
-
(e.g., "MUST add CLI documentation" instead of listing specific files).
|
|
193
|
-
|
|
194
|
-
## Work Execution Workflow
|
|
195
|
-
|
|
196
|
-
The work execution workflow has a standard name `session:work_execution` and describes the step-by-step plan of work to be done in the context of the current session.
|
|
197
|
-
|
|
198
|
-
The workflow MUST be an artifact of kind `workflow`, see details `{{ donna.lib.view("donna:usage:artifacts") }}`. I.e. the final workflow must be a valid FSM that agent will execute with the help of `donna` tool.
|
|
199
|
-
|
|
200
|
-
Primary requirement:
|
|
201
|
-
|
|
202
|
-
1. **You MUST prefer non-linear or cyclic workflows for complex tasks instead of long linear sequences.** I.e. use loops, conditionals, parallel branches, etc. where appropriate. That should help you to apply changes iteratively, validate them early and often and to polish the results step by step. I.e. prefere an incremental/evolutionary approach over a big-bang one.
|
|
203
|
-
2. However, prefere multiple short loops over a single long loop. The approach `do everything then repeat from scratch` is a bad practice. Instead, break down the work into smaller steps that can be done, verified and polished independently.
|
|
204
|
-
3. The resulted workflow MUST ensure that there is at least 1 refine iteration will always be applied (for each loop).
|
|
205
|
-
4. Describe each operation with effort: add details, examples, behavior for edge cases, etc. Formulate each term and action precisely.
|
|
206
|
-
|
|
207
|
-
General requirements:
|
|
208
|
-
|
|
209
|
-
- Each workflow step should describe an operation dedicated to one semantically atomic task.
|
|
210
|
-
- Each operation of the workflow MUST be derived from explicitly available inputs (developer request +
|
|
211
|
-
prior plan sections). It MUST NOT introduce new scope, features, constraints, or deliverables.
|
|
212
|
-
- Each workflow operation item MUST map to ≥1 objective.
|
|
213
|
-
- Each objective MUST be covered by ≥1 workflow operation that produces the required change/artifact,
|
|
214
|
-
and where relevant by additional item(s) that validate it (tests, checks, demo run).
|
|
215
|
-
- Each workflow operation MUST be atomic: one primary action per item (no "and/or" bundles). If
|
|
216
|
-
multiple actions are needed, split into multiple items.
|
|
217
|
-
- Each workflow operation MUST be actionable and specific enough that a agent can execute it
|
|
218
|
-
without needing additional prose:
|
|
219
|
-
- It SHOULD name the component/module/subsystem affected, if known.
|
|
220
|
-
- It SHOULD name the concrete artifact(s) it will create/modify when those artifacts are already
|
|
221
|
-
known from the "Deliverables / Artifacts" section (do not invent file paths).
|
|
222
|
-
- If a command is required (e.g., a CLI (Command-Line Interface) invocation, test runner command),
|
|
223
|
-
operation SHOULD include the exact command.
|
|
224
|
-
- Workflow operation MUST NOT be vague (e.g., "Improve code quality", "Handle edge cases", "Do the thing").
|
|
225
|
-
- Workflow operations MUST respect all "Known constraints".
|
|
226
|
-
- If workflow operation includes research/design work, there results MUST be represented as concrete artifacts or changes in the `session:work_scope` and `session:work_execution` artifacts.
|
|
227
|
-
|
|
228
|
-
Verification steps:
|
|
229
|
-
|
|
230
|
-
- The workflow SHOULD include explicit verification operations that demonstrate acceptance
|
|
231
|
-
criteria, such as:
|
|
232
|
-
- adding or updating automated tests;
|
|
233
|
-
- running tests/lint/static checks (if such gates exist in the project inputs);
|
|
234
|
-
- running a minimal end-to-end command or scenario that shows the user-visible behavior.
|
|
235
|
-
- Verification MUST be phrased as executable checks (commands, test suites, observable outputs), not
|
|
236
|
-
as "Review the code" or "Make sure it works".
|
|
237
|
-
|
|
238
|
-
Examples:
|
|
239
|
-
|
|
240
|
-
- Good: "Implement the `foo` subcommand behavior to emit the required summary line for each generation."
|
|
241
|
-
- Good: "Add automated tests that assert the `foo` subcommand exit code and exact stdout lines for the sample fixture."
|
|
242
|
-
- Good: "Run `pytest -q` and confirm the new tests pass."
|
|
243
|
-
- Bad: "Implement feature and update tests and docs."
|
|
244
|
-
- Bad: "Consider performance implications."
|
|
245
|
-
- Bad: "Document the approach in detail."
|
donna/cli/commands/projects.py
DELETED
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
import pathlib
|
|
2
|
-
from collections.abc import Iterable
|
|
3
|
-
|
|
4
|
-
import typer
|
|
5
|
-
|
|
6
|
-
from donna.cli.application import app
|
|
7
|
-
from donna.cli.types import WorkdirOption
|
|
8
|
-
from donna.cli.utils import cells_cli, try_initialize_donna
|
|
9
|
-
from donna.domain.ids import WorldId
|
|
10
|
-
from donna.protocol.cell_shortcuts import operation_succeeded
|
|
11
|
-
from donna.protocol.cells import Cell
|
|
12
|
-
from donna.world.config import config
|
|
13
|
-
|
|
14
|
-
projects_cli = typer.Typer()
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
@projects_cli.callback(invoke_without_command=True)
|
|
18
|
-
def initialize_callback(ctx: typer.Context) -> None:
|
|
19
|
-
cmd = ctx.invoked_subcommand
|
|
20
|
-
|
|
21
|
-
if cmd is None:
|
|
22
|
-
return
|
|
23
|
-
|
|
24
|
-
if cmd in ["initialize"]:
|
|
25
|
-
return
|
|
26
|
-
|
|
27
|
-
try_initialize_donna()
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
@projects_cli.command(help="Initialize Donna project.")
|
|
31
|
-
@cells_cli
|
|
32
|
-
def initialize(workdir: WorkdirOption = pathlib.Path.cwd()) -> Iterable[Cell]:
|
|
33
|
-
# TODO: use workdir attribute
|
|
34
|
-
project = config().get_world(WorldId("project")).unwrap()
|
|
35
|
-
|
|
36
|
-
project.initialize()
|
|
37
|
-
|
|
38
|
-
session = config().get_world(WorldId("session")).unwrap()
|
|
39
|
-
|
|
40
|
-
session.initialize()
|
|
41
|
-
|
|
42
|
-
return [operation_succeeded("Project initialized successfully")]
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
app.add_typer(
|
|
46
|
-
projects_cli,
|
|
47
|
-
name="projects",
|
|
48
|
-
help="Initialize and manage Donna project.",
|
|
49
|
-
)
|
donna/world/artifacts.py
DELETED
|
@@ -1,122 +0,0 @@
|
|
|
1
|
-
import pathlib
|
|
2
|
-
|
|
3
|
-
from donna.core.entities import BaseEntity
|
|
4
|
-
from donna.core.errors import ErrorsList
|
|
5
|
-
from donna.core.result import Err, Ok, Result, unwrap_to_error
|
|
6
|
-
from donna.domain.ids import FullArtifactId, FullArtifactIdPattern, WorldId
|
|
7
|
-
from donna.machine.artifacts import Artifact
|
|
8
|
-
from donna.machine.tasks import Task, WorkUnit
|
|
9
|
-
from donna.world import errors
|
|
10
|
-
from donna.world.config import config
|
|
11
|
-
from donna.world.templates import RenderMode
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
class ArtifactRenderContext(BaseEntity):
|
|
15
|
-
primary_mode: RenderMode
|
|
16
|
-
current_task: Task | None = None
|
|
17
|
-
current_work_unit: WorkUnit | None = None
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
class ArtifactUpdateError(errors.WorldError):
|
|
21
|
-
cell_kind: str = "artifact_update_error"
|
|
22
|
-
artifact_id: FullArtifactId
|
|
23
|
-
path: pathlib.Path
|
|
24
|
-
|
|
25
|
-
def content_intro(self) -> str:
|
|
26
|
-
return f"Error updating artifact '{self.artifact_id}' from the path '{self.path}'"
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
class CanNotUpdateReadonlyWorld(ArtifactUpdateError):
|
|
30
|
-
code: str = "donna.world.cannot_update_readonly_world"
|
|
31
|
-
message: str = "Cannot upload artifact to the read-only world `{error.world_id}`"
|
|
32
|
-
world_id: WorldId
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
class InputPathHasNoExtension(ArtifactUpdateError):
|
|
36
|
-
code: str = "donna.world.input_path_has_no_extension"
|
|
37
|
-
message: str = "Input path has no extension to determine artifact source type"
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
class NoSourceForArtifactExtension(ArtifactUpdateError):
|
|
41
|
-
code: str = "donna.world.no_source_for_artifact_extension"
|
|
42
|
-
message: str = "No source found for artifact extension of input path"
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
@unwrap_to_error
|
|
46
|
-
def artifact_file_extension(full_id: FullArtifactId) -> Result[str, ErrorsList]:
|
|
47
|
-
world = config().get_world(full_id.world_id).unwrap()
|
|
48
|
-
return Ok(world.file_extension_for(full_id.artifact_id).unwrap().lstrip("."))
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
@unwrap_to_error
|
|
52
|
-
def fetch_artifact(full_id: FullArtifactId, output: pathlib.Path) -> Result[None, ErrorsList]:
|
|
53
|
-
world = config().get_world(full_id.world_id).unwrap()
|
|
54
|
-
content = world.fetch_source(full_id.artifact_id).unwrap()
|
|
55
|
-
|
|
56
|
-
with output.open("wb") as f:
|
|
57
|
-
f.write(content)
|
|
58
|
-
|
|
59
|
-
return Ok(None)
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
@unwrap_to_error
|
|
63
|
-
def update_artifact(full_id: FullArtifactId, input: pathlib.Path) -> Result[None, ErrorsList]:
|
|
64
|
-
world = config().get_world(full_id.world_id).unwrap()
|
|
65
|
-
|
|
66
|
-
if world.readonly:
|
|
67
|
-
return Err([CanNotUpdateReadonlyWorld(artifact_id=full_id, path=input, world_id=world.id)])
|
|
68
|
-
|
|
69
|
-
source_suffix = input.suffix.lower()
|
|
70
|
-
content_bytes = input.read_bytes()
|
|
71
|
-
|
|
72
|
-
if not source_suffix:
|
|
73
|
-
return Err([InputPathHasNoExtension(artifact_id=full_id, path=input)])
|
|
74
|
-
|
|
75
|
-
source_config = config().find_source_for_extension(source_suffix)
|
|
76
|
-
if source_config is None:
|
|
77
|
-
return Err([NoSourceForArtifactExtension(artifact_id=full_id, path=input)])
|
|
78
|
-
|
|
79
|
-
render_context = ArtifactRenderContext(primary_mode=RenderMode.view)
|
|
80
|
-
test_artifact = source_config.construct_artifact_from_bytes(full_id, content_bytes, render_context).unwrap()
|
|
81
|
-
validation_result = test_artifact.validate_artifact()
|
|
82
|
-
|
|
83
|
-
validation_result.unwrap()
|
|
84
|
-
world.update(full_id.artifact_id, content_bytes, source_suffix).unwrap()
|
|
85
|
-
|
|
86
|
-
return Ok(None)
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
@unwrap_to_error
|
|
90
|
-
def load_artifact(
|
|
91
|
-
full_id: FullArtifactId, render_context: ArtifactRenderContext | None = None
|
|
92
|
-
) -> Result[Artifact, ErrorsList]:
|
|
93
|
-
if render_context is None:
|
|
94
|
-
render_context = ArtifactRenderContext(primary_mode=RenderMode.view)
|
|
95
|
-
|
|
96
|
-
world = config().get_world(full_id.world_id).unwrap()
|
|
97
|
-
return Ok(world.fetch(full_id.artifact_id, render_context).unwrap())
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
def list_artifacts( # noqa: CCR001
|
|
101
|
-
pattern: FullArtifactIdPattern, render_context: ArtifactRenderContext | None = None
|
|
102
|
-
) -> Result[list[Artifact], ErrorsList]:
|
|
103
|
-
|
|
104
|
-
if render_context is None:
|
|
105
|
-
render_context = ArtifactRenderContext(primary_mode=RenderMode.view)
|
|
106
|
-
|
|
107
|
-
artifacts: list[Artifact] = []
|
|
108
|
-
errors: ErrorsList = []
|
|
109
|
-
|
|
110
|
-
for world in reversed(config().worlds_instances):
|
|
111
|
-
for artifact_id in world.list_artifacts(pattern):
|
|
112
|
-
full_id = FullArtifactId((world.id, artifact_id))
|
|
113
|
-
artifact_result = load_artifact(full_id, render_context)
|
|
114
|
-
if artifact_result.is_err():
|
|
115
|
-
errors.extend(artifact_result.unwrap_err())
|
|
116
|
-
continue
|
|
117
|
-
artifacts.append(artifact_result.unwrap())
|
|
118
|
-
|
|
119
|
-
if errors:
|
|
120
|
-
return Err(errors)
|
|
121
|
-
|
|
122
|
-
return Ok(artifacts)
|
donna/world/initialization.py
DELETED
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
import tomllib
|
|
2
|
-
|
|
3
|
-
from donna.core import errors as core_errors
|
|
4
|
-
from donna.core import utils
|
|
5
|
-
from donna.core.result import Err, Ok, Result, unwrap_to_error
|
|
6
|
-
from donna.world import config
|
|
7
|
-
from donna.world import errors as world_errors
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
@unwrap_to_error
|
|
11
|
-
def initialize_environment() -> Result[None, core_errors.ErrorsList]:
|
|
12
|
-
"""Initialize the environment for the application.
|
|
13
|
-
|
|
14
|
-
This function MUST be called before any other operations.
|
|
15
|
-
"""
|
|
16
|
-
project_dir = utils.discover_project_dir(config.DONNA_DIR_NAME).unwrap()
|
|
17
|
-
|
|
18
|
-
config.project_dir.set(project_dir)
|
|
19
|
-
|
|
20
|
-
config_dir = project_dir / config.DONNA_DIR_NAME
|
|
21
|
-
|
|
22
|
-
config.config_dir.set(config_dir)
|
|
23
|
-
|
|
24
|
-
config_path = config_dir / config.DONNA_CONFIG_NAME
|
|
25
|
-
|
|
26
|
-
if not config_path.exists():
|
|
27
|
-
config.config.set(config.Config())
|
|
28
|
-
return Ok(None)
|
|
29
|
-
|
|
30
|
-
try:
|
|
31
|
-
data = tomllib.loads(config_path.read_text())
|
|
32
|
-
except tomllib.TOMLDecodeError as e:
|
|
33
|
-
return Err([world_errors.ConfigParseFailed(config_path=config_path, details=str(e))])
|
|
34
|
-
|
|
35
|
-
try:
|
|
36
|
-
loaded_config = config.Config.model_validate(data)
|
|
37
|
-
except Exception as e:
|
|
38
|
-
return Err([world_errors.ConfigValidationFailed(config_path=config_path, details=str(e))])
|
|
39
|
-
|
|
40
|
-
config.config.set(loaded_config)
|
|
41
|
-
|
|
42
|
-
return Ok(None)
|
donna/world/worlds/__init__.py
DELETED
|
File without changes
|
donna-0.2.0.dist-info/RECORD
DELETED
|
@@ -1,85 +0,0 @@
|
|
|
1
|
-
donna/__init__.py,sha256=lEC7l3wDCBiC5gw56XkAeBW1XJA52pck7SFR1_CUals,41
|
|
2
|
-
donna/artifacts/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
3
|
-
donna/artifacts/usage/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
4
|
-
donna/artifacts/usage/artifacts.md,sha256=slHrJRmFYiXxOQnPWHY5bb3LOa1VLmRnWS6FvKFWlHs,11241
|
|
5
|
-
donna/artifacts/usage/cli.md,sha256=GzWaGK-QB_Bg3A1czVzIPmWLcR7565hBW4gEkQHAtZo,6753
|
|
6
|
-
donna/artifacts/usage/worlds.md,sha256=EBMGLg6ae_Paiaeas5CyCaOqs13xXu9tp6IQASyIdYs,1848
|
|
7
|
-
donna/artifacts/work/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
8
|
-
donna/artifacts/work/do_it.md,sha256=bCYeF45vET83qPdh4m5n4QH8wSUjdsbcSZzsHKZ_Amo,5594
|
|
9
|
-
donna/artifacts/work/do_it_fast.md,sha256=2TSAvrUlNC7PUCU1F1YNiu3KtTiBLO501XdxVarru3s,3594
|
|
10
|
-
donna/artifacts/work/planning.md,sha256=C2kbUopoGdWM7CHmTTCP0Sbetff8zYkMqOFXuNbjdRE,14375
|
|
11
|
-
donna/cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
12
|
-
donna/cli/__main__.py,sha256=sKI9NNX2pKkuxmyzgMvULCtNOBHQYW1BGPhxOK4ZPvI,222
|
|
13
|
-
donna/cli/application.py,sha256=rIEseTvPZgX4tZ23fTX49LF0XLfyzTO8gtpA8G80MTI,466
|
|
14
|
-
donna/cli/commands/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
15
|
-
donna/cli/commands/artifacts.py,sha256=E_84OwE08Cb59P_qFavpe0HdvuhhCCDJryb28EaGwH8,3609
|
|
16
|
-
donna/cli/commands/projects.py,sha256=bu257fUnV-RhYJUw_lUNW9w17XS2AFbf2PP5bqr4hiY,1198
|
|
17
|
-
donna/cli/commands/sessions.py,sha256=eTu65EBB2kve43WoGnK4oNsTGXz2Pas8t1fwurKPkec,2122
|
|
18
|
-
donna/cli/types.py,sha256=YsBPGPSV6h1f8dNvnQmWefnW2s_ARRwG75_u2DXSm-8,3546
|
|
19
|
-
donna/cli/utils.py,sha256=kQm-bYDQu-xLZJXT59F6w3HlPjAiYs9EIpK9aacxz_E,1421
|
|
20
|
-
donna/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
21
|
-
donna/core/entities.py,sha256=Y3udcI1ykWDI_yPqCX6JTuDmF81BxO0PnnJzzD5uMoM,753
|
|
22
|
-
donna/core/errors.py,sha256=k6Dx4tNids64mupnpnkMF2dEVkfMF5Bm04Rx2fjWQYM,3771
|
|
23
|
-
donna/core/result.py,sha256=nlugpkq0bdeOT626dnwLfF7fTvidKvTmjiMwKAiX-BA,2392
|
|
24
|
-
donna/core/utils.py,sha256=BViEifQWxZ8ju2427VKk1P_xk4fVVOHTAdJIv-7Oyyk,1276
|
|
25
|
-
donna/domain/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
26
|
-
donna/domain/errors.py,sha256=jewM3wYUCGLwNb8tvHkJ35-Y59ezJKgWy7pr_Utk7iA,1253
|
|
27
|
-
donna/domain/ids.py,sha256=CMEBRj6i2vjVi74TtUcjLTALn3MqKsEbs-Iv463mjVg,14678
|
|
28
|
-
donna/lib/__init__.py,sha256=4g2r8dSat9yxkmKPpX8f-ANbTp6HDNXM5K_L2c_Ihb4,834
|
|
29
|
-
donna/lib/sources.py,sha256=96RMyWBFL0Y6MxORtl7E4fE-dDECH0CYPcAA_v33UB8,177
|
|
30
|
-
donna/lib/worlds.py,sha256=5uepMT4aJJYwz2vqVQ9vcymjygaUKnBn_V4lBizmvH0,276
|
|
31
|
-
donna/machine/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
32
|
-
donna/machine/action_requests.py,sha256=Tdp0Q64lCZLjrzOsLbxFaZ1fJNVKBRXmc8-HmBuhZ7w,1377
|
|
33
|
-
donna/machine/artifacts.py,sha256=_Gwsu5lasnFF0GuWXMFUL-3FOZiyX9GcAzVXgZr-3o8,6603
|
|
34
|
-
donna/machine/changes.py,sha256=TlgMA70u0ffRvwKVBwXEgEk1bp4m9w9MsVxtishX9Sw,2463
|
|
35
|
-
donna/machine/errors.py,sha256=45EPNC12rRT2pdgd2b9HMXCP0aon4sxo9DdUfxXeMnQ,4956
|
|
36
|
-
donna/machine/operations.py,sha256=CHXPy8hDYNqE5woVMj_lu2p4wgl7fqRxO0Dz0v1t4zI,761
|
|
37
|
-
donna/machine/primitives.py,sha256=DuCecXLwIsYOD3fzFp5ZQ08b1_K4Xlol6SDvM09X2ms,3267
|
|
38
|
-
donna/machine/sessions.py,sha256=eA_SV8zDtjKg3vA6wmbT7P14RK68TA2XbFAZMLYuyXc,6880
|
|
39
|
-
donna/machine/state.py,sha256=E5ckioJ8K5Mv_IvJyNf7O15tW10hSYf6oA79x3WiZKU,8101
|
|
40
|
-
donna/machine/tasks.py,sha256=10hPk325VR5Ii6vytqeNRq9rgGCEM8SGoqrvgz1lQSA,2826
|
|
41
|
-
donna/machine/templates.py,sha256=wB6s41fTaHD-GuL3zPn1JTID5scfpUgVzBiuFfyYUtU,2474
|
|
42
|
-
donna/primitives/__init__.py,sha256=CfJhz3TLdFxYbqCXioWVAIKGQ2tAMwXwL_Fg3A68Dqo,53
|
|
43
|
-
donna/primitives/artifacts/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
44
|
-
donna/primitives/artifacts/specification.py,sha256=3mzZLIMwKhDJ-GxJ0X0vW1Xh-PqFXwg9EDy_jooS8eI,461
|
|
45
|
-
donna/primitives/artifacts/workflow.py,sha256=7YlJ7ohpeWnuGhnoRqlFTZGq-54STLL_BDTYYGWz4sc,7684
|
|
46
|
-
donna/primitives/directives/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
47
|
-
donna/primitives/directives/goto.py,sha256=uJdMJe3leJPSl_0PU4jd2AbHFJsJkf-x6rKhn4hKZd8,1679
|
|
48
|
-
donna/primitives/directives/task_variable.py,sha256=KvxY8ZOKFh6alkBhgDvkWzIJBfRNP4oYKRJ0SgHzO_g,2959
|
|
49
|
-
donna/primitives/directives/view.py,sha256=BiTZULx1ZC0z4V_Z6EaG3bYLcFna-nV_akaVXAvxJRo,1558
|
|
50
|
-
donna/primitives/operations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
51
|
-
donna/primitives/operations/finish_workflow.py,sha256=qRSjemF2o2Lim-GGrnjBjouxPMzDS9M-QEw_Weg0Zu0,1494
|
|
52
|
-
donna/primitives/operations/request_action.py,sha256=cwNZl5Av1ko3DU4fcO62xCFJqvIUmm7ff_BvTaGmAhA,3041
|
|
53
|
-
donna/primitives/operations/run_script.py,sha256=Pl6llF9_Ck-WXn_4-cVfxY9K2WyrbEoOfQJGSxA__Xs,9338
|
|
54
|
-
donna/protocol/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
55
|
-
donna/protocol/cell_shortcuts.py,sha256=dZVCzoaPu09IYEA5g5gYPhR-q8MpgmehcYti1z9BBuI,385
|
|
56
|
-
donna/protocol/cells.py,sha256=jQCM-l31Kt7gEBXgvb7Ph5Fstbz9lf0lEUbH0bgNlWg,1348
|
|
57
|
-
donna/protocol/errors.py,sha256=u54fxMtJMWL8cbOLWU0acrmxV7Q8uHnyT1NFw959SMI,486
|
|
58
|
-
donna/protocol/formatters/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
59
|
-
donna/protocol/formatters/automation.py,sha256=I_I-b8bixuXBlKqn2ryHDKSdRJy77FzDATJi-jhEPWI,928
|
|
60
|
-
donna/protocol/formatters/base.py,sha256=PGrAgxiEtZKyg1wPePQMt5syOr6IpC4ydh5rMElaojE,405
|
|
61
|
-
donna/protocol/formatters/human.py,sha256=WvoZVYlD4H3MftDkpEEP_RtyZnzJhUWKNecKgm3FoXg,1168
|
|
62
|
-
donna/protocol/formatters/llm.py,sha256=z_2djZFaVVHjLYFMneUrYp5sA-EvtPuHUDzGKV1ogu4,1266
|
|
63
|
-
donna/protocol/modes.py,sha256=vFDjciPdPy26XlLBGrgAn1kAVW7EJAHrccGcJrK7vUo,960
|
|
64
|
-
donna/protocol/nodes.py,sha256=aP5IVOouZe6akSdfzPpfcGuZLbxkEieTE6j6SuVuTUU,1974
|
|
65
|
-
donna/world/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
66
|
-
donna/world/artifacts.py,sha256=qCACfo6ZNX1UypM2bHIiYRnMNDjh-PVJY4IumEpCB0c,4316
|
|
67
|
-
donna/world/artifacts_discovery.py,sha256=8-IYannZodL65paQxXjk_sJ_cATXXe9252FF-OAVqpo,2798
|
|
68
|
-
donna/world/config.py,sha256=XS4r1Y3TKmKJZGLqywGDa8U3uyG-ZeHWKZTp9G4v4yw,6355
|
|
69
|
-
donna/world/errors.py,sha256=fGB89o2qRNu8ojU71SJvsc432x4C3P31Kn4k1i7PYWc,7799
|
|
70
|
-
donna/world/initialization.py,sha256=AfA79qVoa7iJo16ut0NonHe54oh_yaOiurps3ftjldg,1268
|
|
71
|
-
donna/world/markdown.py,sha256=4KDEG0B4P2G6dKO1S8eNLY_XLKiw4d8aLoP_HEmEvm0,7250
|
|
72
|
-
donna/world/sources/__init__.py,sha256=IRwKWnqQKh1ase742jhdadBcS4E9Hxr6j_l9Li6wwfw,70
|
|
73
|
-
donna/world/sources/base.py,sha256=P5O2O1A7_GWqJvVVTwjg_fCH0TYIWUJpAjacB0LZBqk,2010
|
|
74
|
-
donna/world/sources/markdown.py,sha256=sQ7Tgk0-xbPF0h7o77epq58wa5zt9lkGzT9EpXvMcFo,9669
|
|
75
|
-
donna/world/templates.py,sha256=bcrDvZBBRfDdXYmh1jevzDBVDT-2hmMRdGkd0xx2RVQ,6054
|
|
76
|
-
donna/world/tmp.py,sha256=oKXMt3WDn10hYlYxwuSHC7ZpD7sDjl06RqNdfJ58ZAc,791
|
|
77
|
-
donna/world/worlds/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
78
|
-
donna/world/worlds/base.py,sha256=3SZp44lzmYmve1XiXyUX5oD6NWSvrXqg7aar0dO7lsM,2465
|
|
79
|
-
donna/world/worlds/filesystem.py,sha256=W18pSCJQAkeP5gn_FkIU-FIorrXTfMipUGc1FjbqfOo,6648
|
|
80
|
-
donna/world/worlds/python.py,sha256=R9BOZJJT9MomNzTM0L19SO43DAwQY_R-QL9JtrcjPtc,7035
|
|
81
|
-
donna-0.2.0.dist-info/METADATA,sha256=4N8NZmx4hgJCowL7fT7ODPH7Xr8imdKiPGaXgxlpPXE,2012
|
|
82
|
-
donna-0.2.0.dist-info/WHEEL,sha256=3ny-bZhpXrU6vSQ1UPG34FoxZBp3lVcvK0LkgUz6VLk,88
|
|
83
|
-
donna-0.2.0.dist-info/entry_points.txt,sha256=r2W_yOzauooYCu312OQwCycIN1UjVnO5paPpS2EDZqo,48
|
|
84
|
-
donna-0.2.0.dist-info/licenses/LICENSE,sha256=KiF6_RVxH0MLeHZZtc8ag497X-c6oPmk-0OOf9qQDDk,1504
|
|
85
|
-
donna-0.2.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|