V13 / PROJECTS

project_draft_source_operation

Application-bound scenario operation. Named XML inputs control execution; this is not a main-agent tool.

See source registrationIntroduced in V12V13

What it does

Read the exact source snapshot below for its parameters, behavior, and registration.

Read the implementation

This page describes the selected release. The source link points to the same exact commit; it cannot silently open a newer implementation.

Lilith/Core/Projects/ProjectEditingOperations.cs ↗

Implementation code

Read the implementation from this version's exact source snapshot. Helper links below stay on the same release.

Lilith/Core/Projects/ProjectEditingOperations.cs

C#
namespace Lilith.Core.Projects;

internal static class ProjectEditingOperations
{
    internal static readonly string[] Names = ["project_edit_prepare_operation", "project_restore_prepare_operation", "project_backups_operation", "project_draft_read_operation", "project_draft_source_operation", "project_edit_require_operation", "project_tests_require_operation", "project_edit_apply_operation", "project_set_tests_operation", "project_run_tests_operation"];
    internal static async Task<string> ExecuteAsync(ProviderClient provider, string name, IReadOnlyDictionary<string, string> inputs, CancellationToken ct)
    {
        var store = new ProjectDraftStore(provider.Workspace ?? throw new InvalidOperationException("Project editing needs a workspace."));
        string Get(string key) => inputs.GetValueOrDefault(key, "");
        string id = Get("id");
        if (name == "project_draft_source_operation") return ProjectJson.Serialize(new { source = ProjectIntegrationCodec.Display(new(store.Load(id).Files)) });
        string Receipt(ProjectDraft draft) => ProjectJson.Serialize(new { planned = true, status = "awaiting_test_approval", draft.Id, draft.Name, tests = draft.Tests.Select(t => new { t.Id, t.Requirement }), message = "Private candidate and tests prepared. No generated application was run or published. Review with /project-review " + draft.Id + "; explicitly approve this project and up to ten test/repair rounds with /project-test " + draft.Id + ". Publication approval remains separate." });
        if (name == "project_tests_require_operation")
        {
            var draft = store.Load(id);
            if (draft.Tests.Length == 0 || draft.State != "awaiting_test_approval") throw new InvalidOperationException("No valid frozen test plan was prepared after three attempts. Nothing executed or published.");
            return Receipt(draft);
        }
        if (name == "project_edit_require_operation" && store.Load(id).Revision == 0) throw new InvalidOperationException("No valid source edit was prepared after three attempts. Private diagnostics are retained.");
        if (name == "project_backups_operation") return ProjectJson.Serialize(new { backups = store.Backups(Get("name")) });
        if (name == "project_restore_prepare_operation") return ProjectJson.Serialize(store.Inspect(store.Restore(Get("name"), Get("backup_id")).Id));
        if (name == "project_run_tests_operation")
        {
            if (provider.ProjectExecutionId != id) throw new InvalidOperationException("Explicit host execution approval required: /project-test <draft-id>. Models cannot approve execution.");
            return await ProjectQualification.RunAsync(provider, store, id, ct);
        }
        if (name == "project_edit_prepare_operation")
        {
            var draft = store.Import(Get("name"), Get("request")); return ProjectJson.Serialize(store.Inspect(draft.Id));
        }
        if (name is "project_edit_apply_operation" or "project_set_tests_operation")
        {
            // A separate host cannot change a draft while its qualification lease is held.
            using var lease = new FileStream(Path.Combine(store.Folder(id), "execution.lock"), FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None);
            if (name == "project_edit_apply_operation")
            {
                try { store.Apply(id, Get("changes")); return ProjectJson.Serialize(new { applied = true, id }); }
                catch (Exception ex) when (ex is InvalidDataException or System.Text.Json.JsonException)
                {
                    var draft = store.Load(id); store.Save(draft with { SourceReview = "Source edit was rejected: " + ex.Message });
                    return ProjectJson.Serialize(new { applied = false, id, diagnostics = ex.Message });
                }
            }
            else
            {
                try { return Receipt(store.AddTests(id, Get("plan"))); }
                catch (Exception ex) when (ex is InvalidDataException or System.Text.Json.JsonException)
                {
                    var draft = store.Load(id); store.Save(draft with { SourceReview = "Test plan was rejected: " + ex.Message });
                    return ProjectJson.Serialize(new { planned = false, id, diagnostics = ex.Message });
                }
            }
        }
        return ProjectJson.Serialize(store.Inspect(id));
    }
}

Scenarios using this tool