Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
1cdf5dc
Add named resource roots and rename RootFolder
chrisgregan May 19, 2026
b5248fa
Add pluggable root handlers and scoped path validation
chrisgregan May 19, 2026
d68c188
Add .celbridge roots, handlers, and monitoring
chrisgregan May 19, 2026
4d8c9da
Clarify resource-key roots and canonicalize outputs
chrisgregan May 19, 2026
72fc514
Replace ResourceFileWriter with ResourceFileSystem
chrisgregan May 20, 2026
bcdfe36
Add IPythonInstaller and move file-hash utilities
chrisgregan May 20, 2026
acb4db9
Move utility helpers into Helpers folder
chrisgregan May 20, 2026
928cbd6
Add sidecar parsing, metadata service, tests
chrisgregan May 20, 2026
c30f0dc
Return structured results for resource ops
chrisgregan May 21, 2026
748b0e8
Use Resource* messages; eager notify on FS ops
chrisgregan May 21, 2026
0bbbabc
Propagate inner Result errors via Result.Fail(Result)
chrisgregan May 21, 2026
83803ae
Clarify explorer delete/move referencer behavior
chrisgregan May 21, 2026
c9d4e97
Add metadata sidecar tools and project checks
chrisgregan May 22, 2026
2331027
Phase 5.5: Add data APIs and sidecar services
chrisgregan May 22, 2026
444b9ed
Clarify data_get_info behavior when parent missing
chrisgregan May 22, 2026
7b92843
Canonicalize ResourceKey.ToString to include root
chrisgregan May 22, 2026
fa75841
Prefer resource Path for UI and file paths
chrisgregan May 22, 2026
14a7d0e
Exclude .md from resource scanning
chrisgregan May 22, 2026
41014ac
Allowlist-based scanner; resolve paths via registry
chrisgregan May 23, 2026
69f6e03
Enforce resource key case and improve error handling
chrisgregan May 23, 2026
7984853
Support exact filenames and multi-part extensions
chrisgregan May 23, 2026
c4d3ef0
Refactor resource/sidecar and document editor APIs
chrisgregan May 26, 2026
b74a133
Add test NLog.config and improve tests
chrisgregan May 27, 2026
455012b
Track and enforce EditorId on document views
chrisgregan May 27, 2026
1c29764
Notify messenger when WebView gains focus
chrisgregan May 27, 2026
9a35679
Add .cel editor type and Celbridge icons
chrisgregan May 27, 2026
08c673d
Use IResourceFileSystem and async streaming IO
chrisgregan May 28, 2026
eaa6ccf
Introduce ResourceClassifier and FileKind
chrisgregan May 28, 2026
9d700fa
Rename ResourceFileSystem API to FileStorage
chrisgregan May 28, 2026
c973f3a
Rename ReferenceLiteralRules to ResourceReferenceParser
chrisgregan May 28, 2026
cb5b744
Add ComputeHash and remove FileAccessHelper
chrisgregan May 28, 2026
9e88574
Unify file IO retry logic and use streaming reads
chrisgregan May 28, 2026
367d25d
Remove filename-based document editor support
chrisgregan May 28, 2026
22ef66b
Build zip archive in-memory, remove temp file
chrisgregan May 28, 2026
6c0c8f1
Per-root PathValidator and cache invalidation
chrisgregan May 28, 2026
1a15898
Refactor SearchService to use workspace properties
chrisgregan May 28, 2026
00b05f3
Integrate FileFilter into SearchService
chrisgregan May 28, 2026
e50cf05
Refactor resource commands to use workspace services
chrisgregan May 28, 2026
c92f882
Add Trash service and ResourceKey-based ops
chrisgregan May 28, 2026
e2a3a48
Introduce IBatchScope and RootPathResolver
chrisgregan May 29, 2026
ad40801
Track files by size+mtime; coalesce reloads
chrisgregan May 29, 2026
c490a89
Add reload hints for document view state
chrisgregan May 29, 2026
8700681
Don't move open tab unless address provided
chrisgregan May 29, 2026
af901d9
Inject PackageRegistry into PackageService
chrisgregan May 29, 2026
18cbeca
Add temp:downloads and refactor temp path handling
chrisgregan May 29, 2026
293397e
Refactor resource/storage types & sidecar handling
chrisgregan May 29, 2026
e76b054
Add LegacyConstants and refactor project constants
chrisgregan May 29, 2026
f0428c5
Rename CelFileReport to SidecarReport
chrisgregan May 29, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
5 changes: 3 additions & 2 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,13 +81,14 @@ python run_tests.py
- When logging an exception, pass the exception object to the logger overload (e.g. `_logger.LogError(ex, "...")`); do not interpolate `ex.Message` or `ex.ToString()` into the message string
- Keep XML doc comments concise but informative: one or two `<summary>` sentences describing *what* the member does, written so a reader who hasn't seen the class can understand it. If one line would just rephrase the member name (e.g. `"Typed counterpart of X"`), use two — conciseness is the constraint, not the goal. Do not embed implementation rationale, caller behavior, or detail already carried by types (enums, records, nullable returns). Avoid inline formatting tags (`<c>`, `<list>`, `<item>`) and multi-paragraph `<remarks>` blocks; plain type names read fine without `<see cref>` prose in summaries
- Interface members and public types in `Celbridge.Foundation` must always carry a concise `<summary>` — the Foundation abstractions are how a reader understands the system, so every interface method, public record, and public enum there needs enough comment to stand alone. Conversely, skip xmldoc on concrete-class members by default: the interface they implement already documents them, and duplicated comments drift out of sync with the implementation. Exception: when the implementation has behavior that isn't obvious from the signature (unusual threading constraints, hidden side effects, non-obvious failure modes, subtle invariants), add a brief note. Treat the exception as rare — if the summary would just restate the name or repeat the interface comment, skip it
- Keep inline body comments terse — write only what a first-time reader needs to know that they can't read off the code. Don't narrate what the current change is about, don't recap rationale visible in the surrounding code, don't enumerate edge cases the reader can infer. If a comment approaches paragraph length, the code probably needs restructuring instead
- Model user or programmatic cancellation as a typed success outcome (e.g., `Result<OutcomeEnum>` with a `Cancelled` value), not as `Result.Fail`; `Result.Fail` stays reserved for genuine errors (precedent: `OpenDocumentOutcome`, `CloseDocumentOutcome`)
- Minimize `Result<T>` boilerplate at return sites: use implicit conversions (`return value;` for concrete types; `return Result.Fail("message");` for failures). For interface return types, use the `OkResult<T>()` extension from `ResultExtensions`. Always unpack `result.Value` into a named temporary variable before using it

## Architecture

- Workspace-scoped services are transient and must NOT be injected via constructor DI. Access them through `_workspaceWrapper.WorkspaceService`:
- IWorkspaceSettingsService, IWorkspaceSettings, IResourceRegistry, IResourceTransferService, IResourceOperationService, IPythonService, IConsoleService, IDocumentsService, IExplorerService, IInspectorService, IDataTransferService, IEntityService, IGenerativeAIService, IActivityService
- IWorkspaceSettingsService, IWorkspaceSettings, IResourceRegistry, IFileStorage, IResourceTransferService, IResourceOperationService, IPythonService, IConsoleService, IDocumentsService, IExplorerService, IInspectorService, IDataTransferService, IEntityService, IGenerativeAIService, IActivityService
- Project configuration: use `IProjectService.CurrentProject` (singleton) to access the current project, and `project.Config` for its config. To parse `.celbridge` files outside of project loading, use `ProjectConfigParser.ParseFromFile()`
- The Foundation project (`Core\Celbridge.Foundation`) should only contain abstractions (interfaces, abstract classes), never concrete implementations
- Never bypass `ICommandService` to call methods directly. Every important operation goes through the command service for automation and auditing support. If a command-based flow has a bug, fix it within the command service pattern (e.g., add new command options or fix the command handling logic)
Expand All @@ -100,7 +101,7 @@ Documents auto-save via `DocumentViewModel.OnDataChanged()` → per-view save ti
- Do not add "discard unsaved changes?" prompts on close — closing always saves.
- Programmatic edit commands (`EditFileCommand`, `MultiEditFileCommand`, `ReplaceFileCommand`, `ApplyRangeEditsCommand`, `WriteFileCommand`, `WriteBinaryFileCommand`) write straight to disk; there is no editor-routed code path. When the target file is open, the on-disk write triggers a watcher event and the document buffer reloads from disk via `editor.setValue`, which clears Monaco's undo history. Preserve that contract when adding new edit code paths — do not route writes through the open editor, and do not try to preserve undo state across a programmatic write.
- External edits always win: if a watcher event arrives while a save is queued or in flight, the save is discarded and the buffer reloads from disk. `DocumentViewModel.SaveTextToFileAsync` also raises `ReloadRequested` when the post-write disk hash differs from what we intended to write (i.e. an external write interleaved).
- `MonitoredResourceChangedMessage` fires on every save; `DocumentViewModel` filters self-triggered events by hash. New consumers should expect high-frequency events.
- `ResourceChangedMessage` fires on every save; `DocumentViewModel` filters self-triggered events by hash. New consumers should expect high-frequency events.

## MCP Tools

Expand Down
2 changes: 1 addition & 1 deletion Source/Celbridge/Package.appxmanifest
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
xmlns:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities"
IgnorableNamespaces="uap rescap">

<Identity Name="org.celbridge.Celbridge" Version="0.2.7.0" Publisher="CN=AnTulcha"/>
<Identity Name="org.celbridge.Celbridge" Version="0.3.0.0" Publisher="CN=AnTulcha"/>
<Properties >
<DisplayName>Celbridge</DisplayName>
<PublisherDisplayName>celbridge.org</PublisherDisplayName>
Expand Down
17 changes: 16 additions & 1 deletion Source/Celbridge/Resources/Strings/en-US/Resources.resw
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Expand Down Expand Up @@ -566,6 +566,12 @@ Do you wish to continue?</value>
<data name="ConsolePanel_PackageLoadErrorMessage" xml:space="preserve">
<value>One or more packages failed to load. See the log for details.</value>
</data>
<data name="ConsolePanel_ProjectCheckFindingsTitle" xml:space="preserve">
<value>Project Check Findings</value>
</data>
<data name="ConsolePanel_ProjectCheckFindingsMessage" xml:space="preserve">
<value>Project check found {0} issue(s). See log for details.</value>
</data>
<data name="DocumentToolbar_SplitEditorTooltip" xml:space="preserve">
<value>Split Editor</value>
</data>
Expand Down Expand Up @@ -962,6 +968,15 @@ Do you wish to continue?</value>
<data name="DocumentEditor_HtmlViewer" xml:space="preserve">
<value>HTML Viewer</value>
</data>
<data name="DocumentEditor_ProjectFile" xml:space="preserve">
<value>Project File</value>
</data>
<data name="DocumentEditor_PackageManifest" xml:space="preserve">
<value>Package Manifest</value>
</data>
<data name="DocumentEditor_DocumentContribution" xml:space="preserve">
<value>Document Contribution</value>
</data>
<data name="WebView_NavigationPrompt_Title" xml:space="preserve">
<value>Open external link</value>
</data>
Expand Down
6 changes: 2 additions & 4 deletions Source/Core/Celbridge.Commands/Services/CommandService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -106,8 +106,7 @@ public async Task<Result> ExecuteAsync<T>(

if (executionResult.IsFailure)
{
return Result.Fail($"Command execution failed")
.WithErrors(executionResult);
return Result.Fail(executionResult);
}

return Result.Ok();
Expand All @@ -134,8 +133,7 @@ public async Task<Result<TResult>> ExecuteAsync<TCommand, TResult>(

if (result.IsFailure)
{
return Result<TResult>.Fail(result.FirstErrorMessage)
.WithErrors(result);
return Result.Fail(result);
}

// The command populated ResultValue during its ExecuteAsync().
Expand Down
7 changes: 7 additions & 0 deletions Source/Core/Celbridge.Foundation/Console/ConsoleMessages.cs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,13 @@ public enum ConsoleErrorType
/// One or more packages failed to load during project discovery.
/// </summary>
PackageLoadError,

/// <summary>
/// The workspace-load project consistency check returned non-empty
/// findings (broken references, orphan .cel files, or broken .cel files).
/// The ConsoleErrorMessage.ConfigFileName field carries the summary text.
/// </summary>
ProjectCheckError,
}

/// <summary>
Expand Down
Loading
Loading