From f762210ff252a0e4de57b565cbdd6e7321c0ab07 Mon Sep 17 00:00:00 2001 From: "Aliaksei Yaletski (Tiendil)" Date: Wed, 13 May 2026 11:36:47 +0200 Subject: [PATCH] removing .donna directory --- .agents/donna/intro.donna.md | 2 +- .agents/donna/research/specs/report.donna.md | 2 +- .agents/donna/research/work/research.donna.md | 6 ++-- .agents/donna/rfc/specs/design.donna.md | 2 +- .../rfc/specs/request_for_change.donna.md | 2 +- .agents/donna/rfc/work/design.donna.md | 4 +-- .agents/donna/rfc/work/do.donna.md | 4 +-- .agents/donna/rfc/work/plan.donna.md | 4 +-- .agents/donna/rfc/work/request.donna.md | 4 +-- .agents/donna/usage/cli.donna.md | 25 +++++++------- .agents/donna/usage/worlds.donna.md | 6 ++-- .donna/config.toml | 2 -- README.md | 20 +++++------ donna.toml | 29 ++++++++++++++++ donna/cli/commands/artifacts.py | 2 +- donna/cli/commands/workspaces.py | 10 +++--- donna/cli/types.py | 4 +-- donna/core/errors.py | 8 ++--- donna/core/utils.py | 27 +++++++-------- donna/fixtures/specs/intro.donna.md | 2 +- .../specs/research/specs/report.donna.md | 2 +- .../specs/research/work/research.donna.md | 6 ++-- .../fixtures/specs/rfc/specs/design.donna.md | 2 +- .../rfc/specs/request_for_change.donna.md | 2 +- donna/fixtures/specs/rfc/work/design.donna.md | 4 +-- donna/fixtures/specs/rfc/work/do.donna.md | 4 +-- donna/fixtures/specs/rfc/work/plan.donna.md | 4 +-- .../fixtures/specs/rfc/work/request.donna.md | 4 +-- donna/skills/fixtures/artifacts.md | 8 ++--- donna/skills/fixtures/configuration.md | 30 ++++++++++++----- donna/skills/fixtures/initialization.md | 23 +++++++------ donna/skills/fixtures/usage.md | 28 ++++++++-------- donna/workspaces/artifacts.py | 8 ----- donna/workspaces/config.py | 24 +++++++------- donna/workspaces/errors.py | 12 +++---- donna/workspaces/initialization.py | 33 ++++++++----------- donna/workspaces/sessions.py | 4 +-- specs/core/top_level_architecture.donna.md | 6 ++-- specs/intro.donna.md | 6 ++-- specs/work/log_changes.donna.md | 2 +- 40 files changed, 200 insertions(+), 177 deletions(-) delete mode 100644 .donna/config.toml create mode 100644 donna.toml diff --git a/.agents/donna/intro.donna.md b/.agents/donna/intro.donna.md index 0eb043c4..8a34945d 100644 --- a/.agents/donna/intro.donna.md +++ b/.agents/donna/intro.donna.md @@ -41,7 +41,7 @@ Artifact type tags: Donna creates internal journal records for important workflow events, according to the description in `{{ donna.lib.view("./usage/cli.donna.md") }}`. -Journal records can be forwarded to a third-party tool by configuring `[journal].cmd` in `/.donna/config.toml`. +Journal records can be forwarded to a third-party tool by configuring `[journal].cmd` in `/donna.toml`. The configured command is a list of command arguments. Arguments whose first and last characters are `{` and `}` are replaced with attributes of `JournalRecord`. diff --git a/.agents/donna/research/specs/report.donna.md b/.agents/donna/research/specs/report.donna.md index 08f4ab68..59358fa2 100644 --- a/.agents/donna/research/specs/report.donna.md +++ b/.agents/donna/research/specs/report.donna.md @@ -10,7 +10,7 @@ This document describes the format and structure of a Research Report document u Donna introduces a group of workflows located in `../**` namespace that organize the process of researching a problem, collecting information, analyzing it, synthesizing options, and producing a final solution. -Session-related research artifacts MUST be stored as `@/.donna/session/research/.donna.md`, unless the developer or parent workflow specifies a different location. The `` MUST be unique within the session. +Session-related research artifacts MUST be stored as `@/.session/donna/research/.donna.md`, unless the developer or parent workflow specifies a different location. The `` MUST be unique within the session. The agent (via workflows) creates the artifact and updates it iteratively as the research process progresses. diff --git a/.agents/donna/research/work/research.donna.md b/.agents/donna/research/work/research.donna.md index a211f5eb..79b42f92 100644 --- a/.agents/donna/research/work/research.donna.md +++ b/.agents/donna/research/work/research.donna.md @@ -34,7 +34,7 @@ kind = "donna.lib.request_action" At this point, you SHOULD have a clear description of the problem in your context. I.e., you know what you need to do in this workflow. 1. If you have a problem description in your context, `{{ donna.lib.goto("prepare_artifact") }}`. -2. If you have no problem description in your context, but you know it is in one of `@/.donna/session/**` artifacts, find and view it. Then `{{ donna.lib.goto("prepare_artifact") }}`. +2. If you have no problem description in your context, but you know it is in one of `@/.session/donna/**` artifacts, find and view it. Then `{{ donna.lib.goto("prepare_artifact") }}`. 3. If you have no problem description in your context, and you don't know where it is, ask the developer to provide it. After you get the problem description, `{{ donna.lib.goto("prepare_artifact") }}`. ## Prepare research artifact @@ -44,8 +44,8 @@ id = "prepare_artifact" kind = "donna.lib.request_action" ``` -1. Based on the problem description you have, suggest an artifact name in the format `@/.donna/session/research/.donna.md`. `` MUST be unique within the session. -{# TODO: we can add donna.lib.list('@/.donna/session/**') here as the command to list all session artifacts #} +1. Based on the problem description you have, suggest an artifact name in the format `@/.session/donna/research/.donna.md`. `` MUST be unique within the session. +{# TODO: we can add donna.lib.list('@/.session/donna/**') here as the command to list all session artifacts #} 2. Create the artifact and specify an original problem description in it. 3. `{{ donna.lib.goto("formalize_research") }}` diff --git a/.agents/donna/rfc/specs/design.donna.md b/.agents/donna/rfc/specs/design.donna.md index 3a9d3b2b..e5e7f19c 100644 --- a/.agents/donna/rfc/specs/design.donna.md +++ b/.agents/donna/rfc/specs/design.donna.md @@ -12,7 +12,7 @@ Donna introduces a group of workflows located in `../**` namespace that organize You create a Design document to explicitly describe the exact changes you want to make to the project in order to implement the RFC. -If not otherwise specified, Design documents for the session MUST be stored as `@/.donna/session/design/.donna.md` artifacts under `/.donna/session`. +If not otherwise specified, Design documents for the session MUST be stored as `@/.session/donna/design/.donna.md` artifacts under `/.session/donna`. **The Design document MUST list exact changes to the project that will be implemented.** E.g. concrete function names and signatures, file paths, data structures, etc. diff --git a/.agents/donna/rfc/specs/request_for_change.donna.md b/.agents/donna/rfc/specs/request_for_change.donna.md index ecace694..b5e1e92f 100644 --- a/.agents/donna/rfc/specs/request_for_change.donna.md +++ b/.agents/donna/rfc/specs/request_for_change.donna.md @@ -12,7 +12,7 @@ Donna introduces a group of workflows located in `../**` namespace that organize You create RFC documents to propose changes to the project. -If not otherwise specified, RFC documents for the session MUST be stored as `@/.donna/session/rfc/.donna.md` artifacts under `/.donna/session`. +If not otherwise specified, RFC documents for the session MUST be stored as `@/.session/donna/rfc/.donna.md` artifacts under `/.session/donna`. ## RFC structure diff --git a/.agents/donna/rfc/work/design.donna.md b/.agents/donna/rfc/work/design.donna.md index 18b8bfeb..db356d55 100644 --- a/.agents/donna/rfc/work/design.donna.md +++ b/.agents/donna/rfc/work/design.donna.md @@ -29,7 +29,7 @@ kind = "donna.lib.request_action" At this point, you SHOULD have a clear RFC to design. 1. If you have an RFC artifact id in your context, view it and `{{ donna.lib.goto("prepare_design_artifact") }}`. -2. If you have no RFC artifact id in your context, but you know it is in one of `{{ donna.lib.list("@/.donna/session/**") }}` artifacts, find and view it. Then `{{ donna.lib.goto("prepare_design_artifact") }}`. +2. If you have no RFC artifact id in your context, but you know it is in one of `{{ donna.lib.list("@/.session/donna/**") }}` artifacts, find and view it. Then `{{ donna.lib.goto("prepare_design_artifact") }}`. 3. If you have no RFC artifact id in your context, and you don't know where it is, ask the developer to provide the RFC artifact id or to create a new RFC. After you get it and view the artifact, `{{ donna.lib.goto("prepare_design_artifact") }}`. ## Prepare Design artifact @@ -39,7 +39,7 @@ id = "prepare_design_artifact" kind = "donna.lib.request_action" ``` -1. If the name of the artifact is not specified explicitly, assume it to be `@/.donna/session/design/.donna.md`, where `` SHOULD correspond to the RFC slug. +1. If the name of the artifact is not specified explicitly, assume it to be `@/.session/donna/design/.donna.md`, where `` SHOULD correspond to the RFC slug. 2. Save the next template into the artifact, replace `` with appropriate values. ~~~ diff --git a/.agents/donna/rfc/work/do.donna.md b/.agents/donna/rfc/work/do.donna.md index 1af618a3..b97cf0ff 100644 --- a/.agents/donna/rfc/work/do.donna.md +++ b/.agents/donna/rfc/work/do.donna.md @@ -76,7 +76,7 @@ kind = "donna.lib.request_action" 1. Choose the workflow to plan the work. If you created a Design document in the previous step, use it as a basis. 2. Run the chosen workflow. -3. Ensure you know the workflow id created in the previous step (default is `@/.donna/session/execute_rfc.donna.md` if not specified). +3. Ensure you know the workflow id created in the previous step (default is `@/.session/donna/execute_rfc.donna.md` if not specified). 4. After completing the workflow `{{ donna.lib.goto("execute_rfc_work") }}`. ## Execute RFC work @@ -86,7 +86,7 @@ id = "execute_rfc_work" kind = "donna.lib.request_action" ``` -1. Run the workflow created by the plan step (default: `@/.donna/session/execute_rfc.donna.md`) and complete it. +1. Run the workflow created by the plan step (default: `@/.session/donna/execute_rfc.donna.md`) and complete it. 2. After completing the workflow `{{ donna.lib.goto("polish_changes") }}`. ## Polish changes diff --git a/.agents/donna/rfc/work/plan.donna.md b/.agents/donna/rfc/work/plan.donna.md index d620889f..20044c33 100644 --- a/.agents/donna/rfc/work/plan.donna.md +++ b/.agents/donna/rfc/work/plan.donna.md @@ -6,7 +6,7 @@ kind = "donna.lib.workflow" start_operation_id = "start" ``` -This workflow plans the work required to implement a specified Design document. The RFC document SHOULD be used as a helper context. The result of this workflow is a new workflow stored as a `@/.donna/session/**` artifact under `/.donna/session` with detailed steps to implement the designed changes. +This workflow plans the work required to implement a specified Design document. The RFC document SHOULD be used as a helper context. The result of this workflow is a new workflow stored as a `@/.session/donna/**` artifact under `/.session/donna` with detailed steps to implement the designed changes. ## Start Work @@ -28,7 +28,7 @@ id = "prepare_workflow_artifact" kind = "donna.lib.request_action" ``` -1. If the name of the artifact is not specified explicitly, assume it to `@/.donna/session/plans/.donna.md`. +1. If the name of the artifact is not specified explicitly, assume it to `@/.session/donna/plans/.donna.md`. 2. Create a workflow with the next operations: - Start - A step for each action point in the RFC document and each item in the `Order of implementation` in Design document with the goal to minimize dependencies between steps and introduce changes incrementally. diff --git a/.agents/donna/rfc/work/request.donna.md b/.agents/donna/rfc/work/request.donna.md index f66d58a3..b5f2a0f1 100644 --- a/.agents/donna/rfc/work/request.donna.md +++ b/.agents/donna/rfc/work/request.donna.md @@ -30,7 +30,7 @@ kind = "donna.lib.request_action" At this point, you SHOULD have a clear description of the problem in your context. I.e. you know what you need to do in this workflow. 1. If you have a problem description in your context, `{{ donna.lib.goto("prepare_rfc_artifact") }}`. -2. If you have no problem description in your context, but you know it is in one of `{{ donna.lib.list("@/.donna/session/**") }}` artifacts, find and view it. Then `{{ donna.lib.goto("prepare_rfc_artifact") }}`. +2. If you have no problem description in your context, but you know it is in one of `{{ donna.lib.list("@/.session/donna/**") }}` artifacts, find and view it. Then `{{ donna.lib.goto("prepare_rfc_artifact") }}`. 3. If you have no problem description in your context, and you don't know where it is, ask the developer to provide it. After you get the problem description, `{{ donna.lib.goto("prepare_rfc_artifact") }}`. ## Prepare RFC artifact @@ -40,7 +40,7 @@ id = "prepare_rfc_artifact" kind = "donna.lib.request_action" ``` -1. If the name of the artifact is not specified explicitly, assume it to be `@/.donna/session/rfc/.donna.md`, where `` MUST be unique within the session. +1. If the name of the artifact is not specified explicitly, assume it to be `@/.session/donna/rfc/.donna.md`, where `` MUST be unique within the session. 2. Save the next template into the artifact, replace `` with appropriate values. ~~~ diff --git a/.agents/donna/usage/cli.donna.md b/.agents/donna/usage/cli.donna.md index 2b7ffc8f..d1527174 100644 --- a/.agents/donna/usage/cli.donna.md +++ b/.agents/donna/usage/cli.donna.md @@ -41,7 +41,7 @@ When an agent invokes Donna, it SHOULD use the `llm` protocol (pass an `-p llm` ### Project root `-r ` sets the project root explicitly for any command (long form: `--root`). -If it is omitted, Donna discovers the project root by searching from the current working directory upwards for the `.donna` workspace directory. +If it is omitted, Donna discovers the project root by searching from the current working directory upwards for `donna.toml`. Use this option when you run Donna from outside the project tree or when you want to target a specific project. ### Protocol cells @@ -72,7 +72,7 @@ Donna renders cells differently, depending on the protocol used. There are three sets of commands: -- `donna -p workspaces …` — manages workspaces. Most-likely it will be used once per your project to initialize it. +- `donna -p workspaces …` — initializes and refreshes Donna project files. Most likely it will be used once per project. - `donna -p sessions …` — manages sessions. You will use these commands to start, push forward, and manage your work. - `donna -p artifacts …` — manages artifact discovery, reading, and validation. @@ -83,9 +83,9 @@ Use: ### Workspaces -Run `donna -p workspaces init []` to initialize Donna workspace in the given directory. If `` is omitted, Donna will initialize workspace in the current working directory. +Run `donna -p workspaces init []` to initialize Donna in the given directory. If `` is omitted, Donna will initialize the current working directory. -It is a one time operation you need to perform once per project to create a place where Donna will store all its data. +It is a one time operation you need to perform once per project to create `donna.toml`, the configured session directory, and synced Donna fixtures. ### Starting sessions @@ -107,7 +107,7 @@ After the session starts you MUST follow the next workflow to perform your work: 3. Start chosen workflow by calling `donna -p sessions run `. 4. Donna will output descriptions of all operations it performs to complete the work. 5. Donna will output **action requests** that you MUST perform. You MUST follow these instructions precisely. -6. When you done processing an action request, call `donna -p sessions action-request-completed ` to report request completion. `` MUST contain the full identifier of the next operation, for example `@/.donna/session/execute_rfc.donna.md:review_changes`. +6. When you done processing an action request, call `donna -p sessions action-request-completed ` to report request completion. `` MUST contain the full identifier of the next operation, for example `@/.session/donna/execute_rfc.donna.md:review_changes`. 7. After you complete an action request, Donna will continue workflow execution and output what you need to do next. You MUST continue following Donna's instructions until the workflow is completed. @@ -136,15 +136,15 @@ If Donna tells you there is no work left, you MUST inform the developer that the ### Working with artifacts -An artifact is a markdown document with extra metadata stored in the project workspace. +An artifact is a markdown document with extra metadata stored in the Donna project. Use the next commands to work with artifacts: -- `donna -p artifacts list []` — list all artifacts corresponding to the given pattern. If `` is omitted, list all artifacts in the project workspace. Use this command when you need to find an artifact or see what artifacts are available. +- `donna -p artifacts list []` — list all artifacts corresponding to the given pattern. If `` is omitted, list all artifacts in the Donna project. Use this command when you need to find an artifact or see what artifacts are available. - `donna -p artifacts view ` — get the meaningful (rendered) content of all matching artifacts. This command shows the rendered information about each artifact. Use this command when you need to read artifact content. -- `donna -p artifacts validate []` — validate all artifacts corresponding to the given pattern. If `` is omitted, validate all artifacts in the project workspace. +- `donna -p artifacts validate []` — validate all artifacts corresponding to the given pattern. If `` is omitted, validate all artifacts in the Donna project. -Donna does not mutate artifacts stored in the project workspace. Developers and external tools are responsible for creating, updating, moving, copying, or deleting artifacts before Donna reads or validates them. +Donna does not mutate artifacts stored in the project. Developers and external tools are responsible for creating, updating, moving, copying, or deleting artifacts before Donna reads or validates them. Commands that accept an artifact pattern (`artifacts list`, `artifacts view`, `artifacts validate`) also accept `--predicate/-p ` to filter by artifact primary section. The expression is evaluated as `bool` with `section` global available (for example: `--predicate '"workflow" in section.tags'`). @@ -155,9 +155,9 @@ The format of `` is as follows: - `*/intro.donna.md` — matches all artifacts with filename `intro.donna.md` exactly one directory below the project root. - `@/*/intro.donna.md` — equivalent full form. - `**` — double wildcard matches multiple levels in the rooted artifact path. Examples: - - `**/name.donna.md` — matches all artifacts with filename `name.donna.md` anywhere in the project workspace. + - `**/name.donna.md` — matches all artifacts with filename `name.donna.md` anywhere in the Donna project. - `@/**/intro.donna.md` — equivalent full form. - - `@/.donna/**` — matches all artifacts under `.donna`. + - `@/.session/donna/**` — matches all artifacts under the default configured session directory. CLI arguments MUST NOT use relative artifact paths like `./...` or `../../...`; use absolute `@/...` paths or rooted wildcard forms. @@ -166,8 +166,7 @@ CLI arguments MUST NOT use relative artifact paths like `./...` or `../../...`; Donna creates internal `JournalRecord` values for important workflow events. Donna does not expose a journal CLI command. -To forward journal records to a third-party tool, configure the workspace -`/.donna/config.toml` file: +To forward journal records to a third-party tool, configure `/donna.toml`: ```toml [journal] diff --git a/.agents/donna/usage/worlds.donna.md b/.agents/donna/usage/worlds.donna.md index 09ec4d56..2e4a93b8 100644 --- a/.agents/donna/usage/worlds.donna.md +++ b/.agents/donna/usage/worlds.donna.md @@ -17,13 +17,13 @@ formats can be used as well, if explicitly requested by the developer or by the Donna discovers these artifacts in a single built-in project world rooted at ``. The project world is a singleton object configured in code and backed by the project's filesystem. -Donna does not read world definitions from `/.donna/config.toml`. +Donna does not read world definitions from `/donna.toml`. The project world and its primary artifact areas are: - `../../../specs/**` — artifacts under `/specs`, owned by the project itself. - `../**` — synced Donna usage specs and workflows under `/.agents/donna`. -- `@/.donna/session/**` — session artifacts under `/.donna/session`. +- `@/.session/donna/**` — session artifacts under `/.session/donna`. The project world has a free layout, defined by the developers who own the project. @@ -33,7 +33,7 @@ Donna has read access to artifacts stored in the project world. It discovers, fe Developers and external tools are responsible for mutating project artifacts before Donna reads or validates them. -Donna still writes its own session state under `/.donna/session`, but that internal state storage is separate from world-artifact mutation. +Donna still writes its own session state under `/.session/donna`, but that internal state storage is separate from world-artifact mutation. ## Intro Artifacts diff --git a/.donna/config.toml b/.donna/config.toml deleted file mode 100644 index 19086356..00000000 --- a/.donna/config.toml +++ /dev/null @@ -1,2 +0,0 @@ -[journal] -cmd = ["./bin/taskwarior.sh", "log", "+journal", "+donna", "kind:event", "{message}"] diff --git a/README.md b/README.md index 75cad7a3..0b58edfb 100644 --- a/README.md +++ b/README.md @@ -142,7 +142,7 @@ donna workspaces init Donna will: -- Create a `.donna/` folder in your project root with a default configuration in `.donna/config.toml`. +- Create `donna.toml` in your project root and the configured session directory. - Sync bundled Donna specs into `.agents/donna/`. - Install skills into `.agents/skills/` folder. @@ -166,7 +166,7 @@ Commands you may need: - `donna sessions start` — start a new working session, remove everything from the previous session. - `donna artifacts list ` — list artifacts with short descriptions. -Donna can send internal journal records to a third-party tool. Configure it in `.donna/config.toml`: +Donna can send internal journal records to a third-party tool. Configure it in `donna.toml`: ```toml [journal] @@ -194,7 +194,7 @@ You find detailed documentation in the built-in skill documents — they are rea - `donna skill usage` — full list of commands and how to use them. - `donna skill artifacts` — what Donna artifacts are and how to use them on the filesystem. -- `donna skill configuration` — how to configure `.donna/config.toml`. +- `donna skill configuration` — how to configure `donna.toml`. - `donna skill initialization` — how to initialize or refresh a Donna workspace. The documentation below covers aspects important to humans and partially duplicates the agent's instructions. @@ -229,13 +229,13 @@ Points of interest: ## Artifacts on Filesystem - Artifacts are text files Donna reads and validates. In practice they are usually Markdown workflows and specifications stored as `.donna.md` files. -- Donna discovers artifacts directly in the project filesystem and limits what is visible via `.donna/config.toml:file_filters`. +- Donna discovers artifacts directly in the project filesystem and limits what is visible via `donna.toml:file_filters`. By default, Donna uses these artifact areas: - `specs/` — project-owned artifacts. - `.agents/donna/` — bundled Donna specs and workflows synced by `donna workspaces init` or `donna workspaces update`. -- `.donna/session/` — session artifacts and Donna runtime state. +- `.session/donna/` — session artifacts and Donna runtime state. ### Rendering @@ -251,7 +251,7 @@ Examples: - `@/specs/work/polish.donna.md` - `@/.agents/donna/work/polish.donna.md` -- `@/.donna/session/execute_rfc.donna.md:review_changes` +- `@/.session/donna/execute_rfc.donna.md:review_changes` You and agents can `list`, `view`, and `validate` artifacts. @@ -272,7 +272,7 @@ Examples: - `@/*.donna.md` — matches all artifacts directly under the project root. - `@/**/intro.donna.md` — matches all artifacts named `intro.donna.md`. -- `@/.donna/session/**` — matches all session artifacts. +- `@/.session/donna/**` — matches all session artifacts. - `**/test_*.donna.md` — matches artifact filenames that start with `test_`. Commands that accept an artifact pattern also support `--predicate ''` to filter by primary section properties available as `section`. @@ -287,7 +287,7 @@ You can find all workflows with the command ## Sessions -`/.donna/session/` contains the current state of work performed by Donna: runtime state plus temporary documents and workflows created during the session. +`/.session/donna/` contains the current state of work performed by Donna: runtime state plus temporary documents and workflows created during the session. The developer is responsible for starting/resetting sessions with commands from `donna -p human sessions` group. @@ -308,7 +308,7 @@ To execute a workflow, Donna uses a simplified virtual machine (VM) that maintai
What you may want to know about workflows implementation -- `.donna/session/state.json` file contains the current state of all running workflows in the current session. +- `.session/donna/state.json` file contains the current state of all running workflows in the current session. - Each workflow executes in the context of its own task, which is a distant analog of a call stack frame. So, we may look at workflows as functions. - Of course, workflows may call other workflows as subroutines. At any moment, only last executed workflow is active. - Task has a context that is accessible by operations. There is an issue [command to read/write task context](https://github.com/Tiendil/donna/issues/47) to allow agents and humans to edit task context. @@ -420,7 +420,7 @@ What you can implement: - Custom rendering directives. Check [./donna/primitives/directives](./donna/primitives/directives) subpackage for examples. - Custom artifact parsers. Check [./donna/workspaces/sources](./donna/workspaces/sources) subpackage for examples. -Sources and file filters are configured in the `.donna/config.toml` file of your project. +Sources and file filters are configured in the `donna.toml` file of your project. Sections and directives are used directly in artifacts by their Python import paths. diff --git a/donna.toml b/donna.toml new file mode 100644 index 00000000..582172e4 --- /dev/null +++ b/donna.toml @@ -0,0 +1,29 @@ +session = ".session/donna" +cache_lifetime = 1.0 + +[[sources]] +kind = "donna.lib.sources.markdown" +extension = ".donna.md" + +[[file_filters]] +mode = "include" +pattern = "@/.session/donna/**/*.donna.md" + +[[file_filters]] +mode = "include" +pattern = "@/.agents/**/*.donna.md" + +[[file_filters]] +mode = "ignore" +pattern = ".*/**" + +[[file_filters]] +mode = "include" +pattern = "**/*.donna.md" + +[[file_filters]] +mode = "ignore" +pattern = "**" + +[journal] +cmd = ["./bin/taskwarior.sh", "log", "+journal", "+donna", "kind:event", "{message}"] diff --git a/donna/cli/commands/artifacts.py b/donna/cli/commands/artifacts.py index a3853a50..559e4bad 100644 --- a/donna/cli/commands/artifacts.py +++ b/donna/cli/commands/artifacts.py @@ -99,5 +99,5 @@ def validate( app.add_typer( artifacts_cli, name="artifacts", - help="Inspect and validate stored artifacts in the project workspace.", + help="Inspect and validate stored artifacts in the Donna project.", ) diff --git a/donna/cli/commands/workspaces.py b/donna/cli/commands/workspaces.py index 278c717e..07bf515d 100644 --- a/donna/cli/commands/workspaces.py +++ b/donna/cli/commands/workspaces.py @@ -9,28 +9,28 @@ workspaces_cli = typer.Typer() -@workspaces_cli.command(help="Initialize Donna workspace.") +@workspaces_cli.command(help="Initialize Donna project config.") def init(context: typer.Context, skills: SkillsOption = True, specs: SpecsOption = True) -> None: with command_context(context, load_environment=False) as command: target_dir = command.target_dir() initialize_workspace(target_dir, install_skills=skills, install_specs=specs).unwrap() - command.write_cells([operation_succeeded("Workspace initialized successfully")]) + command.write_cells([operation_succeeded("Donna project initialized successfully")]) -@workspaces_cli.command(help="Update Donna workspace files.") +@workspaces_cli.command(help="Update Donna project files.") def update(context: typer.Context, skills: SkillsOption = True, specs: SpecsOption = True) -> None: with command_context(context) as command: target_dir = command.target_dir() update_workspace(target_dir, install_skills=skills, install_specs=specs).unwrap() - command.write_cells([operation_succeeded("Workspace updated successfully")]) + command.write_cells([operation_succeeded("Donna project updated successfully")]) app.add_typer( workspaces_cli, name="workspaces", - help="Initialize and manage Donna workspace.", + help="Initialize and manage Donna project files.", ) diff --git a/donna/cli/types.py b/donna/cli/types.py index 855c57af..1e040d0d 100644 --- a/donna/cli/types.py +++ b/donna/cli/types.py @@ -211,7 +211,7 @@ def _parse_input_path(value: str) -> pathlib.Path: parser=_parse_artifact_section_id, help=( "Artifact section ID in absolute project-root form 'artifact:section' " - "(e.g. '@/.donna/session/plans/artifact_id_filepaths.donna.md:finish')." + "(e.g. '@/.session/donna/plans/artifact_id_filepaths.donna.md:finish')." ), ), ] @@ -239,7 +239,7 @@ def _parse_input_path(value: str) -> pathlib.Path: exists=True, help=( "Optional project root directory. " - "If omitted, Donna discovers it by searching parent directories for the workspace." + "If omitted, Donna discovers it by searching parent directories for donna.toml." ), ), ] diff --git a/donna/core/errors.py b/donna/core/errors.py index 667e5a18..0f42938c 100644 --- a/donna/core/errors.py +++ b/donna/core/errors.py @@ -50,12 +50,12 @@ class CoreEnvironmentError(EnvironmentError): class ProjectDirNotFound(CoreEnvironmentError): code: str = "donna.core.project_dir_not_found" - message: str = "Could not find a project directory containing `{error.donna_dir_name}`." + message: str = "Could not find a project directory containing `{error.config_name}`." ways_to_fix: list[str] = [ - "Run Donna from within a project directory that contains the donna directory.", - "Create the donna workspace via CLI command if it does not exist yet.", + "Run Donna from within a project directory that contains the Donna config file.", + "Create the Donna project config via CLI command if it does not exist yet.", ] - donna_dir_name: str + config_name: str class EnvironmentErrorNode(Node): diff --git a/donna/core/utils.py b/donna/core/utils.py index d76800d8..60001fa9 100644 --- a/donna/core/utils.py +++ b/donna/core/utils.py @@ -9,31 +9,26 @@ def now() -> datetime.datetime: return datetime.datetime.now(datetime.UTC) -def first_donna_dir(donna_dir_name: str) -> pathlib.Path | None: - """Get the first parent directory containing the donna directory. +def first_project_dir_with_config(config_name: str) -> pathlib.Path | None: + """Get the first parent directory containing the Donna config file. - Search from the current working directory upwards for a folder with donna directory (.donna by default). + Search from the current working directory upwards for a folder with Donna config. """ current_dir = pathlib.Path.cwd().resolve() for parent in [current_dir] + list(current_dir.parents): - donna_path = parent / donna_dir_name - if donna_path.is_dir(): + config_path = parent / config_name + if config_path.is_file(): return parent return None -def donna_home_dir(donna_dir_name: str) -> pathlib.Path: - """Get the donna home directory in the user's home folder.""" - return pathlib.Path.home() / donna_dir_name +def discover_project_dir(config_name: str) -> Result[pathlib.Path, core_errors.ErrorsList]: + """Discover the project directory by looking for the Donna config file in parent folders.""" + project_dir = first_project_dir_with_config(config_name) + if project_dir is None: + return Err([core_errors.ProjectDirNotFound(config_name=config_name)]) -def discover_project_dir(donna_dir_name: str) -> Result[pathlib.Path, core_errors.ErrorsList]: - """Discover the project directory by looking for the donna directory in parent folders.""" - donna_dir = first_donna_dir(donna_dir_name) - - if donna_dir is None: - return Err([core_errors.ProjectDirNotFound(donna_dir_name=donna_dir_name)]) - - return Ok(donna_dir) + return Ok(project_dir) diff --git a/donna/fixtures/specs/intro.donna.md b/donna/fixtures/specs/intro.donna.md index 2bc3aab6..ede43a66 100644 --- a/donna/fixtures/specs/intro.donna.md +++ b/donna/fixtures/specs/intro.donna.md @@ -41,7 +41,7 @@ Artifact type tags: Donna creates internal journal records for important workflow events, according to the description in `donna skill usage`. -Journal records can be forwarded to a third-party tool by configuring `[journal].cmd` in `/.donna/config.toml`. +Journal records can be forwarded to a third-party tool by configuring `[journal].cmd` in `/donna.toml`. The configured command is a list of command arguments. Arguments whose first and last characters are `{` and `}` are replaced with attributes of `JournalRecord`. diff --git a/donna/fixtures/specs/research/specs/report.donna.md b/donna/fixtures/specs/research/specs/report.donna.md index 8e469176..94f6b9e1 100644 --- a/donna/fixtures/specs/research/specs/report.donna.md +++ b/donna/fixtures/specs/research/specs/report.donna.md @@ -10,7 +10,7 @@ This document describes the format and structure of a Research Report document u Donna introduces a group of workflows located in `../**` namespace that organize the process of researching a problem, collecting information, analyzing it, synthesizing options, and producing a final solution. -Session-related research artifacts MUST be stored as `@/.donna/session/research/.donna.md`, unless the developer or parent workflow specifies a different location. The `` MUST be unique within the session. +Session-related research artifacts MUST be stored as `@/.session/donna/research/.donna.md`, unless the developer or parent workflow specifies a different location. The `` MUST be unique within the session. The agent (via workflows) creates the artifact and updates it iteratively as the research process progresses. diff --git a/donna/fixtures/specs/research/work/research.donna.md b/donna/fixtures/specs/research/work/research.donna.md index 694f4fe8..a2f9c181 100644 --- a/donna/fixtures/specs/research/work/research.donna.md +++ b/donna/fixtures/specs/research/work/research.donna.md @@ -34,7 +34,7 @@ kind = "donna.lib.request_action" At this point, you SHOULD have a clear description of the problem in your context. I.e., you know what you need to do in this workflow. 1. If you have a problem description in your context, `{{ donna.lib.goto("prepare_artifact") }}`. -2. If you have no problem description in your context, but you know it is in one of `@/.donna/session/**` artifacts, find and view it. Then `{{ donna.lib.goto("prepare_artifact") }}`. +2. If you have no problem description in your context, but you know it is in one of `@/.session/donna/**` artifacts, find and view it. Then `{{ donna.lib.goto("prepare_artifact") }}`. 3. If you have no problem description in your context, and you don't know where it is, ask the developer to provide it. After you get the problem description, `{{ donna.lib.goto("prepare_artifact") }}`. ## Prepare research artifact @@ -44,8 +44,8 @@ id = "prepare_artifact" kind = "donna.lib.request_action" ``` -1. Based on the problem description you have, suggest an artifact name in the format `@/.donna/session/research/.donna.md`. `` MUST be unique within the session. -{# TODO: we can add donna.lib.list('@/.donna/session/**') here as the command to list all session artifacts #} +1. Based on the problem description you have, suggest an artifact name in the format `@/.session/donna/research/.donna.md`. `` MUST be unique within the session. +{# TODO: we can add donna.lib.list('@/.session/donna/**') here as the command to list all session artifacts #} 2. Create the artifact and specify an original problem description in it. 3. `{{ donna.lib.goto("formalize_research") }}` diff --git a/donna/fixtures/specs/rfc/specs/design.donna.md b/donna/fixtures/specs/rfc/specs/design.donna.md index 4f9169e8..71237d1b 100644 --- a/donna/fixtures/specs/rfc/specs/design.donna.md +++ b/donna/fixtures/specs/rfc/specs/design.donna.md @@ -12,7 +12,7 @@ Donna introduces a group of workflows located in `../**` namespace that organize You create a Design document to explicitly describe the exact changes you want to make to the project in order to implement the RFC. -If not otherwise specified, Design documents for the session MUST be stored as `@/.donna/session/design/.donna.md` artifacts under `/.donna/session`. +If not otherwise specified, Design documents for the session MUST be stored as `@/.session/donna/design/.donna.md` artifacts under `/.session/donna`. **The Design document MUST list exact changes to the project that will be implemented.** E.g. concrete function names and signatures, file paths, data structures, etc. diff --git a/donna/fixtures/specs/rfc/specs/request_for_change.donna.md b/donna/fixtures/specs/rfc/specs/request_for_change.donna.md index 8f135d49..7d85548d 100644 --- a/donna/fixtures/specs/rfc/specs/request_for_change.donna.md +++ b/donna/fixtures/specs/rfc/specs/request_for_change.donna.md @@ -12,7 +12,7 @@ Donna introduces a group of workflows located in `../**` namespace that organize You create RFC documents to propose changes to the project. -If not otherwise specified, RFC documents for the session MUST be stored as `@/.donna/session/rfc/.donna.md` artifacts under `/.donna/session`. +If not otherwise specified, RFC documents for the session MUST be stored as `@/.session/donna/rfc/.donna.md` artifacts under `/.session/donna`. ## RFC structure diff --git a/donna/fixtures/specs/rfc/work/design.donna.md b/donna/fixtures/specs/rfc/work/design.donna.md index 8eecf84c..d4c5cbcc 100644 --- a/donna/fixtures/specs/rfc/work/design.donna.md +++ b/donna/fixtures/specs/rfc/work/design.donna.md @@ -29,7 +29,7 @@ kind = "donna.lib.request_action" At this point, you SHOULD have a clear RFC to design. 1. If you have an RFC artifact id in your context, view it and `{{ donna.lib.goto("prepare_design_artifact") }}`. -2. If you have no RFC artifact id in your context, but you know it is in one of `{{ donna.lib.list("@/.donna/session/**") }}` artifacts, find and view it. Then `{{ donna.lib.goto("prepare_design_artifact") }}`. +2. If you have no RFC artifact id in your context, but you know it is in one of `{{ donna.lib.list("@/.session/donna/**") }}` artifacts, find and view it. Then `{{ donna.lib.goto("prepare_design_artifact") }}`. 3. If you have no RFC artifact id in your context, and you don't know where it is, ask the developer to provide the RFC artifact id or to create a new RFC. After you get it and view the artifact, `{{ donna.lib.goto("prepare_design_artifact") }}`. ## Prepare Design artifact @@ -39,7 +39,7 @@ id = "prepare_design_artifact" kind = "donna.lib.request_action" ``` -1. If the name of the artifact is not specified explicitly, assume it to be `@/.donna/session/design/.donna.md`, where `` SHOULD correspond to the RFC slug. +1. If the name of the artifact is not specified explicitly, assume it to be `@/.session/donna/design/.donna.md`, where `` SHOULD correspond to the RFC slug. 2. Save the next template into the artifact, replace `` with appropriate values. ~~~ diff --git a/donna/fixtures/specs/rfc/work/do.donna.md b/donna/fixtures/specs/rfc/work/do.donna.md index 1af618a3..b97cf0ff 100644 --- a/donna/fixtures/specs/rfc/work/do.donna.md +++ b/donna/fixtures/specs/rfc/work/do.donna.md @@ -76,7 +76,7 @@ kind = "donna.lib.request_action" 1. Choose the workflow to plan the work. If you created a Design document in the previous step, use it as a basis. 2. Run the chosen workflow. -3. Ensure you know the workflow id created in the previous step (default is `@/.donna/session/execute_rfc.donna.md` if not specified). +3. Ensure you know the workflow id created in the previous step (default is `@/.session/donna/execute_rfc.donna.md` if not specified). 4. After completing the workflow `{{ donna.lib.goto("execute_rfc_work") }}`. ## Execute RFC work @@ -86,7 +86,7 @@ id = "execute_rfc_work" kind = "donna.lib.request_action" ``` -1. Run the workflow created by the plan step (default: `@/.donna/session/execute_rfc.donna.md`) and complete it. +1. Run the workflow created by the plan step (default: `@/.session/donna/execute_rfc.donna.md`) and complete it. 2. After completing the workflow `{{ donna.lib.goto("polish_changes") }}`. ## Polish changes diff --git a/donna/fixtures/specs/rfc/work/plan.donna.md b/donna/fixtures/specs/rfc/work/plan.donna.md index b640db26..19a6017f 100644 --- a/donna/fixtures/specs/rfc/work/plan.donna.md +++ b/donna/fixtures/specs/rfc/work/plan.donna.md @@ -6,7 +6,7 @@ kind = "donna.lib.workflow" start_operation_id = "start" ``` -This workflow plans the work required to implement a specified Design document. The RFC document SHOULD be used as a helper context. The result of this workflow is a new workflow stored as a `@/.donna/session/**` artifact under `/.donna/session` with detailed steps to implement the designed changes. +This workflow plans the work required to implement a specified Design document. The RFC document SHOULD be used as a helper context. The result of this workflow is a new workflow stored as a `@/.session/donna/**` artifact under `/.session/donna` with detailed steps to implement the designed changes. ## Start Work @@ -28,7 +28,7 @@ id = "prepare_workflow_artifact" kind = "donna.lib.request_action" ``` -1. If the name of the artifact is not specified explicitly, assume it to `@/.donna/session/plans/.donna.md`. +1. If the name of the artifact is not specified explicitly, assume it to `@/.session/donna/plans/.donna.md`. 2. Create a workflow with the next operations: - Start - A step for each action point in the RFC document and each item in the `Order of implementation` in Design document with the goal to minimize dependencies between steps and introduce changes incrementally. diff --git a/donna/fixtures/specs/rfc/work/request.donna.md b/donna/fixtures/specs/rfc/work/request.donna.md index 2eefefc1..e31a5532 100644 --- a/donna/fixtures/specs/rfc/work/request.donna.md +++ b/donna/fixtures/specs/rfc/work/request.donna.md @@ -30,7 +30,7 @@ kind = "donna.lib.request_action" At this point, you SHOULD have a clear description of the problem in your context. I.e. you know what you need to do in this workflow. 1. If you have a problem description in your context, `{{ donna.lib.goto("prepare_rfc_artifact") }}`. -2. If you have no problem description in your context, but you know it is in one of `{{ donna.lib.list("@/.donna/session/**") }}` artifacts, find and view it. Then `{{ donna.lib.goto("prepare_rfc_artifact") }}`. +2. If you have no problem description in your context, but you know it is in one of `{{ donna.lib.list("@/.session/donna/**") }}` artifacts, find and view it. Then `{{ donna.lib.goto("prepare_rfc_artifact") }}`. 3. If you have no problem description in your context, and you don't know where it is, ask the developer to provide it. After you get the problem description, `{{ donna.lib.goto("prepare_rfc_artifact") }}`. ## Prepare RFC artifact @@ -40,7 +40,7 @@ id = "prepare_rfc_artifact" kind = "donna.lib.request_action" ``` -1. If the name of the artifact is not specified explicitly, assume it to be `@/.donna/session/rfc/.donna.md`, where `` MUST be unique within the session. +1. If the name of the artifact is not specified explicitly, assume it to be `@/.session/donna/rfc/.donna.md`, where `` MUST be unique within the session. 2. Save the next template into the artifact, replace `` with appropriate values. ~~~ diff --git a/donna/skills/fixtures/artifacts.md b/donna/skills/fixtures/artifacts.md index 9030f2b0..fe6c1437 100644 --- a/donna/skills/fixtures/artifacts.md +++ b/donna/skills/fixtures/artifacts.md @@ -10,17 +10,17 @@ The common artifact areas are: - `/specs`: project-owned specifications and workflows. - `/.agents/donna`: synced built-in Donna specs and workflows. -- `/.donna/session`: session artifacts and active workflow state. +- `/.session/donna`: session artifacts and active workflow state. Example: ```text specs/intro.donna.md .agents/donna/work/polish.donna.md -.donna/session/current_task.donna.md +.session/donna/current_task.donna.md ``` -Donna sees only files allowed by `.donna/config.toml:file_filters`. +Donna sees only files allowed by `donna.toml:file_filters`. ## List Artifacts @@ -93,7 +93,7 @@ Pattern examples: - `@/*.donna.md`: Donna Markdown artifacts directly under the project root. - `@/**/intro.donna.md`: any introduction artifact. - `@/.agents/donna/**`: synced Donna artifacts. -- `@/.donna/session/**`: session artifacts. +- `@/.session/donna/**`: session artifacts. Do not pass relative filesystem paths such as `./specs/intro.donna.md`. Use `@/specs/intro.donna.md`. diff --git a/donna/skills/fixtures/configuration.md b/donna/skills/fixtures/configuration.md index 954ce088..f73d73ac 100644 --- a/donna/skills/fixtures/configuration.md +++ b/donna/skills/fixtures/configuration.md @@ -1,25 +1,28 @@ # `donna` Configuration -Donna workspace configuration lives at: +Donna project configuration lives at: ```text -/.donna/config.toml +/donna.toml ``` The file is created by `donna -p llm workspaces init`. Edit it when the project needs custom artifact sources, artifact visibility rules, cache behavior, or journal forwarding. ## Minimal Configuration -A default workspace can use the generated configuration without manual edits. The effective defaults are: +A default project can use the generated configuration without manual edits. The effective defaults are: ```toml +session = ".session/donna" +cache_lifetime = 1.0 + [[sources]] kind = "donna.lib.sources.markdown" extension = ".donna.md" [[file_filters]] mode = "include" -pattern = "@/.donna/session/**/*.donna.md" +pattern = "@/.session/donna/**/*.donna.md" [[file_filters]] mode = "include" @@ -38,10 +41,21 @@ mode = "ignore" pattern = "**" [journal] +``` -cache_lifetime = 1.0 +## Session Directory + +`session` points to Donna's temporary session directory. +Donna stores runtime state, action requests, and session-created artifacts there. + +Default: + +```toml +session = ".session/donna" ``` +Relative paths are resolved from the project root; absolute paths are used as configured. Use a directory ignored by version control unless a project intentionally tracks session artifacts. + ## Sources `sources` tell Donna how to load artifacts with specific filename extensions. @@ -144,7 +158,7 @@ cmd = [ ## Cache Lifetime -`cache_lifetime` controls how long Donna may reuse cached workspace data, in seconds. +`cache_lifetime` controls how long Donna may reuse cached project data, in seconds. Example: @@ -156,11 +170,11 @@ Use a smaller value when artifacts are edited rapidly by external tools. Use the ## Validation Workflow -After editing `.donna/config.toml`, run: +After editing `donna.toml`, run: ```bash donna -p llm artifacts list '**' donna -p llm artifacts validate '**' ``` -If Donna cannot load the workspace, inspect the reported configuration error and fix the TOML or unsupported source path before continuing workflow work. +If Donna cannot load the project config, inspect the reported configuration error and fix the TOML or unsupported source path before continuing workflow work. diff --git a/donna/skills/fixtures/initialization.md b/donna/skills/fixtures/initialization.md index dad1f8b6..58e99631 100644 --- a/donna/skills/fixtures/initialization.md +++ b/donna/skills/fixtures/initialization.md @@ -1,22 +1,21 @@ # `donna` Initialization -Initialization creates the Donna workspace and optionally installs built-in Donna skills and specs into the project. +Initialization creates the Donna project config and optionally installs built-in Donna skills and specs into the project. -Use this document when a project has no `.donna` directory, when built-in Donna fixtures are missing, or when synced fixture files need to be refreshed. +Use this document when a project has no `donna.toml`, when built-in Donna fixtures are missing, or when synced fixture files need to be refreshed. ## What Initialization Creates `donna -p llm workspaces init` creates: ```text -/.donna/ -/.donna/config.toml -/.donna/session/ +/donna.toml +/.session/donna/ /.agents/skills/ /.agents/donna/ ``` -The `.donna` directory stores configuration and session state. The `.agents/skills` and `.agents/donna` directories contain built-in agent-facing Donna skills, workflows, and specifications. +`donna.toml` stores configuration. The configured session directory stores Donna runtime state and session artifacts. The `.agents/skills` and `.agents/donna` directories contain built-in agent-facing Donna skills, workflows, and specifications. ## Initialize The Current Directory @@ -26,7 +25,7 @@ Run from the directory that should become the project root: donna -p llm workspaces init ``` -This command fails if `.donna` already exists. +This command fails if `donna.toml` already exists. ## Initialize Another Directory @@ -36,7 +35,7 @@ Pass an explicit root directory: donna -p llm --root /path/to/project workspaces init ``` -The target directory must already exist. Donna creates `.donna` inside it. +The target directory must already exist. Donna creates `donna.toml` and the configured session directory inside it. ## Install Only Part Of The Fixtures @@ -56,7 +55,7 @@ Use these options only when the project deliberately manages those files another ## Refresh Existing Fixtures -Use `update`, not `init`, for an existing workspace: +Use `update`, not `init`, for an existing Donna project: ```bash donna -p llm workspaces update @@ -74,11 +73,11 @@ Refresh only synced Donna specs and workflows: donna -p llm workspaces update --no-skills ``` -`update` requires an existing `.donna` directory. +`update` requires an existing `donna.toml`. ## First Checks After Initialization -Verify the workspace can load: +Verify the project config can load: ```bash donna -p llm sessions status @@ -104,6 +103,6 @@ donna -p llm artifacts validate '**' ## Agent Guidance -Initialize a workspace only when the developer asks for it or when the task explicitly requires Donna and no workspace exists. +Initialize Donna only when the developer asks for it or when the task explicitly requires Donna and no `donna.toml` exists. Do not overwrite project-owned workflows or specifications by hand. Use `workspaces update` for built-in fixtures, and edit project-owned artifacts directly when the developer asks for project-specific behavior changes. diff --git a/donna/skills/fixtures/usage.md b/donna/skills/fixtures/usage.md index 81db9254..00951617 100644 --- a/donna/skills/fixtures/usage.md +++ b/donna/skills/fixtures/usage.md @@ -4,14 +4,14 @@ Donna is a CLI tool for orchestrating AI-agent work with project-local workflows Use this document as the first reference for command usage. For narrower topics, use: -- `donna skill configuration` for `.donna/config.toml`. -- `donna skill initialization` for creating or refreshing Donna workspace files. +- `donna skill configuration` for `donna.toml`. +- `donna skill initialization` for creating or refreshing Donna project files. - `donna skill artifacts` for artifact layout, discovery, and authoring rules. - `donna skill usage` for this command overview. ## Project Root -Donna works inside a project root. If `--root/-r` is omitted, commands that load a workspace discover the project root by searching upward from the current directory for `.donna`. +Donna works inside a project root. If `--root/-r` is omitted, commands that load a project discover the project root by searching upward from the current directory for `donna.toml`. Use `--root PATH` when running Donna from outside the project tree or when targeting a specific project: @@ -19,7 +19,7 @@ Use `--root PATH` when running Donna from outside the project tree or when targe donna -p llm --root /path/to/project sessions status ``` -`donna skill ...` does not load a workspace and can run from any directory. +`donna skill ...` does not load a project config and can run from any directory. ## Output Protocols @@ -43,7 +43,7 @@ donna -p llm --root /path/to/project artifacts list '**' ## Skill Documents -The `skill` command prints built-in agent documentation as plain Markdown. It does not require an initialized workspace. +The `skill` command prints built-in agent documentation as plain Markdown. It does not require an initialized Donna project. Examples: @@ -54,25 +54,25 @@ donna skill initialization donna skill artifacts ``` -Use these documents when an agent needs stable instructions before a workspace exists or when synced artifacts are not available. +Use these documents when an agent needs stable instructions before `donna.toml` exists or when synced artifacts are not available. -## Workspace Commands +## Project Commands -Workspace commands create or refresh Donna-owned files. +Workspace commands create or refresh Donna-owned project files. -Initialize a workspace in the current directory: +Initialize Donna in the current directory: ```bash donna -p llm workspaces init ``` -Initialize a workspace in an explicit existing directory: +Initialize Donna in an explicit existing directory: ```bash donna -p llm --root /path/to/project workspaces init ``` -Refresh synced Donna skills and specifications in an existing workspace: +Refresh synced Donna skills and specifications in an existing Donna project: ```bash donna -p llm workspaces update @@ -87,7 +87,7 @@ donna -p llm workspaces update --no-skills ## Session Commands -All workflow execution happens in the active session. Session state lives under `/.donna/session`. +All workflow execution happens in the active session. Session state lives under the configured session directory, `.session/donna` by default. Start a new session: @@ -124,7 +124,7 @@ donna -p llm sessions run @/.agents/donna/work/polish.donna.md Complete an action request by passing its id and the next operation id exactly as Donna instructed: ```bash -donna -p llm sessions action-request-completed AR-12-x @/.donna/session/workflow.donna.md:next_step +donna -p llm sessions action-request-completed AR-12-x @/.session/donna/workflow.donna.md:next_step ``` ## Artifact Commands @@ -188,7 +188,7 @@ donna -p llm sessions run @/.agents/donna/work/polish.donna.md ## Journal Forwarding -Donna creates internal journal records for workflow events. To forward them to another tool, configure `[journal].cmd` in `/.donna/config.toml`. +Donna creates internal journal records for workflow events. To forward them to another tool, configure `[journal].cmd` in `/donna.toml`. Example: diff --git a/donna/workspaces/artifacts.py b/donna/workspaces/artifacts.py index 95565857..10599a9a 100644 --- a/donna/workspaces/artifacts.py +++ b/donna/workspaces/artifacts.py @@ -37,11 +37,6 @@ def render(self, artifact_id: ArtifactId, render_context: ArtifactRenderContext) return Ok(render_artifact_from_source(artifact_id, self.source_id, self.get_bytes(), render_context).unwrap()) -def _should_skip_directory(parts: list[str], name: str) -> bool: - # `.donna/tmp` contains scratch files and must not be treated as durable artifacts. - return parts == [".donna"] and name == "tmp" - - def _match_supported_extension(path: pathlib.Path, supported_extensions: set[str]) -> str | None: name = path.name.lower() @@ -122,9 +117,6 @@ def walk_filesystem(filters: list["workspace_config.FileFilter"]) -> Iterator[pa def walk(node: pathlib.Path, parts: list[str]) -> Iterator[pathlib.Path]: # noqa: CCR001 for entry in sorted(node.iterdir(), key=lambda item: item.name): if entry.is_dir(): - if _should_skip_directory(parts, entry.name): - continue - next_parts = parts + [entry.name] if not _required_filters_match_prefix(next_parts, filters): continue diff --git a/donna/workspaces/config.py b/donna/workspaces/config.py index 84311184..4d19c540 100644 --- a/donna/workspaces/config.py +++ b/donna/workspaces/config.py @@ -19,9 +19,8 @@ if TYPE_CHECKING: from donna.protocol.modes import Mode -DONNA_DIR_NAME = ".donna" -DONNA_CONFIG_NAME = "config.toml" -DONNA_WORLD_SESSION_DIR_NAME = "session" +DONNA_CONFIG_NAME = "donna.toml" +DONNA_DEFAULT_SESSION_DIR = pathlib.Path(".session") / "donna" class SourceConfig(BaseEntity): @@ -98,9 +97,6 @@ def _default_sources() -> list[SourceConfig]: def _default_file_filters() -> list[FileFilter]: return [ - FileFilter( - mode=FileFilterMode.include, pattern=ArtifactIdPattern.parse("@/.donna/session/**/*.donna.md").unwrap() - ), FileFilter(mode=FileFilterMode.include, pattern=ArtifactIdPattern.parse("@/.agents/**/*.donna.md").unwrap()), FileFilter(mode=FileFilterMode.ignore, pattern=ArtifactIdPattern.parse(".*/**").unwrap()), FileFilter(mode=FileFilterMode.include, pattern=ArtifactIdPattern.parse("**/*.donna.md").unwrap()), @@ -109,6 +105,7 @@ def _default_file_filters() -> list[FileFilter]: class Config(BaseEntity): + session: pathlib.Path = DONNA_DEFAULT_SESSION_DIR sources: list[SourceConfig] = pydantic.Field(default_factory=_default_sources) file_filters: list[FileFilter] = pydantic.Field(default_factory=_default_file_filters) journal: JournalConfig = pydantic.Field(default_factory=JournalConfig) @@ -133,6 +130,16 @@ def model_post_init(self, __context: Any) -> None: # noqa: CCR001 sources.append(primitive.construct_source(source_config)) object.__setattr__(self, "_sources_instances", sources) + session_filter = FileFilter(mode=FileFilterMode.include, pattern=self.session_artifact_pattern()) + if session_filter not in self.file_filters: + object.__setattr__(self, "file_filters", [session_filter, *self.file_filters]) + + def session_artifact_pattern(self) -> ArtifactIdPattern: + session_path = self.session.as_posix().strip("/") + if session_path in {"", "."}: + return ArtifactIdPattern.parse("@/**/*.donna.md").unwrap() + + return ArtifactIdPattern.parse(f"@/{session_path}/**/*.donna.md").unwrap() @property def sources_instances(self) -> list[SourceConfigValue]: @@ -172,7 +179,6 @@ class Workspace(BaseEntity): model_config = pydantic.ConfigDict(arbitrary_types_allowed=True) root: pydantic.DirectoryPath - config_dir: pydantic.DirectoryPath config: Config @@ -202,7 +208,6 @@ def __call__(self) -> V: project_dir = GlobalConfig[pathlib.Path]() -config_dir = GlobalConfig[pathlib.Path]() config = GlobalConfig[Config]() protocol: GlobalConfig["Mode"] = GlobalConfig() @@ -211,8 +216,5 @@ def install_workspace(workspace: Workspace) -> None: if not project_dir.is_set(): project_dir.set(pathlib.Path(workspace.root)) - if not config_dir.is_set(): - config_dir.set(pathlib.Path(workspace.config_dir)) - if not config.is_set(): config.set(workspace.config) diff --git a/donna/workspaces/errors.py b/donna/workspaces/errors.py index 7fa78c48..7cf7cf16 100644 --- a/donna/workspaces/errors.py +++ b/donna/workspaces/errors.py @@ -17,7 +17,7 @@ class WorkspaceConfigError(WorkspaceError): config_path: pathlib.Path def content_intro(self) -> str: - return f"Error in workspace config file '{self.config_path}'" + return f"Error in Donna config file '{self.config_path}'" class ConfigParseFailed(WorkspaceConfigError): @@ -34,13 +34,13 @@ class ConfigValidationFailed(WorkspaceConfigError): class WorkspaceAlreadyInitialized(WorkspaceError): code: str = "donna.workspaces.workspace_already_initialized" - message: str = "Workspace already initialized at `{error.project_dir}`" + message: str = "Donna project config already exists at `{error.config_path}`" ways_to_fix: list[str] = [ - "Continue using the existing workspace.", - "Remove the existing `.donna` directory if you want to reinitialize.", + "Continue using the existing project config.", + "Remove the existing `donna.toml` file if you want to reinitialize.", "Choose a different project directory.", ] - project_dir: pathlib.Path + config_path: pathlib.Path class JournalCommandConfigInvalid(WorkspaceError): @@ -92,7 +92,7 @@ class ArtifactNotFound(ArtifactError): message: str = "Artifact `{error.artifact_id}` does not exist" ways_to_fix: list[str] = [ "Check the artifact id for typos.", - "Ensure the artifact exists in the project workspace.", + "Ensure the artifact exists in the Donna project.", ] diff --git a/donna/workspaces/initialization.py b/donna/workspaces/initialization.py index 26649431..daf741a7 100644 --- a/donna/workspaces/initialization.py +++ b/donna/workspaces/initialization.py @@ -53,18 +53,16 @@ def _sync_donna_specs(project_dir: pathlib.Path) -> None: def load_workspace(root_dir: pathlib.Path | None = None) -> Result[config.Workspace, core_errors.ErrorsList]: """Load workspace configuration without mutating process-global state.""" if root_dir is None: - project_dir = utils.discover_project_dir(config.DONNA_DIR_NAME).unwrap() + project_dir = utils.discover_project_dir(config.DONNA_CONFIG_NAME).unwrap() else: project_dir = root_dir.resolve() - if not (project_dir / config.DONNA_DIR_NAME).is_dir(): - return Err([core_errors.ProjectDirNotFound(donna_dir_name=config.DONNA_DIR_NAME)]) + if not (project_dir / config.DONNA_CONFIG_NAME).is_file(): + return Err([core_errors.ProjectDirNotFound(config_name=config.DONNA_CONFIG_NAME)]) - config_dir = project_dir / config.DONNA_DIR_NAME - - config_path = config_dir / config.DONNA_CONFIG_NAME + config_path = project_dir / config.DONNA_CONFIG_NAME if not config_path.exists(): - return Ok(config.Workspace(root=project_dir, config_dir=config_dir, config=config.Config())) + return Ok(config.Workspace(root=project_dir, config=config.Config())) try: data = tomllib.loads(config_path.read_text(encoding="utf-8")) @@ -76,7 +74,7 @@ def load_workspace(root_dir: pathlib.Path | None = None) -> Result[config.Worksp except Exception as e: return Err([world_errors.ConfigValidationFailed(config_path=config_path, details=str(e))]) - return Ok(config.Workspace(root=project_dir, config_dir=config_dir, config=loaded_config)) + return Ok(config.Workspace(root=project_dir, config=loaded_config)) @unwrap_to_error @@ -103,20 +101,17 @@ def initialize_workspace( install_skills: bool = True, install_specs: bool = True, ) -> Result[config.Workspace, core_errors.ErrorsList]: - """Initialize the physical workspace for the project (`.donna` directory).""" + """Initialize Donna project configuration.""" project_dir = project_dir.resolve() - workspace_dir = project_dir / config.DONNA_DIR_NAME - - if workspace_dir.exists(): - return Err([world_errors.WorkspaceAlreadyInitialized(project_dir=project_dir)]) + config_path = project_dir / config.DONNA_CONFIG_NAME - workspace_dir.mkdir(parents=True, exist_ok=True) + if config_path.exists(): + return Err([world_errors.WorkspaceAlreadyInitialized(config_path=config_path)]) default_config = config.Config() - workspace = config.Workspace(root=project_dir, config_dir=workspace_dir, config=default_config) + workspace = config.Workspace(root=project_dir, config=default_config) config.install_workspace(workspace) - config_path = workspace_dir / config.DONNA_CONFIG_NAME config_path.write_text( tomli_w.dumps(default_config.model_dump(mode="json", exclude_none=True)), encoding="utf-8", @@ -140,10 +135,10 @@ def update_workspace( install_specs: bool = True, ) -> Result[None, core_errors.ErrorsList]: project_dir = project_dir.resolve() - workspace_dir = project_dir / config.DONNA_DIR_NAME + config_path = project_dir / config.DONNA_CONFIG_NAME - if not workspace_dir.exists(): - return Err([core_errors.ProjectDirNotFound(donna_dir_name=config.DONNA_DIR_NAME)]) + if not config_path.exists(): + return Err([core_errors.ProjectDirNotFound(config_name=config.DONNA_CONFIG_NAME)]) if install_skills: _sync_donna_skill(project_dir) diff --git a/donna/workspaces/sessions.py b/donna/workspaces/sessions.py index c36b855b..75d43f58 100644 --- a/donna/workspaces/sessions.py +++ b/donna/workspaces/sessions.py @@ -1,11 +1,11 @@ import pathlib import shutil -from donna.workspaces.config import DONNA_DIR_NAME, DONNA_WORLD_SESSION_DIR_NAME, project_dir +from donna.workspaces.config import config, project_dir def dir() -> pathlib.Path: - return project_dir() / DONNA_DIR_NAME / DONNA_WORLD_SESSION_DIR_NAME + return project_dir() / config().session def ensure_dir() -> None: diff --git a/specs/core/top_level_architecture.donna.md b/specs/core/top_level_architecture.donna.md index 15a8f512..f2aa3609 100644 --- a/specs/core/top_level_architecture.donna.md +++ b/specs/core/top_level_architecture.donna.md @@ -21,13 +21,13 @@ The code is separated by layers/subsystems into subpackages: - `donna.domain` — code that is required by all Donna'specific logic: ID classes, common types, etc. - `donna.machine` — code that implements the core Donna's logic — how Donna works regardless of external environments, i.e. pure domain behavior. - `donna.context` — code that stores and provides execution-scoped runtime context for Donna's domain logic: artifact/state/primitive caches and scoped values like current actor/work unit/operation identifiers. -- `donna.workspaces` — code that integrates Donna with the project workspace and filesystem: runtime configuration, artifact discovery/loading, session storage, source parsing, and workspace initialization. +- `donna.workspaces` — code that integrates Donna with the project root and filesystem: runtime configuration, artifact discovery/loading, session storage, source parsing, and project initialization. - `donna.protocol` — code that implements protocol via which Donna's core domain logic interacts with external environments: CLI, API, etc. Includes basic classes for information representing (for the external environments) and its formatting. - `donna.cli` — code that implements the `donna` CLI tool, its commands, arguments parsing, etc. - `donna.primitives` — code that implements basic building blocks for Donna's behavior: concrete implementations of various classes from the `donna.machine`. - `donna.lib` — module that contains constructed primitives to be used in donna artifacts by referencing them by python import path. Like `donna.lib.workflow`, `donna.lib.goto`, etc. -- `donna.fixtures.skills` — bundled skills that are distributed with Donna and synced into project workspaces under `.agents/skills`. -- `donna.fixtures.specs` — bundled Donna specifications and workflows that are distributed with Donna and synced into project workspaces under `.agents/donna`, where they are addressed as `@/.agents/donna/**` artifacts. +- `donna.fixtures.skills` — bundled skills that are distributed with Donna and synced into projects under `.agents/skills`. +- `donna.fixtures.specs` — bundled Donna specifications and workflows that are distributed with Donna and synced into projects under `.agents/donna`, where they are addressed as `@/.agents/donna/**` artifacts. ## Data structures diff --git a/specs/intro.donna.md b/specs/intro.donna.md index 16f677ed..10df4bb0 100644 --- a/specs/intro.donna.md +++ b/specs/intro.donna.md @@ -33,12 +33,12 @@ We may need coding agents on each step of the process, but there is no reason fo - **Head section** — the H1 section of a markdown artifact (before the first H2) that contains the primary description and mandatory config block. - **Internal error** — an error caused by a bug or unexpected state in Donna itself. These errors are not expected to be handled by agents or users. - **Protocol** — the output/interaction mode for Donna (e.g., `llm`) that governs CLI behavior and rendering. -- **Session** — the active unit of work tracked by Donna; its state and artifacts live under `/.donna/session`. +- **Session** — the active unit of work tracked by Donna; its state and artifacts live under `/.session/donna`. - **Source** — the entity that implements logic of building an artifact from its raw data (text or binary). - **Specification** — a text artifact of kind `donna.lib.specification` that documents behavior, rules, or project guidance. - **Story** — a semantically consistent scope of work within a session; a conceptual unit not directly represented in the tool. - **Tail section** — each H2 section of an artifact. -- **Workspace** — the `.donna` directory at `/.donna` that stores Donna's configuration, and runtime state. +- **Workspace** — the Donna project rooted at the directory containing `donna.toml`; runtime state lives under the configured session directory. - **Workflow** — a `donna.lib.workflow` artifact that encodes a finite-state machine of operations guiding the agent's work. - **Workflow operation** — a single step in a workflow, defined by a tail section with an `id`, `kind`, and instructions. @@ -46,7 +46,7 @@ We may need coding agents on each step of the process, but there is no reason fo - `./donna/` — a directory containing source code of project — `donna` CLI tool. - `./specs/` — a directory containing project-specific donna artifacts that is used to manage the work of AI agents on this project. -- `./.donna/` — a directory containing Donna-specific artifacts used to manage the work of AI agents on this project. +- `./.session/donna/` — the configured temporary session directory used by Donna for runtime state and session artifacts. ## Specifications of interest diff --git a/specs/work/log_changes.donna.md b/specs/work/log_changes.donna.md index 58c05ac4..c13a46a6 100644 --- a/specs/work/log_changes.donna.md +++ b/specs/work/log_changes.donna.md @@ -41,7 +41,7 @@ id = "analyze_scoped_changes" kind = "donna.lib.request_action" ``` -1. Focus on changes in the `@/.donna/session/**` artifacts provided by the parent workflow. +1. Focus on changes in the `@/.session/donna/**` artifacts provided by the parent workflow. 2. Summarize the main changes within that scoped set to use for the changelog entry. 3. Only after the scoped analysis, check the git state to confirm the summary reflects the current working tree. 4. `{{ donna.lib.goto("analyze_branch_name") }}`