donna 0.2.3__py3-none-any.whl → 0.2.4__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 +3 -2
- donna/artifacts/usage/cli.md +10 -0
- donna/cli/application.py +6 -8
- donna/cli/commands/artifacts.py +1 -11
- donna/cli/commands/sessions.py +1 -11
- donna/cli/commands/workspaces.py +8 -17
- donna/cli/types.py +18 -1
- donna/cli/utils.py +23 -4
- donna/primitives/directives/goto.py +7 -3
- donna/primitives/directives/list.py +7 -3
- donna/primitives/directives/view.py +7 -3
- donna/protocol/modes.py +4 -18
- donna/workspaces/config.py +10 -1
- donna/workspaces/initialization.py +17 -3
- {donna-0.2.3.dist-info → donna-0.2.4.dist-info}/METADATA +5 -3
- {donna-0.2.3.dist-info → donna-0.2.4.dist-info}/RECORD +19 -19
- {donna-0.2.3.dist-info → donna-0.2.4.dist-info}/WHEEL +0 -0
- {donna-0.2.3.dist-info → donna-0.2.4.dist-info}/entry_points.txt +0 -0
- {donna-0.2.3.dist-info → donna-0.2.4.dist-info}/licenses/LICENSE +0 -0
donna/artifacts/intro.md
CHANGED
|
@@ -35,5 +35,6 @@ Artifact type tags:
|
|
|
35
35
|
1. On start of the YOUR session you **MUST** read and understand instruction on using the Donna tool `{{ donna.lib.view("donna:usage:cli") }}`. It **MUST** be a one time operation. Do not repeat it unless you forget how to use the tool.
|
|
36
36
|
2. If you need to perform a work with Donna, you **MUST** select an appropriate Donna workflow to perform the work and run it.
|
|
37
37
|
3. If there is no appropriate workflow, ask the developer for a precise instructions on what to do.
|
|
38
|
-
4.
|
|
39
|
-
5. List all
|
|
38
|
+
4. If you are executing a workflow operation and need to perform a complex action or changes, you SHOULD search for an appropriate workflow and run it (as a child workflow) — it is the intended way to use Donna.
|
|
39
|
+
5. List all workflows: `{{ donna.lib.list("**", tags=["workflow"]) }}`
|
|
40
|
+
6. List all specifications: `{{ donna.lib.list("**", tags=["specification"]) }}`
|
donna/artifacts/usage/cli.md
CHANGED
|
@@ -39,6 +39,12 @@ We may need coding agents on the each step of the process, but there no reason f
|
|
|
39
39
|
Protocol selects the output formatting and behavior of Donna's CLI for different consumers (humans, LLMs, automation).
|
|
40
40
|
When an agent invokes Donna, it SHOULD use the `llm` protocol (pass an `-p llm` argument) unless the developer explicitly instructs otherwise.
|
|
41
41
|
|
|
42
|
+
### Project root
|
|
43
|
+
|
|
44
|
+
`-r <project-root>` sets the project root explicitly for any command (long form: `--root`).
|
|
45
|
+
If it is omitted, Donna discovers the project root by searching from the current working directory upwards for the `.donna` workspace directory.
|
|
46
|
+
Use this option when you run Donna from outside the project tree or when you want to target a specific project.
|
|
47
|
+
|
|
42
48
|
### Protocol cells
|
|
43
49
|
|
|
44
50
|
Donna communicates its progress and requests by outputting inrofmation organized in "cells". There are two kinds of cells output:
|
|
@@ -172,6 +178,10 @@ The format of `<artifact-pattern>` is as follows:
|
|
|
172
178
|
|
|
173
179
|
**All Donna CLI commands MUST include an explicit protocol selection using `-p <protocol>`.** Like `donna -p llm <command>`.
|
|
174
180
|
|
|
181
|
+
**All Donna CLI commands MUST be run from the project root or its subdirectories unless you pass `-r <project-root>`.**
|
|
182
|
+
|
|
183
|
+
If you are not running from the project root or its subdirectories, add `-r <project-root>` to point Donna to the correct project.
|
|
184
|
+
|
|
175
185
|
**Pass text arguments to the tool in quotes with respect to escaping.** The tool MUST receive the exact text you want to pass as an argument.
|
|
176
186
|
|
|
177
187
|
Use one of the next approaches to correctly escape text arguments:
|
donna/cli/application.py
CHANGED
|
@@ -1,17 +1,15 @@
|
|
|
1
1
|
import typer
|
|
2
2
|
|
|
3
|
-
from donna.cli.types import ProtocolModeOption
|
|
4
|
-
from donna.
|
|
3
|
+
from donna.cli.types import ProtocolModeOption, RootOption
|
|
4
|
+
from donna.cli.utils import try_initialize_donna
|
|
5
|
+
from donna.protocol.modes import Mode
|
|
5
6
|
|
|
6
7
|
app = typer.Typer(help="Donna CLI: manage hierarchical state machines to guide your AI agents.")
|
|
7
8
|
|
|
8
9
|
|
|
9
10
|
@app.callback()
|
|
10
11
|
def initialize(
|
|
11
|
-
protocol: ProtocolModeOption =
|
|
12
|
+
protocol: ProtocolModeOption = Mode.human,
|
|
13
|
+
root_dir: RootOption = None,
|
|
12
14
|
) -> None:
|
|
13
|
-
|
|
14
|
-
typer.echo("Error: protocol is required. Examples: --protocol=llm or -p llm.", err=True)
|
|
15
|
-
raise typer.Exit(code=2)
|
|
16
|
-
|
|
17
|
-
set_mode(protocol)
|
|
15
|
+
try_initialize_donna(project_dir=root_dir, protocol=protocol)
|
donna/cli/commands/artifacts.py
CHANGED
|
@@ -12,7 +12,7 @@ from donna.cli.types import (
|
|
|
12
12
|
OutputPathOption,
|
|
13
13
|
TagOption,
|
|
14
14
|
)
|
|
15
|
-
from donna.cli.utils import cells_cli
|
|
15
|
+
from donna.cli.utils import cells_cli
|
|
16
16
|
from donna.core.errors import ErrorsList
|
|
17
17
|
from donna.core.result import Err, Ok, Result
|
|
18
18
|
from donna.domain.ids import FullArtifactIdPattern
|
|
@@ -38,16 +38,6 @@ def _parse_slug_with_extension(value: str) -> Result[tuple[str, str], ErrorsList
|
|
|
38
38
|
return Ok((slug, extension))
|
|
39
39
|
|
|
40
40
|
|
|
41
|
-
@artifacts_cli.callback(invoke_without_command=True)
|
|
42
|
-
def initialize(ctx: typer.Context) -> None:
|
|
43
|
-
cmd = ctx.invoked_subcommand
|
|
44
|
-
|
|
45
|
-
if cmd is None:
|
|
46
|
-
return
|
|
47
|
-
|
|
48
|
-
try_initialize_donna()
|
|
49
|
-
|
|
50
|
-
|
|
51
41
|
@artifacts_cli.command(
|
|
52
42
|
help="List artifacts matching a pattern and show their status summaries. Lists all all artifacts by default."
|
|
53
43
|
)
|
donna/cli/commands/sessions.py
CHANGED
|
@@ -4,23 +4,13 @@ import typer
|
|
|
4
4
|
|
|
5
5
|
from donna.cli.application import app
|
|
6
6
|
from donna.cli.types import ActionRequestIdArgument, FullArtifactIdArgument, FullArtifactSectionIdArgument
|
|
7
|
-
from donna.cli.utils import cells_cli
|
|
7
|
+
from donna.cli.utils import cells_cli
|
|
8
8
|
from donna.machine import sessions
|
|
9
9
|
from donna.protocol.cells import Cell
|
|
10
10
|
|
|
11
11
|
sessions_cli = typer.Typer()
|
|
12
12
|
|
|
13
13
|
|
|
14
|
-
@sessions_cli.callback(invoke_without_command=True)
|
|
15
|
-
def initialize(ctx: typer.Context) -> None:
|
|
16
|
-
cmd = ctx.invoked_subcommand
|
|
17
|
-
|
|
18
|
-
if cmd is None:
|
|
19
|
-
return
|
|
20
|
-
|
|
21
|
-
try_initialize_donna()
|
|
22
|
-
|
|
23
|
-
|
|
24
14
|
@sessions_cli.command(help="Start a new session, reset session state, remove all session artifacts.")
|
|
25
15
|
@cells_cli
|
|
26
16
|
def start() -> Iterable[Cell]:
|
donna/cli/commands/workspaces.py
CHANGED
|
@@ -4,32 +4,23 @@ from collections.abc import Iterable
|
|
|
4
4
|
import typer
|
|
5
5
|
|
|
6
6
|
from donna.cli.application import app
|
|
7
|
-
from donna.cli.
|
|
8
|
-
from donna.cli.utils import cells_cli, try_initialize_donna
|
|
7
|
+
from donna.cli.utils import cells_cli
|
|
9
8
|
from donna.protocol.cell_shortcuts import operation_succeeded
|
|
10
9
|
from donna.protocol.cells import Cell
|
|
10
|
+
from donna.workspaces import config as workspace_config
|
|
11
11
|
from donna.workspaces.initialization import initialize_workspace
|
|
12
12
|
|
|
13
13
|
workspaces_cli = typer.Typer()
|
|
14
14
|
|
|
15
15
|
|
|
16
|
-
@workspaces_cli.callback(invoke_without_command=True)
|
|
17
|
-
def initialize_callback(ctx: typer.Context) -> None:
|
|
18
|
-
cmd = ctx.invoked_subcommand
|
|
19
|
-
|
|
20
|
-
if cmd is None:
|
|
21
|
-
return
|
|
22
|
-
|
|
23
|
-
if cmd in {"init"}:
|
|
24
|
-
return
|
|
25
|
-
|
|
26
|
-
try_initialize_donna()
|
|
27
|
-
|
|
28
|
-
|
|
29
16
|
@workspaces_cli.command(help="Initialize Donna workspace.")
|
|
30
17
|
@cells_cli
|
|
31
|
-
def init(
|
|
32
|
-
|
|
18
|
+
def init() -> Iterable[Cell]:
|
|
19
|
+
if workspace_config.project_dir.is_set():
|
|
20
|
+
target_dir = workspace_config.project_dir()
|
|
21
|
+
else:
|
|
22
|
+
target_dir = pathlib.Path.cwd()
|
|
23
|
+
|
|
33
24
|
initialize_workspace(target_dir).unwrap()
|
|
34
25
|
|
|
35
26
|
return [operation_succeeded("Workspace initialized successfully")]
|
donna/cli/types.py
CHANGED
|
@@ -100,7 +100,7 @@ FullArtifactSectionIdArgument = Annotated[
|
|
|
100
100
|
|
|
101
101
|
|
|
102
102
|
ProtocolModeOption = Annotated[
|
|
103
|
-
Mode
|
|
103
|
+
Mode,
|
|
104
104
|
typer.Option(
|
|
105
105
|
"--protocol",
|
|
106
106
|
"-p",
|
|
@@ -110,6 +110,23 @@ ProtocolModeOption = Annotated[
|
|
|
110
110
|
]
|
|
111
111
|
|
|
112
112
|
|
|
113
|
+
RootOption = Annotated[
|
|
114
|
+
pathlib.Path | None,
|
|
115
|
+
typer.Option(
|
|
116
|
+
"--root",
|
|
117
|
+
"-r",
|
|
118
|
+
resolve_path=True,
|
|
119
|
+
file_okay=False,
|
|
120
|
+
dir_okay=True,
|
|
121
|
+
exists=True,
|
|
122
|
+
help=(
|
|
123
|
+
"Optional project root directory. "
|
|
124
|
+
"If omitted, Donna discovers it by searching parent directories for the workspace."
|
|
125
|
+
),
|
|
126
|
+
),
|
|
127
|
+
]
|
|
128
|
+
|
|
129
|
+
|
|
113
130
|
InputPathArgument = Annotated[
|
|
114
131
|
pathlib.Path,
|
|
115
132
|
typer.Argument(
|
donna/cli/utils.py
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import functools
|
|
2
|
+
import pathlib
|
|
2
3
|
import sys
|
|
3
4
|
from collections.abc import Iterable
|
|
4
5
|
from typing import Callable, ParamSpec
|
|
@@ -8,7 +9,8 @@ import typer
|
|
|
8
9
|
from donna.core.errors import EnvironmentError
|
|
9
10
|
from donna.core.result import UnwrapError
|
|
10
11
|
from donna.protocol.cells import Cell
|
|
11
|
-
from donna.protocol.modes import get_cell_formatter
|
|
12
|
+
from donna.protocol.modes import Mode, get_cell_formatter
|
|
13
|
+
from donna.workspaces import config as workspace_config
|
|
12
14
|
from donna.workspaces.initialization import initialize_runtime
|
|
13
15
|
|
|
14
16
|
|
|
@@ -42,12 +44,29 @@ def cells_cli(func: Callable[P, Iterable[Cell]]) -> Callable[P, None]:
|
|
|
42
44
|
return wrapper
|
|
43
45
|
|
|
44
46
|
|
|
45
|
-
def
|
|
46
|
-
|
|
47
|
+
def _is_workspace_init_command() -> bool:
|
|
48
|
+
args = sys.argv[1:]
|
|
49
|
+
if "workspaces" not in args:
|
|
50
|
+
return False
|
|
51
|
+
|
|
52
|
+
index = args.index("workspaces")
|
|
53
|
+
return len(args) > index + 1 and args[index + 1] == "init"
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def try_initialize_donna(project_dir: pathlib.Path | None, protocol: Mode) -> None:
|
|
57
|
+
if _is_workspace_init_command():
|
|
58
|
+
workspace_config.protocol.set(protocol)
|
|
59
|
+
if project_dir is not None:
|
|
60
|
+
workspace_config.project_dir.set(project_dir)
|
|
61
|
+
return
|
|
62
|
+
|
|
63
|
+
result = initialize_runtime(root_dir=project_dir, protocol=protocol)
|
|
47
64
|
|
|
48
65
|
if result.is_ok():
|
|
49
66
|
return
|
|
50
67
|
|
|
51
|
-
|
|
68
|
+
errors = result.unwrap_err()
|
|
69
|
+
|
|
70
|
+
output_cells([error.node().info() for error in errors])
|
|
52
71
|
|
|
53
72
|
raise typer.Exit(code=0)
|
|
@@ -7,7 +7,7 @@ from donna.core.errors import ErrorsList
|
|
|
7
7
|
from donna.core.result import Err, Ok, Result
|
|
8
8
|
from donna.domain.ids import FullArtifactSectionId
|
|
9
9
|
from donna.machine.templates import Directive, PreparedDirectiveResult
|
|
10
|
-
from donna.
|
|
10
|
+
from donna.workspaces import config as workspace_config
|
|
11
11
|
|
|
12
12
|
|
|
13
13
|
class EnvironmentError(core_errors.EnvironmentError):
|
|
@@ -37,8 +37,12 @@ class GoTo(Directive):
|
|
|
37
37
|
return Ok((next_operation_id,))
|
|
38
38
|
|
|
39
39
|
def render_view(self, context: Context, next_operation_id: FullArtifactSectionId) -> Result[Any, ErrorsList]:
|
|
40
|
-
protocol =
|
|
41
|
-
|
|
40
|
+
protocol = workspace_config.protocol().value
|
|
41
|
+
root_dir = workspace_config.project_dir()
|
|
42
|
+
return Ok(
|
|
43
|
+
f"donna -p {protocol} -r '{root_dir}' "
|
|
44
|
+
f"sessions action-request-completed <action-request-id> '{next_operation_id}'"
|
|
45
|
+
)
|
|
42
46
|
|
|
43
47
|
def render_analyze(self, context: Context, next_operation_id: FullArtifactSectionId) -> Result[Any, ErrorsList]:
|
|
44
48
|
return Ok(f"$$donna {self.analyze_id} {next_operation_id.local_id} donna$$")
|
|
@@ -7,7 +7,7 @@ from donna.core.errors import ErrorsList
|
|
|
7
7
|
from donna.core.result import Err, Ok, Result
|
|
8
8
|
from donna.domain.ids import FullArtifactIdPattern
|
|
9
9
|
from donna.machine.templates import Directive, PreparedDirectiveResult
|
|
10
|
-
from donna.
|
|
10
|
+
from donna.workspaces import config as workspace_config
|
|
11
11
|
|
|
12
12
|
|
|
13
13
|
class EnvironmentError(core_errors.EnvironmentError):
|
|
@@ -71,10 +71,14 @@ class List(Directive):
|
|
|
71
71
|
def render_view(
|
|
72
72
|
self, context: Context, artifact_pattern: FullArtifactIdPattern, tags: list[str]
|
|
73
73
|
) -> Result[Any, ErrorsList]:
|
|
74
|
-
protocol =
|
|
74
|
+
protocol = workspace_config.protocol().value
|
|
75
|
+
root_dir = workspace_config.project_dir()
|
|
75
76
|
tags_args = " ".join(f"--tag '{tag}'" for tag in tags)
|
|
76
77
|
tag_suffix = f" {tags_args}" if tags_args else ""
|
|
77
|
-
return Ok(
|
|
78
|
+
return Ok(
|
|
79
|
+
f"{artifact_pattern} (donna -p {protocol} -r '{root_dir}' "
|
|
80
|
+
f"artifacts list '{artifact_pattern}'{tag_suffix})"
|
|
81
|
+
)
|
|
78
82
|
|
|
79
83
|
def render_analyze(
|
|
80
84
|
self, context: Context, artifact_pattern: FullArtifactIdPattern, tags: list[str]
|
|
@@ -7,7 +7,7 @@ from donna.core.errors import ErrorsList
|
|
|
7
7
|
from donna.core.result import Err, Ok, Result
|
|
8
8
|
from donna.domain.ids import FullArtifactIdPattern
|
|
9
9
|
from donna.machine.templates import Directive, PreparedDirectiveResult
|
|
10
|
-
from donna.
|
|
10
|
+
from donna.workspaces import config as workspace_config
|
|
11
11
|
|
|
12
12
|
|
|
13
13
|
class EnvironmentError(core_errors.EnvironmentError):
|
|
@@ -71,10 +71,14 @@ class View(Directive):
|
|
|
71
71
|
def render_view(
|
|
72
72
|
self, context: Context, artifact_pattern: FullArtifactIdPattern, tags: list[str]
|
|
73
73
|
) -> Result[Any, ErrorsList]:
|
|
74
|
-
protocol =
|
|
74
|
+
protocol = workspace_config.protocol().value
|
|
75
|
+
root_dir = workspace_config.project_dir()
|
|
75
76
|
tags_args = " ".join(f"--tag '{tag}'" for tag in tags)
|
|
76
77
|
tag_suffix = f" {tags_args}" if tags_args else ""
|
|
77
|
-
return Ok(
|
|
78
|
+
return Ok(
|
|
79
|
+
f"{artifact_pattern} (donna -p {protocol} -r '{root_dir}' "
|
|
80
|
+
f"artifacts view '{artifact_pattern}'{tag_suffix})"
|
|
81
|
+
)
|
|
78
82
|
|
|
79
83
|
def render_analyze(
|
|
80
84
|
self, context: Context, artifact_pattern: FullArtifactIdPattern, tags: list[str]
|
donna/protocol/modes.py
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import enum
|
|
2
2
|
|
|
3
|
-
from donna.protocol.errors import
|
|
3
|
+
from donna.protocol.errors import UnsupportedFormatterMode
|
|
4
4
|
from donna.protocol.formatters.automation import Formatter as AutomationFormatter
|
|
5
5
|
from donna.protocol.formatters.base import Formatter
|
|
6
6
|
from donna.protocol.formatters.human import Formatter as HumanFormatter
|
|
7
7
|
from donna.protocol.formatters.llm import Formatter as LLMFormatter
|
|
8
|
+
from donna.workspaces.config import protocol as protocol_mode
|
|
8
9
|
|
|
9
10
|
|
|
10
11
|
class Mode(enum.StrEnum):
|
|
@@ -13,23 +14,8 @@ class Mode(enum.StrEnum):
|
|
|
13
14
|
automation = "automation"
|
|
14
15
|
|
|
15
16
|
|
|
16
|
-
_MODE: Mode | None = None
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
def set_mode(mode: Mode) -> None:
|
|
20
|
-
global _MODE
|
|
21
|
-
_MODE = mode
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
def mode() -> Mode:
|
|
25
|
-
if _MODE is None:
|
|
26
|
-
raise ModeNotSet()
|
|
27
|
-
|
|
28
|
-
return _MODE
|
|
29
|
-
|
|
30
|
-
|
|
31
17
|
def get_cell_formatter() -> Formatter:
|
|
32
|
-
match
|
|
18
|
+
match protocol_mode():
|
|
33
19
|
case Mode.human:
|
|
34
20
|
return HumanFormatter()
|
|
35
21
|
case Mode.llm:
|
|
@@ -37,4 +23,4 @@ def get_cell_formatter() -> Formatter:
|
|
|
37
23
|
case Mode.automation:
|
|
38
24
|
return AutomationFormatter()
|
|
39
25
|
case _:
|
|
40
|
-
raise UnsupportedFormatterMode(mode=
|
|
26
|
+
raise UnsupportedFormatterMode(mode=protocol_mode())
|
donna/workspaces/config.py
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
1
3
|
import pathlib
|
|
2
|
-
from typing import Any
|
|
4
|
+
from typing import TYPE_CHECKING, Any
|
|
3
5
|
|
|
4
6
|
import pydantic
|
|
5
7
|
|
|
@@ -14,6 +16,9 @@ from donna.workspaces.sources.base import SourceConstructor
|
|
|
14
16
|
from donna.workspaces.worlds.base import World as BaseWorld
|
|
15
17
|
from donna.workspaces.worlds.base import WorldConstructor
|
|
16
18
|
|
|
19
|
+
if TYPE_CHECKING:
|
|
20
|
+
from donna.protocol.modes import Mode
|
|
21
|
+
|
|
17
22
|
DONNA_DIR_NAME = ".donna"
|
|
18
23
|
DONNA_CONFIG_NAME = "config.toml"
|
|
19
24
|
DONNA_WORLD_SESSION_DIR_NAME = "session"
|
|
@@ -196,6 +201,9 @@ class GlobalConfig[V]():
|
|
|
196
201
|
|
|
197
202
|
return self._value
|
|
198
203
|
|
|
204
|
+
def is_set(self) -> bool:
|
|
205
|
+
return self._value is not None
|
|
206
|
+
|
|
199
207
|
def __call__(self) -> V:
|
|
200
208
|
return self.get()
|
|
201
209
|
|
|
@@ -203,3 +211,4 @@ class GlobalConfig[V]():
|
|
|
203
211
|
project_dir = GlobalConfig[pathlib.Path]()
|
|
204
212
|
config_dir = GlobalConfig[pathlib.Path]()
|
|
205
213
|
config = GlobalConfig[Config]()
|
|
214
|
+
protocol: GlobalConfig["Mode"] = GlobalConfig()
|
|
@@ -7,17 +7,29 @@ from donna.core import errors as core_errors
|
|
|
7
7
|
from donna.core import utils
|
|
8
8
|
from donna.core.result import Err, Ok, Result, unwrap_to_error
|
|
9
9
|
from donna.domain.ids import WorldId
|
|
10
|
+
from donna.protocol.modes import Mode
|
|
10
11
|
from donna.workspaces import config
|
|
11
12
|
from donna.workspaces import errors as world_errors
|
|
12
13
|
|
|
13
14
|
|
|
14
15
|
@unwrap_to_error
|
|
15
|
-
def initialize_runtime(
|
|
16
|
+
def initialize_runtime( # noqa: CCR001
|
|
17
|
+
root_dir: pathlib.Path | None = None,
|
|
18
|
+
protocol: Mode | None = None,
|
|
19
|
+
) -> Result[None, core_errors.ErrorsList]:
|
|
16
20
|
"""Initialize the runtime environment for the application.
|
|
17
21
|
|
|
18
22
|
This function MUST be called before any other operations.
|
|
19
23
|
"""
|
|
20
|
-
|
|
24
|
+
if protocol is not None:
|
|
25
|
+
config.protocol.set(protocol)
|
|
26
|
+
|
|
27
|
+
if root_dir is None:
|
|
28
|
+
project_dir = utils.discover_project_dir(config.DONNA_DIR_NAME).unwrap()
|
|
29
|
+
else:
|
|
30
|
+
project_dir = root_dir.resolve()
|
|
31
|
+
if not (project_dir / config.DONNA_DIR_NAME).is_dir():
|
|
32
|
+
return Err([core_errors.ProjectDirNotFound(donna_dir_name=config.DONNA_DIR_NAME)])
|
|
21
33
|
|
|
22
34
|
config.project_dir.set(project_dir)
|
|
23
35
|
|
|
@@ -55,7 +67,9 @@ def initialize_workspace(project_dir: pathlib.Path) -> Result[None, core_errors.
|
|
|
55
67
|
if workspace_dir.exists():
|
|
56
68
|
return Err([world_errors.WorkspaceAlreadyInitialized(project_dir=project_dir)])
|
|
57
69
|
|
|
58
|
-
config.project_dir.
|
|
70
|
+
if not config.project_dir.is_set():
|
|
71
|
+
config.project_dir.set(project_dir)
|
|
72
|
+
|
|
59
73
|
config.config_dir.set(workspace_dir)
|
|
60
74
|
|
|
61
75
|
workspace_dir.mkdir(parents=True, exist_ok=True)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: donna
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.4
|
|
4
4
|
Summary: Deterministic behavior, state machines, artifact management, and meta programming for your coding agent.
|
|
5
5
|
License-Expression: BSD-3-Clause
|
|
6
6
|
License-File: LICENSE
|
|
@@ -160,7 +160,7 @@ pip install donna
|
|
|
160
160
|
|
|
161
161
|
```bash
|
|
162
162
|
cd <your-project-root>
|
|
163
|
-
donna
|
|
163
|
+
donna workspaces init
|
|
164
164
|
```
|
|
165
165
|
|
|
166
166
|
Donna will create a `.donna/` folder in your project root with a default configuration in `.donna/config.toml`.
|
|
@@ -170,10 +170,12 @@ Donna will create a `.donna/` folder in your project root with a default configu
|
|
|
170
170
|
```markdown
|
|
171
171
|
**Use `donna` tool to work on this project.**
|
|
172
172
|
|
|
173
|
-
**ALWAYS** run `donna -p llm artifacts view '*:intro'` when you start working on the project.
|
|
173
|
+
**ALWAYS** run `donna -p llm -r <project-root> artifacts view '*:intro'` when you start working on the project.
|
|
174
174
|
It **MUST** be a one time operation. Do not repeat it unless you forget how to use the tool.
|
|
175
175
|
```
|
|
176
176
|
|
|
177
|
+
`-r <project-root>` is optional. If you run Donna from the project root or any subdirectory, it will discover the root automatically.
|
|
178
|
+
|
|
177
179
|
4. Ask your agent to do something like `Add a button that …`. The agent will discover the appropriate workflow and run it.
|
|
178
180
|
|
|
179
181
|
## Usage
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
donna/__init__.py,sha256=lEC7l3wDCBiC5gw56XkAeBW1XJA52pck7SFR1_CUals,41
|
|
2
2
|
donna/artifacts/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
3
|
-
donna/artifacts/intro.md,sha256=
|
|
3
|
+
donna/artifacts/intro.md,sha256=99mj_nHnj-UtwCg1IzktftG_euiBryJEy3NdGSQnh4U,2355
|
|
4
4
|
donna/artifacts/research/specs/report.md,sha256=r3D5Jb5hJNsGyh4hM2ewiKIopb7yHFD6f6MBxxwLG_Q,8598
|
|
5
5
|
donna/artifacts/research/work/research.md,sha256=Zyp4quC-7Dg7H1UeDixzo9z2Myj87FFlcpSMA4l8sl8,7081
|
|
6
6
|
donna/artifacts/rfc/specs/request_for_change.md,sha256=tEaowYtT-sRtPQ-LT1DJn5florLoZIHCt1_wUzJhQVE,13008
|
|
@@ -9,18 +9,18 @@ donna/artifacts/rfc/work/do.md,sha256=GOqjcozVv7Oubg9Zg79zD8fCqQMiEyla5EEQECSkNL
|
|
|
9
9
|
donna/artifacts/rfc/work/plan.md,sha256=xqWLf-7eRGdzVtaAFxdtlts3sZcdhtu_Q1nTYewwy5Q,2574
|
|
10
10
|
donna/artifacts/usage/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
11
11
|
donna/artifacts/usage/artifacts.md,sha256=BHo7yW2rd_TLTyvCGpnEBk86XkWHp1nt7uZvRlBVODc,13638
|
|
12
|
-
donna/artifacts/usage/cli.md,sha256=
|
|
12
|
+
donna/artifacts/usage/cli.md,sha256=ec6kgOR4ZSGJ31-PrpGdlMr9n-hk1Ar6UG19BNiHxzY,11402
|
|
13
13
|
donna/artifacts/usage/worlds.md,sha256=iA61-ZzS29NLxrdVQhdSF-2hpS6wGO1stlWkMkHnNDU,2078
|
|
14
14
|
donna/cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
15
15
|
donna/cli/__main__.py,sha256=_zo9JRR0m_ggVlrSaCpwo84bo0-cR9DgnJFup1AcH5U,224
|
|
16
|
-
donna/cli/application.py,sha256=
|
|
16
|
+
donna/cli/application.py,sha256=49JVonL0rZMpKXMYRM34RaU3ACQM8XNhfZFG73Kp81g,449
|
|
17
17
|
donna/cli/commands/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
18
|
-
donna/cli/commands/artifacts.py,sha256=
|
|
19
|
-
donna/cli/commands/sessions.py,sha256=
|
|
20
|
-
donna/cli/commands/workspaces.py,sha256=
|
|
18
|
+
donna/cli/commands/artifacts.py,sha256=pXh7_5JTqN9OX2E5X_8wQO4xIr0XyUo2LDInkuIUzvA,6198
|
|
19
|
+
donna/cli/commands/sessions.py,sha256=MaPH7u4IZhaRrIOV496SwJOZXJuFS7qPUKwS9CcksBo,1925
|
|
20
|
+
donna/cli/commands/workspaces.py,sha256=sv7UsxBhlcuzzgAyQhVjRKLkG6jtGw6OlMMv1XBoyY4,879
|
|
21
21
|
donna/cli/errors.py,sha256=9UzGo4tINr3EEwhOu361M7ulGS-bEe7wGgVivu07Z1o,524
|
|
22
|
-
donna/cli/types.py,sha256=
|
|
23
|
-
donna/cli/utils.py,sha256=
|
|
22
|
+
donna/cli/types.py,sha256=GuV-WzAnB_lQX_Rhc5omoKKHasIDpU7nK_KVdd-0oy8,4061
|
|
23
|
+
donna/cli/utils.py,sha256=TXDlqp8z9Pcru8QdNoQb8AaAY5LPCS5gp6tQzr-7mvM,2021
|
|
24
24
|
donna/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
25
25
|
donna/core/entities.py,sha256=Y3udcI1ykWDI_yPqCX6JTuDmF81BxO0PnnJzzD5uMoM,753
|
|
26
26
|
donna/core/errors.py,sha256=jkblzdC1bk0-E5eSGiiPSSIEHPbUbz88CXPvrHdLVuU,3313
|
|
@@ -48,10 +48,10 @@ donna/primitives/artifacts/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJ
|
|
|
48
48
|
donna/primitives/artifacts/specification.py,sha256=SYqRHJwfIvSVd0PTrrLG_Q0IdNy2mbdeK73Y1bt80_o,844
|
|
49
49
|
donna/primitives/artifacts/workflow.py,sha256=4u4Y9Le8ICKqWJR6qmC-flXKMers9Udm4vzKCHHLMME,7939
|
|
50
50
|
donna/primitives/directives/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
51
|
-
donna/primitives/directives/goto.py,sha256=
|
|
52
|
-
donna/primitives/directives/list.py,sha256=
|
|
51
|
+
donna/primitives/directives/goto.py,sha256=EBdjmsL6zqBzW7JyqYZlUo4mFPPmOezVRmAoxvvsMLc,1822
|
|
52
|
+
donna/primitives/directives/list.py,sha256=h9VgIWbB5kVUu6zh3DdAEcIsJvs1Px8dSHY1IL2sG1w,3341
|
|
53
53
|
donna/primitives/directives/task_variable.py,sha256=KvxY8ZOKFh6alkBhgDvkWzIJBfRNP4oYKRJ0SgHzO_g,2959
|
|
54
|
-
donna/primitives/directives/view.py,sha256
|
|
54
|
+
donna/primitives/directives/view.py,sha256=yoXAsSgETyVnt3xLqDLai_Gl24Y_277eX_9A5A5NmK8,3341
|
|
55
55
|
donna/primitives/operations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
56
56
|
donna/primitives/operations/finish_workflow.py,sha256=-3vaYAjj6oN93JWeQIoV9TOqzDjv-2ch_Wp4pXcOHvs,1846
|
|
57
57
|
donna/primitives/operations/output.py,sha256=P0eYKK7-dUMfalVqFySHVY57RylBhhG-t8_xcTEZ4xE,3316
|
|
@@ -66,15 +66,15 @@ donna/protocol/formatters/automation.py,sha256=I_I-b8bixuXBlKqn2ryHDKSdRJy77FzDA
|
|
|
66
66
|
donna/protocol/formatters/base.py,sha256=PGrAgxiEtZKyg1wPePQMt5syOr6IpC4ydh5rMElaojE,405
|
|
67
67
|
donna/protocol/formatters/human.py,sha256=WvoZVYlD4H3MftDkpEEP_RtyZnzJhUWKNecKgm3FoXg,1168
|
|
68
68
|
donna/protocol/formatters/llm.py,sha256=z_2djZFaVVHjLYFMneUrYp5sA-EvtPuHUDzGKV1ogu4,1266
|
|
69
|
-
donna/protocol/modes.py,sha256=
|
|
69
|
+
donna/protocol/modes.py,sha256=o7w6jTbfDEGnx2yGZn1992-09bTfgM6XGZYv42T6KoE,841
|
|
70
70
|
donna/protocol/nodes.py,sha256=aP5IVOouZe6akSdfzPpfcGuZLbxkEieTE6j6SuVuTUU,1974
|
|
71
71
|
donna/protocol/utils.py,sha256=GMiqGH2vawKu8_MmofWhCljI7AqoYDI0w19I-21t02g,663
|
|
72
72
|
donna/workspaces/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
73
73
|
donna/workspaces/artifacts.py,sha256=co6MBjIX2kV91WgNqCnDiK01hqUeB5cGPhE_ftJMl8U,8254
|
|
74
74
|
donna/workspaces/artifacts_discovery.py,sha256=JEf5ZVLaK2wwhx5mVE4ulOdmC2lApCdyfpfv2vBB_DE,2803
|
|
75
|
-
donna/workspaces/config.py,sha256=
|
|
75
|
+
donna/workspaces/config.py,sha256=AnX9DXU7NDKWk3yFgdn6ODZNQHMQTsL5In4kdVX8prs,6684
|
|
76
76
|
donna/workspaces/errors.py,sha256=ZK77AKjnRLc0-Qnu-NKztliSbCYBDmzr71fo1soWDrg,8276
|
|
77
|
-
donna/workspaces/initialization.py,sha256=
|
|
77
|
+
donna/workspaces/initialization.py,sha256=HygU7OwaoY5UP7QabyhkRljF-AYcCMvMhKjBkBkHaOM,2938
|
|
78
78
|
donna/workspaces/markdown.py,sha256=Aom9AnnpGHXI8LndmizwwG5r6aIFlosHjCvw-juL85Q,7214
|
|
79
79
|
donna/workspaces/sources/__init__.py,sha256=IRwKWnqQKh1ase742jhdadBcS4E9Hxr6j_l9Li6wwfw,70
|
|
80
80
|
donna/workspaces/sources/base.py,sha256=y6CawcOSBUX3oMO8YXlxE6p_NMJ713ukTZhgNKKBl94,2020
|
|
@@ -85,8 +85,8 @@ donna/workspaces/worlds/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG
|
|
|
85
85
|
donna/workspaces/worlds/base.py,sha256=mdmAT1WV5tYe-GnWlxeDXXzO1qT6Q4u0itpHZafc408,2590
|
|
86
86
|
donna/workspaces/worlds/filesystem.py,sha256=0zCQwM0RuPOJKm1EsODpgmL9NXk6z0fanJZMXfC79rI,7231
|
|
87
87
|
donna/workspaces/worlds/python.py,sha256=dRPS4jHIMRqdecCAmF7FuC6IwH3__nfWaf2cMSc7Txk,7223
|
|
88
|
-
donna-0.2.
|
|
89
|
-
donna-0.2.
|
|
90
|
-
donna-0.2.
|
|
91
|
-
donna-0.2.
|
|
92
|
-
donna-0.2.
|
|
88
|
+
donna-0.2.4.dist-info/METADATA,sha256=TC1sNJpnWoJE5GbECcwesWb8xemhIqFv9U3dGZ-oxy8,23738
|
|
89
|
+
donna-0.2.4.dist-info/WHEEL,sha256=kJCRJT_g0adfAJzTx2GUMmS80rTJIVHRCfG0DQgLq3o,88
|
|
90
|
+
donna-0.2.4.dist-info/entry_points.txt,sha256=r2W_yOzauooYCu312OQwCycIN1UjVnO5paPpS2EDZqo,48
|
|
91
|
+
donna-0.2.4.dist-info/licenses/LICENSE,sha256=KiF6_RVxH0MLeHZZtc8ag497X-c6oPmk-0OOf9qQDDk,1504
|
|
92
|
+
donna-0.2.4.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|