Conversation
There was a problem hiding this comment.
Thanks for this — the workspace scaffolding + opt-in git init is the right feature, and the double-dialog picker fix is real. Before merge it needs a rebase + a few guards (reviewed against main @ 15b6cf0, after #5/#6 landed):
Blockers
-
Stale hunks — rebase needed.
api/routers/assist.py(Popen + watcher thread) andapi/services/harness_env.py(agy/npm PATH) duplicate #5. #5 landed as PATH-only with async kept, so please rebase onto origin/main and drop both hunks from this branch. -
POST /createscaffolds any absolute path with no validation. Please require absolute path, deny system/dot dirs (e.g. ~/.ssh), and refuse non-empty dirs without an explicit flag. -
If the target is already inside a work tree,
git initcreates an embedded repo. Pleasegit rev-parse --show-toplevel(timeout=5) first: if inside a tree, skip init/add/commit and return{already_tracked: True, parent}. Fresh dirs (rev-parse fails) proceed to init normally — that case is untouched. We kind of need to make sure this caters to both users who want privacy vs users who want their workspaces git tracked. -
All git calls need
timeout=10; always-ensure.gitignore(not only-if-missing); treat commit non-zero (missing user.name/email) as{committed: False, error}, not fatal. Moveupdate_settings(linked_workspace_dir)out ofcreate_workspace()so a git failure can't leave the app pointed at a half-built workspace. Don't leak absolute paths viadetail=str(e). -
UI default. Backend
init_gitdefaults False (local-first) butSettingsModal.tsxpre-checks withuseState(true). Please flip tofalseand surface thealready_trackedmessage ('Already inside , skipped init').
** If you are using Antigravity for this one, below is an overview and use a better model !**
- Pure-Tk picker: the osascript/zenity fallback is unreachable behind Tk-first — delete it.
- Dedupe
handleBrowseExisting/handleBrowseNewinto one hook; unify linkStatus/createStatus notices. - Hoist
is_git_availableimport; drop deadimport warnings. - Extend
tests/test_workspace_create.pywith repo-root + nested-subdiralready_trackedcases.
You could also extend the workspace tracking feature to track file states as well and indicate them in the FileSidebar.tsx as well if you plan on it or a sync button repalcing the open workspace button to sync ( add + commit ? ) to the git origin that the workspace has, if there isnt we hide it or something. There is also some workspace dedup needed which i can review once the above changes pulls through.
|
Thanks, and appreciate the pace — the workspace-create rebase plus the broader set (state tracking, staging/commit, diff, restore/snapshots, auto-save, telemetry) is ambitious, and I can already see a couple of ideas from my own todo list implemented here, so you may have saved me some time. One project rule before the larger branch goes up: tracking anything about a story is strictly opt-in, and the UI must never misrepresent the default. The backend in this PR defaults Concretely:
Also, I see you're on Sand — if you haven't tried them yet, give the others a spin. I like Blue Note. |
|
Thanks, I'll update #7 and then stack the rest of the changes. Definitely have that git defaulted to unchecked on the create workspace. Yes, git and snapshots are mutually exclusive. I understand the privacy angle and minimalism design. I'm not familiar with Sand and Blue Note? |
e6686b9 to
22a0dc7
Compare
|
@prxshetty I have rebased on main and updated the PR with the requested changes. I'll split the larger changes up into separate PRs. I don't think I can use the stack feature for cross-fork PRs, but I could push them as drafts that you could rebase and merge as you got to them. Alternatively, I can push them sequentially after each review and merge. I'm looking forward to seeing what you are doing for image support! |
|
@dcmaf added image support. let me know how it goes |
aa564fc to
f97b638
Compare
|
@prxshetty The image support is cool, would definitely let me do what I was looking to do. Are you considering adding integration with image generating AI? I know that can be a can of worms - there are several plugins for it available in SillyTavern. Can you add having shift-drag on a corner maintain aspect ratio when resizing? I've rebased this PR on latest main and verified the image inclusion working in my branch. I also added creation of the assets directory when creating a new workspace. |
- Add workspace creation in `FileStorageService` initializing standard project outline (`chapters/`, `characters/`, `styles/`, `prompts/`, `outputs/`) and essential starter templates (`CHAPTERS.md`, `chapter-1.md`, `CHARACTERS.md`, `protagonist.md`, `STYLES.md`, style guides, `story_state.yaml`). - Add optional Git repository initialization with `.gitignore` generation, automatically disabled when Git is not available in PATH. - Add `POST /api/workspace/create` and `GET /api/workspace/git-status` endpoints. - Unify native folder picker into a single dialog with foreground focus - Add "Create New Workspace" section to General settings in `SettingsModal`. - Add a workspace switcher icon button next to the New Folder button at the top of `FileSidebar`. - Add unit tests covering workspace creation, file generation, Git init, and API endpoints in `tests/test_workspace_create.py`. Generated by Antigravity.
- Validate POST /create paths: require absolute paths, deny system and
dot directories (e.g. ~/.ssh, C:\Windows), and reject non-empty
directories without explicit force=true.
- Prevent embedded git repos: check `git rev-parse --show-toplevel`
(timeout=5) before init; return {already_tracked: True, git_parent}
and skip init/add/commit if already inside a work tree.
- Add timeout=10 to all git subprocess commands; always write .gitignore
on init; handle missing git author identity gracefully without failing.
- Move update_settings() out of create_workspace() so creation failures
cannot leave the application linked to a half-built directory.
- Simplify folder picker to a pure-Tkinter dialog, removing unreachable
OS-specific CLI fallback code and dead imports.
- Sanitize router error responses to avoid leaking internal filesystem paths.
- UI: set local-first initGit default to false, deduplicate folder browse
handlers into a shared browsePicker helper, and surface already_tracked
status via an info banner.
- Add unit tests covering dot/sensitive paths, force flags, and root/nested
already-tracked git repositories (13/13 passing).
Create the directory used to store image assets when creating a new workspace.
71add88 to
9778ebe
Compare
prxshetty
left a comment
There was a problem hiding this comment.
Thanks for the rebase + hardening — verified the 5 blockers are in:
No more assist.py / harness_env.py hunks, clean 5-file diff.
2-4. Absolute/dot/sensitive + force flag, rev-parse already_tracked, timeouts + always-gitignore + non-fatal commit + update_settings moved + sanitized detail — all present.
initGit defaults false + already_tracked banner — present. Picker is pure-Tk, browsePicker deduped, import hoisted.
3 small gaps before I can merge:
-
/var block breaks macOS temp (3 tests fail locally).
_SENSITIVE_PATH_PREFIXES includes Path("/var") (api/services/file_storage.py:36). Router resolves both sides (_is_subpath, api/routers/workspace.py:75-82,141-144). On macOS TMPDIR=/var/folders/... resolves to /private/var/... vs /private/var -> match -> 400 "not allowed".
Repro on macOS: pytest tests/test_workspace_create.py -> test_api_create_workspace, non_empty_rejected_without_force, non_empty_allowed_with_force fail. CI stays green because backend job uses pytest ... 2>/dev/null || echo. Suggest narrowing /var to /var/log, /var/lib etc. or exempting tempfile.gettempdir(). -
assets/ not scaffolded in create_workspace.
9778ebe adds (workspace_dir / "assets").mkdir to _ensure_workspace only, not to create_workspace(). New workspaces still lack assets/ which #9 expects. One-liner in create_workspace alongside chapters/characters/styles/prompts/outputs. -
Relative-path check is dead code.
api/routers/workspace.py:127-131 resolves first, then checks is_absolute() — resolve() always returns absolute, so "relative/path" becomes /cwd/relative/path and passes. The existing test only posts " " (hits empty-check). Suggest checking Path(raw).expanduser().is_absolute() before resolve().
Note: keeping import warnings is correct — still used at file_storage.py:49, so ignore my earlier drop-dead-import note.
Once 1-3 are patched I will merge. No action needed on the stacked ideas (state tracking / staging / diff / restore / auto-save / telemetry) — keep those for follow-up PRs.
@prxshetty Thanks - I'll knock those out and update tonight. I should have the next PR ready to go pretty quickly after that. |
- Narrow sensitive path prefixes to allow macOS TMPDIR (/var/folders) and /tmp - Scaffold missing assets/ directory in create_workspace - Fix dead-code validation by checking raw relative paths before resolve() - Add case-insensitive subpath containment check for Windows and macOS - Use shutil.which() for robust platform-agnostic Git binary resolution - Make workspace path input placeholders in SettingsModal platform-adaptive - Add unit tests for assets/ directory, relative paths, and temp folder creation
|
@prxshetty Those issues should be fixed now along with some additional changes for cross-platform compatibility. |

FileStorageServiceinitializing standard project outline (chapters/,characters/,styles/,prompts/,outputs/) and essential starter templates (CHAPTERS.md,chapter-1.md,CHARACTERS.md,protagonist.md,STYLES.md, style guides,story_state.yaml)..gitignoregeneration, automatically disabled when Git is not available in PATH.POST /api/workspace/createandGET /api/workspace/git-statusendpoints.SettingsModal.FileSidebar.tests/test_workspace_create.py. Generated by Antigravity.