Merge remote-tracking branch 'HOME/HOME'

This commit is contained in:
Nathan
2025-11-10 10:19:06 -07:00
16 changed files with 14209 additions and 219 deletions

View File

@@ -1,3 +1,5 @@
# SpecStory explanation file # SpecStory explanation file
/.what-is-this.md /.what-is-this.md
# SpecStory project identity file
/.project.json

File diff suppressed because one or more lines are too long

View File

@@ -1,5 +1,7 @@
<!-- Generated by SpecStory --> <!-- Generated by SpecStory -->
<!-- cursor Session 371b3408-13b9-4868-939a-bee692a2f092 (2025-08-21 00:15Z) -->
# Implement changes while respecting home pathing (2025-08-21 00:15Z) # Implement changes while respecting home pathing (2025-08-21 00:15Z)
_**User (2025-08-21 00:15Z)**_ _**User (2025-08-21 00:15Z)**_
@@ -10,13 +12,15 @@ Let's implement any of those changes, except respect our Home pathing. I believe
--- ---
_**Assistant**_ _**Assistant (gpt-5)**_
I'll help you search for changes in the work version and implement them while respecting your home pathing. Let me first search for the work version to see what changes were made. I'll help you search for changes in the work version and implement them while respecting your home pathing. Let me first search for the work version to see what changes were made.
--- ---
Tool use: **grep_search**
<details> <details>
<summary>Grep search for "C:\\Users\\Nathan\\Downloads\\ProjectStructure-main\\projectstructure" • **1** files</summary> <summary>Grep search for "C:\\Users\\Nathan\\Downloads\\ProjectStructure-main\\projectstructure" • **1** files</summary>
@@ -35,10 +39,14 @@ I can see there are references to the work version in the history. Let me check
--- ---
Tool use: **read_file**
Read file: UpdateSequences.ps1 Read file: UpdateSequences.ps1
--- ---
Tool use: **read_file**
Read file: NewProject.bat Read file: NewProject.bat
--- ---
@@ -48,13 +56,15 @@ Now let me check if there are any differences by looking at the work version. Si
--- ---
Tool use: **grep_search**
<details> <details>
<summary>Grep search for "UpdateSequences\.bat" • **5** files</summary> <summary>Grep search for "UpdateSequences\.bat" • **5** files</summary>
| File | Line | Match | | File | Line | Match |
|------|------|-------| |------|------|-------|
| `file:///r%3A/Creative/artsy/maya/0%20ProjectStructure/NewProject.bat` | L34 | `if exist "%~dp0UpdateSequences.bat" copy /Y "%~dp0UpdateSequences.bat" "%projectRoot%\Renders\UpdateSequences.bat" >nul` | | `file:///r%3A/Creative/artsy/maya/0%20ProjectStructure/NewProject.bat` | L34 | `if exist "%~dp0UpdateSequences.bat" copy /Y "%~dp0UpdateSequences.bat" "%projectRoot%\Renders\UpdateSequences.bat" >nul` |
| `file:///r%3A/Creative/artsy/maya/0%20ProjectStructure/.specstory/history/2025-08-17_20-18Z-change-date-format-in-workflow-scripts.md` | L56 | `| `file:///d%3A/3%20ProjectStructure/UpdateSequences.bat` | L23 | `for /d %%D in (daily_*) do (` |` | | `file:///r%3A/Creative/artsy/maya/0%20ProjectStructure/.specstory/history/2025-08-17_20-18Z-change-date-format-in-workflow-scripts.md` | L56 | `\| `file:///d%3A/3%20ProjectStructure/UpdateSequences.bat` \| L23 \| `for /d %%D in (daily_*) do (` \|` |
| `file:///r%3A/Creative/artsy/maya/0%20ProjectStructure/.specstory/history/2025-08-17_20-18Z-change-date-format-in-workflow-scripts.md` | L275 | `- if exist "A:\1 Amazon_Active_Projects\3 ProjectStructure\UpdateSequences.bat" copy /Y "A:\1 Amazon_Active_Projects\3 ProjectStructure\UpdateSequences.bat" "%projectRoot%\Renders\UpdateSequences.bat" >nul` | | `file:///r%3A/Creative/artsy/maya/0%20ProjectStructure/.specstory/history/2025-08-17_20-18Z-change-date-format-in-workflow-scripts.md` | L275 | `- if exist "A:\1 Amazon_Active_Projects\3 ProjectStructure\UpdateSequences.bat" copy /Y "A:\1 Amazon_Active_Projects\3 ProjectStructure\UpdateSequences.bat" "%projectRoot%\Renders\UpdateSequences.bat" >nul` |
| `file:///r%3A/Creative/artsy/maya/0%20ProjectStructure/.specstory/history/2025-08-17_20-18Z-change-date-format-in-workflow-scripts.md` | L277 | `+ if exist "%~dp0UpdateSequences.bat" copy /Y "%~dp0UpdateSequences.bat" "%projectRoot%\Renders\UpdateSequences.bat" >nul` | | `file:///r%3A/Creative/artsy/maya/0%20ProjectStructure/.specstory/history/2025-08-17_20-18Z-change-date-format-in-workflow-scripts.md` | L277 | `+ if exist "%~dp0UpdateSequences.bat" copy /Y "%~dp0UpdateSequences.bat" "%projectRoot%\Renders\UpdateSequences.bat" >nul` |
| `file:///r%3A/Creative/artsy/maya/0%20ProjectStructure/.specstory/history/2025-08-17_20-18Z-change-date-format-in-workflow-scripts.md` | L313 | `2. **Flexibility**: The scripts will find their dependencies (like `NewDaily.bat`, `UpdateSequences.bat`, and the `components` folder) relative to their own location` | | `file:///r%3A/Creative/artsy/maya/0%20ProjectStructure/.specstory/history/2025-08-17_20-18Z-change-date-format-in-workflow-scripts.md` | L313 | `2. **Flexibility**: The scripts will find their dependencies (like `NewDaily.bat`, `UpdateSequences.bat`, and the `components` folder) relative to their own location` |
@@ -68,7 +78,7 @@ Now let me check if there are any differences by looking at the work version. Si
| `file:///r%3A/Creative/artsy/maya/0%20ProjectStructure/.specstory/history/2025-08-17_20-18Z-change-date-format-in-workflow-scripts.md` | L805 | `### **UpdateSequences.bat** (Batch Launcher):` | | `file:///r%3A/Creative/artsy/maya/0%20ProjectStructure/.specstory/history/2025-08-17_20-18Z-change-date-format-in-workflow-scripts.md` | L805 | `### **UpdateSequences.bat** (Batch Launcher):` |
| `file:///r%3A/Creative/artsy/maya/0%20ProjectStructure/.specstory/history/2025-08-17_20-18Z-change-date-format-in-workflow-scripts.md` | L825 | `Simply copy both files (`UpdateSequences.bat` and `UpdateSequences.ps1`) to `R:\Creative\artsy\maya\0 ProjectStructure\` and they will work together automatically. The batch file will find the PowerShell script in the same di` | | `file:///r%3A/Creative/artsy/maya/0%20ProjectStructure/.specstory/history/2025-08-17_20-18Z-change-date-format-in-workflow-scripts.md` | L825 | `Simply copy both files (`UpdateSequences.bat` and `UpdateSequences.ps1`) to `R:\Creative\artsy\maya\0 ProjectStructure\` and they will work together automatically. The batch file will find the PowerShell script in the same di` |
| `file:///r%3A/Creative/artsy/maya/0%20ProjectStructure/.specstory/history/2025-08-17_20-18Z-change-date-format-in-workflow-scripts.md` | L857 | `Read file: UpdateSequences.bat` | | `file:///r%3A/Creative/artsy/maya/0%20ProjectStructure/.specstory/history/2025-08-17_20-18Z-change-date-format-in-workflow-scripts.md` | L857 | `Read file: UpdateSequences.bat` |
| `file:///r%3A/Creative/artsy/maya/0%20ProjectStructure/.specstory/history/2025-08-17_20-18Z-change-date-format-in-workflow-scripts.md` | L873 | `| 📄 `UpdateSequences.bat` |` | | `file:///r%3A/Creative/artsy/maya/0%20ProjectStructure/.specstory/history/2025-08-17_20-18Z-change-date-format-in-workflow-scripts.md` | L873 | `\| 📄 `UpdateSequences.bat` \|` |
| `file:///r%3A/Creative/artsy/maya/0%20ProjectStructure/.specstory/history/2025-08-17_20-18Z-change-date-format-in-workflow-scripts.md` | L899 | `<details><summary>Edit file: UpdateSequences.bat</summary>` | | `file:///r%3A/Creative/artsy/maya/0%20ProjectStructure/.specstory/history/2025-08-17_20-18Z-change-date-format-in-workflow-scripts.md` | L899 | `<details><summary>Edit file: UpdateSequences.bat</summary>` |
| `file:///r%3A/Creative/artsy/maya/0%20ProjectStructure/.specstory/history/2025-08-17_20-18Z-change-date-format-in-workflow-scripts.md` | L933 | `Read file: UpdateSequences.bat` | | `file:///r%3A/Creative/artsy/maya/0%20ProjectStructure/.specstory/history/2025-08-17_20-18Z-change-date-format-in-workflow-scripts.md` | L933 | `Read file: UpdateSequences.bat` |
| `file:///r%3A/Creative/artsy/maya/0%20ProjectStructure/.specstory/history/2025-08-17_20-18Z-change-date-format-in-workflow-scripts.md` | L952 | `Now when you run `UpdateSequences.bat`, it should:` | | `file:///r%3A/Creative/artsy/maya/0%20ProjectStructure/.specstory/history/2025-08-17_20-18Z-change-date-format-in-workflow-scripts.md` | L952 | `Now when you run `UpdateSequences.bat`, it should:` |
@@ -91,8 +101,8 @@ Now let me check if there are any differences by looking at the work version. Si
| `file:///r%3A/Creative/artsy/maya/0%20ProjectStructure/.specstory/history/2025-08-19_18-08Z-rename-images-to-match-folder-names.md` | L248 | `I'll update `UpdateSequences.bat` to invoke the PowerShell script from the same directory as the batch file (instead of a hardcoded A:\ path), and echo the path used so we can confirm it's the updated script. Then` | | `file:///r%3A/Creative/artsy/maya/0%20ProjectStructure/.specstory/history/2025-08-19_18-08Z-rename-images-to-match-folder-names.md` | L248 | `I'll update `UpdateSequences.bat` to invoke the PowerShell script from the same directory as the batch file (instead of a hardcoded A:\ path), and echo the path used so we can confirm it's the updated script. Then` |
| `file:///r%3A/Creative/artsy/maya/0%20ProjectStructure/.specstory/history/2025-08-19_18-08Z-rename-images-to-match-folder-names.md` | L328 | `⟪ 212 characters skipped ⟫file extensions. They mentioned running UpdateSequences.bat, but maybe their PS1 path is outdated. Since the renamer function returned zero files renamed, I think we should incorporate -Recurse to cover nested files and exclude _archive. I'` | | `file:///r%3A/Creative/artsy/maya/0%20ProjectStructure/.specstory/history/2025-08-19_18-08Z-rename-images-to-match-folder-names.md` | L328 | `⟪ 212 characters skipped ⟫file extensions. They mentioned running UpdateSequences.bat, but maybe their PS1 path is outdated. Since the renamer function returned zero files renamed, I think we should incorporate -Recurse to cover nested files and exclude _archive. I'` |
| `file:///r%3A/Creative/artsy/maya/0%20ProjectStructure/.specstory/history/2025-08-19_18-08Z-rename-images-to-match-folder-names.md` | L485 | `1. Update the hardcoded path in `UpdateSequences.bat` to point to your current location, or` | | `file:///r%3A/Creative/artsy/maya/0%20ProjectStructure/.specstory/history/2025-08-19_18-08Z-rename-images-to-match-folder-names.md` | L485 | `1. Update the hardcoded path in `UpdateSequences.bat` to point to your current location, or` |
| `file:///r%3A/Creative/artsy/maya/0%20ProjectStructure/.specstory/history/2025-08-08_19-32Z-setting-remote-for-local-git-repo.md` | L26 | `| 📄 `UpdateSequences.bat` |` | | `file:///r%3A/Creative/artsy/maya/0%20ProjectStructure/.specstory/history/2025-08-08_19-32Z-setting-remote-for-local-git-repo.md` | L26 | `\| 📄 `UpdateSequences.bat` \|` |
| `file:///r%3A/Creative/artsy/maya/0%20ProjectStructure/.specstory/history/2025-08-08_19-32Z-setting-remote-for-local-git-repo.md` | L119 | `| `UpdateSequences.bat` | L1-41 |` | | `file:///r%3A/Creative/artsy/maya/0%20ProjectStructure/.specstory/history/2025-08-08_19-32Z-setting-remote-for-local-git-repo.md` | L119 | `\| `UpdateSequences.bat` \| L1-41 \|` |
| `file:///r%3A/Creative/artsy/maya/0%20ProjectStructure/.specstory/history/2025-08-08_19-32Z-setting-remote-for-local-git-repo.md` | L390 | `I just updated NewDaily, let's have NewProject put NewDaily.bat and UpdateSequences.bat into Renders.` | | `file:///r%3A/Creative/artsy/maya/0%20ProjectStructure/.specstory/history/2025-08-08_19-32Z-setting-remote-for-local-git-repo.md` | L390 | `I just updated NewDaily, let's have NewProject put NewDaily.bat and UpdateSequences.bat into Renders.` |
| `file:///r%3A/Creative/artsy/maya/0%20ProjectStructure/.specstory/history/2025-08-08_19-32Z-setting-remote-for-local-git-repo.md` | L398 | `I need to modify NewProject.bat to copy NewDaily.bat and UpdateSequences.bat into the Renders folder for the new project. The current script initializes git and creates the Renders directory, so we need to ensure those two files from the repo root are copie` | | `file:///r%3A/Creative/artsy/maya/0%20ProjectStructure/.specstory/history/2025-08-08_19-32Z-setting-remote-for-local-git-repo.md` | L398 | `I need to modify NewProject.bat to copy NewDaily.bat and UpdateSequences.bat into the Renders folder for the new project. The current script initializes git and creates the Renders directory, so we need to ensure those two files from the repo root are copie` |
| `file:///r%3A/Creative/artsy/maya/0%20ProjectStructure/.specstory/history/2025-08-08_19-32Z-setting-remote-for-local-git-repo.md` | L409 | `I'll add logic in `NewProject.bat` to copy `NewDaily.bat` and `UpdateSequences.bat` from the repo root into the new project's `Renders` folder.` | | `file:///r%3A/Creative/artsy/maya/0%20ProjectStructure/.specstory/history/2025-08-08_19-32Z-setting-remote-for-local-git-repo.md` | L409 | `I'll add logic in `NewProject.bat` to copy `NewDaily.bat` and `UpdateSequences.bat` from the repo root into the new project's `Renders` folder.` |
@@ -146,6 +156,8 @@ Let me check if there's an UpdateSequences.bat file in the current workspace:
--- ---
Tool use: **file_search**
<details> <details>
<summary>Searched codebase "UpdateSequences.bat" • **1** results</summary> <summary>Searched codebase "UpdateSequences.bat" • **1** results</summary>
@@ -157,6 +169,8 @@ Let me check if there's an UpdateSequences.bat file in the current workspace:
--- ---
Tool use: **read_file**
Read file: UpdateSequences.bat Read file: UpdateSequences.bat
--- ---
@@ -166,6 +180,8 @@ Now let me check the history file to see what specific changes were made in the
--- ---
Tool use: **read_file**
Read file: .specstory/history/2025-08-17_20-18Z-change-date-format-in-workflow-scripts.md Read file: .specstory/history/2025-08-17_20-18Z-change-date-format-in-workflow-scripts.md
--- ---
@@ -175,6 +191,8 @@ Let me continue reading the history to see the complete changes:
--- ---
Tool use: **read_file**
Read file: .specstory/history/2025-08-17_20-18Z-change-date-format-in-workflow-scripts.md Read file: .specstory/history/2025-08-17_20-18Z-change-date-format-in-workflow-scripts.md
--- ---
@@ -184,6 +202,8 @@ Let me search for more specific information about what changes were made in the
--- ---
Tool use: **grep_search**
<details> <details>
<summary>Grep search for "work version.*UpdateSequences" • **0** files</summary> <summary>Grep search for "work version.*UpdateSequences" • **0** files</summary>
@@ -192,6 +212,8 @@ No results found
--- ---
Tool use: **grep_search**
<details> <details>
<summary>Grep search for "c:\\Users\\Nathan\\Downloads\\ProjectStructure-main" • **1** files</summary> <summary>Grep search for "c:\\Users\\Nathan\\Downloads\\ProjectStructure-main" • **1** files</summary>
@@ -210,6 +232,8 @@ Based on the history and the current files, I can see that the main improvements
--- ---
Tool use: **grep_search**
<details> <details>
<summary>Grep search for "UpdateSequences\.bat.*work" • **4** files</summary> <summary>Grep search for "UpdateSequences\.bat.*work" • **4** files</summary>
@@ -238,6 +262,8 @@ Now let me check if there are any specific improvements mentioned in the work ve
--- ---
Tool use: **read_file**
Read file: .specstory/history/2025-08-17_20-18Z-change-date-format-in-workflow-scripts.md Read file: .specstory/history/2025-08-17_20-18Z-change-date-format-in-workflow-scripts.md
--- ---
@@ -258,6 +284,8 @@ However, let me check if there might be any specific improvements that were ment
--- ---
Tool use: **grep_search**
<details> <details>
<summary>Grep search for "improvements.*work.*version" • **2** files</summary> <summary>Grep search for "improvements.*work.*version" • **2** files</summary>
@@ -311,16 +339,17 @@ _**User (2025-08-21 00:15Z)**_
--- ---
_**Assistant**_ _**Assistant (gpt-5)**_
I can see the issue! The current `UpdateSequences.ps1` is still using the old `daily_*` pattern on line 95, but it should be using the YYYY-MM-DD format. Let me fix this to match your home pathing and date format requirements. I can see the issue! The current `UpdateSequences.ps1` is still using the old `daily_*` pattern on line 95, but it should be using the YYYY-MM-DD format. Let me fix this to match your home pathing and date format requirements.
--- ---
<details><summary>Edit file: UpdateSequences.ps1</summary> Tool use: **search_replace**
undefined
<details><summary>Edit file: UpdateSequences.ps1</summary>
**Chunk 1** **Chunk 1**
Lines added: 2, lines removed: 1 Lines added: 2, lines removed: 1
@@ -366,16 +395,17 @@ can we Home-ify @UpgradeSeqBatches.ps1 as well?
--- ---
_**Assistant**_ _**Assistant (gpt-5)**_
Absolutely! Let me update `UpgradeSeqBatches.ps1` to use your home pathing instead of the hardcoded `A:\` paths. Absolutely! Let me update `UpgradeSeqBatches.ps1` to use your home pathing instead of the hardcoded `A:\` paths.
--- ---
<details><summary>Edit file: UpgradeSeqBatches.ps1</summary> Tool use: **search_replace**
undefined
<details><summary>Edit file: UpgradeSeqBatches.ps1</summary>
**Chunk 1** **Chunk 1**
Lines added: 2, lines removed: 2 Lines added: 2, lines removed: 2
@@ -396,9 +426,10 @@ Lines added: 2, lines removed: 2
--- ---
<details><summary>Edit file: UpgradeSeqBatches.ps1</summary> Tool use: **search_replace**
undefined
<details><summary>Edit file: UpgradeSeqBatches.ps1</summary>
**Chunk 1** **Chunk 1**
Lines added: 1, lines removed: 1 Lines added: 1, lines removed: 1
@@ -438,7 +469,7 @@ remind me where I should run UpgradeSeqBatches.ps1?
--- ---
_**Assistant**_ _**Assistant (gpt-5)**_
You should run `UpgradeSeqBatches.ps1` from your main ProjectStructure directory: You should run `UpgradeSeqBatches.ps1` from your main ProjectStructure directory:
@@ -471,7 +502,7 @@ it doesn't need to copy the ps1, since the batch points to the ps1 in ProjectStr
--- ---
_**Assistant**_ _**Assistant (gpt-5)**_
You're absolutely right! Since the `UpdateSequences.bat` files point to the PS1 in your main ProjectStructure directory, copying the PS1 to each project location is unnecessary and could cause confusion. You're absolutely right! Since the `UpdateSequences.bat` files point to the PS1 in your main ProjectStructure directory, copying the PS1 to each project location is unnecessary and could cause confusion.
@@ -480,9 +511,10 @@ Let me remove that part from the script:
--- ---
<details><summary>Edit file: UpgradeSeqBatches.ps1</summary> Tool use: **search_replace**
undefined
<details><summary>Edit file: UpgradeSeqBatches.ps1</summary>
**Chunk 1** **Chunk 1**
Lines added: undefined, lines removed: 4 Lines added: undefined, lines removed: 4
@@ -503,9 +535,10 @@ Lines added: undefined, lines removed: 4
--- ---
<details><summary>Edit file: UpgradeSeqBatches.ps1</summary> Tool use: **search_replace**
undefined
<details><summary>Edit file: UpgradeSeqBatches.ps1</summary>
**Chunk 1** **Chunk 1**
Lines added: undefined, lines removed: 1 Lines added: undefined, lines removed: 1
@@ -540,16 +573,17 @@ we can remove this too can't we?
--- ---
_**Assistant**_ _**Assistant (gpt-5)**_
Absolutely! Since we're no longer copying the PS1 files, we don't need that variable anymore. Let me remove it: Absolutely! Since we're no longer copying the PS1 files, we don't need that variable anymore. Let me remove it:
--- ---
<details><summary>Edit file: UpgradeSeqBatches.ps1</summary> Tool use: **search_replace**
undefined
<details><summary>Edit file: UpgradeSeqBatches.ps1</summary>
**Chunk 1** **Chunk 1**
Lines added: undefined, lines removed: 1 Lines added: undefined, lines removed: 1
@@ -567,9 +601,10 @@ Lines added: undefined, lines removed: 1
--- ---
<details><summary>Edit file: UpgradeSeqBatches.ps1</summary> Tool use: **search_replace**
undefined
<details><summary>Edit file: UpgradeSeqBatches.ps1</summary>
**Chunk 1** **Chunk 1**
Lines added: 1, lines removed: 4 Lines added: 1, lines removed: 4
@@ -591,9 +626,10 @@ Lines added: 1, lines removed: 4
--- ---
<details><summary>Edit file: UpgradeSeqBatches.ps1</summary> Tool use: **search_replace**
undefined
<details><summary>Edit file: UpgradeSeqBatches.ps1</summary>
**Chunk 1** **Chunk 1**
Lines added: undefined, lines removed: 1 Lines added: undefined, lines removed: 1
@@ -628,7 +664,7 @@ I just pulled from work again. Let's ensure all these changes will work at home
--- ---
_**Assistant**_ _**Assistant (gpt-5)**_
<think><details><summary>Thought Process</summary>**Updating scripts for home use** <think><details><summary>Thought Process</summary>**Updating scripts for home use**
@@ -646,15 +682,21 @@ I'll resolve the merge conflict in `UpgradeSeqBatches.ps1` to the home-ready ver
--- ---
Read file: undefined Tool use: **read_file**
Read file: UpgradeSeqBatches.ps1
--- ---
Read file: undefined Tool use: **read_file**
Read file: UpdateSequences.bat
--- ---
Read file: undefined Tool use: **read_file**
Read file: UpdateSequences.ps1
--- ---
@@ -720,7 +762,7 @@ I'll resolve merge conflicts for `UpgradeSeqBatches.ps1` and `UpdateSequences.ba
--- ---
The model made no changes to the file.
--- ---
@@ -754,14 +796,20 @@ I'm going to resolve merge conflicts and home-ify the scripts. I'll replace `Upg
--- ---
Tool use: **delete_file**
Remove conflicted file so we can replace it with the home-friendly version. Remove conflicted file so we can replace it with the home-friendly version.
--- ---
Tool use: **delete_file**
Remove conflicted batch file to replace with clean home-targeting version. Remove conflicted batch file to replace with clean home-targeting version.
--- ---
Tool use: **delete_file**
Remove conflicted PowerShell script to replace with clean, merged home version. Remove conflicted PowerShell script to replace with clean, merged home version.
--- ---
@@ -804,15 +852,318 @@ I removed the conflicted files by mistake. I'll restore home-ready versions now:
--- ---
Tool use: **apply_patch**
<details>
<summary>Apply patch for UpgradeSeqBatches.ps1</summary>
```diff
*** Begin Patch
*** Add File: UpgradeSeqBatches.ps1
+# Copy the current UpdateSequences.bat to all subfolders that have it
+
+$sourceFile = "R:\\Creative\\artsy\\maya\\0 ProjectStructure\\UpdateSequences.bat"
+
+if (-not (Test-Path $sourceFile)) {
+ Write-Error "Source file not found: $sourceFile"
+ exit 1
+}
+
+Write-Host "=== Updating UpdateSequences.bat files ===" -ForegroundColor Cyan
+Write-Host "Source .bat: $sourceFile" -ForegroundColor White
+Write-Host ""
+
+# Find all UpdateSequences.bat files
+$targetFiles = Get-ChildItem -Path "R:\\Creative\\artsy\\maya" -Recurse -Filter "UpdateSequences.bat" | Where-Object { $_.FullName -ne $sourceFile }
+
+Write-Host "Found $($targetFiles.Count) target files to update:" -ForegroundColor Yellow
+foreach ($file in $targetFiles) {
+ Write-Host " - $($file.FullName)" -ForegroundColor Gray
+}
+Write-Host ""
+
+$updatedCount = 0
+$failedCount = 0
+
+foreach ($targetFile in $targetFiles) {
+ $targetDir = $targetFile.Directory.FullName
+ $targetBat = Join-Path $targetDir "UpdateSequences.bat"
+
+ try {
+ # Copy the .bat file
+ Copy-Item -Path $sourceFile -Destination $targetBat -Force
+ Write-Host "✓ Updated: $targetBat" -ForegroundColor Green
+ $updatedCount++
+ }
+ catch {
+ Write-Host "✗ Failed to update: $targetBat" -ForegroundColor Red
+ Write-Host " Error: $($_.Exception.Message)" -ForegroundColor Red
+ $failedCount++
+ }
+}
+
+Write-Host ""
+Write-Host "=== SUMMARY ===" -ForegroundColor Magenta
+Write-Host "Successfully updated: $updatedCount" -ForegroundColor Green
+Write-Host "Failed updates: $failedCount" -ForegroundColor Red
+Write-Host "Total targets: $($targetFiles.Count)" -ForegroundColor White
+
+if ($failedCount -eq 0) {
+ Write-Host "`n🎉 All UpdateSequences.bat files have been successfully updated!" -ForegroundColor Green
+} else {
+ Write-Host "`n⚠ Some files failed to update. Check the errors above." -ForegroundColor Yellow
+}
+
*** End Patch
```
--- ---
Tool use: **apply_patch**
<details>
<summary>Apply patch for UpdateSequences.bat</summary>
```diff
*** Begin Patch
*** Add File: UpdateSequences.bat
+@echo off
+setlocal EnableExtensions
+
+set "ps1=R:\\Creative\\artsy\\maya\\0 ProjectStructure\\UpdateSequences.ps1"
+echo Running PowerShell update script...
+powershell -NoProfile -ExecutionPolicy Bypass -File "%ps1%"
+set "rc=%errorlevel%"
+echo PowerShell exited with RC=%rc%
+echo( Done. Press any key to exit.
+pause >nul
+exit /b %rc%
+
*** End Patch
```
--- ---
Tool use: **apply_patch**
<details>
<summary>Apply patch for UpdateSequences.ps1</summary>
```diff
*** Begin Patch
*** Add File: UpdateSequences.ps1
+[CmdletBinding()]
+param(
+ [switch]$DebugMode
+)
+
+Set-StrictMode -Version Latest
+$ErrorActionPreference = 'Stop'
+
+function Get-YoungestTimestamp {
+ param(
+ [Parameter(Mandatory)] [string]$FolderPath
+ )
+ $files = Get-ChildItem -LiteralPath $FolderPath -Recurse -File -ErrorAction SilentlyContinue |
+ Where-Object { $_.FullName -notlike '*\_archive\*' }
+ $young = $files | Sort-Object LastWriteTime -Descending | Select-Object -First 1 -ExpandProperty LastWriteTime
+ if (-not $young) { return [datetime]::Parse('1900-01-01') }
+ return $young
+}
+
+function Sync-SequenceFilenames {
+ param(
+ [Parameter(Mandatory)] [string]$SequenceFolderPath,
+ [Parameter(Mandatory)] [string]$SequenceName,
+ [string]$LogFile,
+ [string[]]$Extensions = @('.png','.jpg','.jpeg','.exr','.tif','.tiff','.bmp','.tga')
+ )
+ $renamed = 0
+ $collisions = 0
+ $errors = 0
+ $checked = 0
+
+ if ($LogFile) { "[$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')] RENAME CHECK in '$SequenceFolderPath' (seq='$SequenceName')" | Add-Content -LiteralPath $LogFile }
+
+ $files = Get-ChildItem -LiteralPath $SequenceFolderPath -File -Recurse -ErrorAction SilentlyContinue |
+ Where-Object { $_.FullName -notlike '*\_archive\*' -and ($Extensions -contains $_.Extension.ToLower()) }
+ foreach ($f in $files) {
+ $checked++
+ $base = [System.IO.Path]::GetFileNameWithoutExtension($f.Name)
+ $ext = $f.Extension
+ $digits = $null
+
+ if ($base -match '_(\d{6})$') { $digits = $Matches[1] }
+ elseif ($base -match '(?<!_)\b(\d{6})$') { $digits = $Matches[1] }
+ elseif ($base -match '(\d{4})$') { $digits = ('00' + $Matches[1]) }
+ else { continue }
+
+ $targetBase = "$SequenceName" + '_' + $digits
+ if ($base -eq $targetBase) { continue }
+
+ $newName = $targetBase + $ext
+ $newPath = Join-Path $SequenceFolderPath $newName
+ try {
+ if (Test-Path -LiteralPath $newPath) {
+ $collisions++
+ if ($LogFile) { "[$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')] RENAME SKIP collision: '$($f.Name)' -> '$newName'" | Add-Content -LiteralPath $LogFile }
+ continue
+ }
+ Rename-Item -LiteralPath $f.FullName -NewName $newName -ErrorAction Stop
+ $renamed++
+ if ($LogFile) { "[$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')] RENAME: '$($f.Name)' -> '$newName'" | Add-Content -LiteralPath $LogFile }
+ }
+ catch {
+ $errors++
+ if ($LogFile) { "[$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')] RENAME ERROR for '$($f.Name)': $($_.Exception.Message)" | Add-Content -LiteralPath $LogFile }
+ }
+ }
+
+ return [pscustomobject]@{ Renamed=$renamed; Collisions=$collisions; Errors=$errors; Checked=$checked }
+}
+
+try {
+ $root = (Get-Location).ProviderPath
+ $currentDir = Join-Path $root '_CURRENT'
+ if (-not (Test-Path -LiteralPath $currentDir)) { New-Item -ItemType Directory -Path $currentDir -Force | Out-Null }
+
+ $logFile = Join-Path $currentDir '_UpdateSequences.log'
+ "[$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')] === UpdateSequences (ps1) started in '$root' ===" | Add-Content -LiteralPath $logFile
+
+ # Scan for folders with YYYY-MM-DD format (e.g., 2025-08-27)
+ $dailyDirs = Get-ChildItem -LiteralPath $root -Directory -Filter '????-??-??' | Where-Object { $_.Name -ne '_archive' }
+
+ $mapDaily = @{}
+ $dailiesScanned = 0
+ $filesRenamedTotal = 0
+ $renameCollisions = 0
+ $renameErrors = 0
+ foreach ($d in $dailyDirs) {
+ $dailiesScanned++
+ $seqDirs = @(Get-ChildItem -LiteralPath $d.FullName -Directory | Where-Object { $_.Name -ne '_archive' })
+ if ($seqDirs.Count -eq 0) { $seqDirs = @($d) }
+ foreach ($s in $seqDirs) {
+ if (-not (Test-Path -LiteralPath $s.FullName)) { continue }
+ $renameResult = Sync-SequenceFilenames -SequenceFolderPath $s.FullName -SequenceName $s.Name -LogFile $logFile
+ if ($DebugMode -or $renameResult.Renamed -gt 0 -or $renameResult.Collisions -gt 0 -or $renameResult.Errors -gt 0) {
+ Write-Host "[RENAME]|$($s.FullName)|$($s.Name)|checked=$($renameResult.Checked)|renamed=$($renameResult.Renamed)|collisions=$($renameResult.Collisions)|errors=$($renameResult.Errors)" -ForegroundColor Cyan
+ }
+ $filesRenamedTotal += $renameResult.Renamed
+ $renameCollisions += $renameResult.Collisions
+ $renameErrors += $renameResult.Errors
+
+ $young = Get-YoungestTimestamp -FolderPath $s.FullName
+ $filesCount = @(Get-ChildItem -LiteralPath $s.FullName -Recurse -File -ErrorAction SilentlyContinue | Where-Object { $_.FullName -notlike '*\_archive\*' }).Count
+ $seqName = $s.Name
+ $cand = [pscustomobject]@{ Seq=$seqName; SrcFull=$s.FullName; Young=$young; FilesCount=$filesCount }
+ if ($mapDaily.ContainsKey($seqName)) {
+ if ($mapDaily[$seqName].Young -lt $young) { $mapDaily[$seqName] = $cand }
+ } else { $mapDaily[$seqName] = $cand }
+ }
+ }
+
+ $mapCurrent = @{}
+ if (Test-Path -LiteralPath $currentDir) {
+ foreach ($c in Get-ChildItem -LiteralPath $currentDir -Directory | Where-Object { $_.Name -ne '_archive' }) {
+ $mapCurrent[$c.Name] = Get-YoungestTimestamp -FolderPath $c.FullName
+ }
+ }
+
+ $lines = @()
+ $lines += "[MAPCOUNT]|count=$($mapDaily.Count)"
+ $total = 0
+ $toCopy = 0
+ foreach ($k in $mapDaily.Keys) {
+ $total++
+ $d = $mapDaily[$k]
+ $curYoung = if ($mapCurrent.ContainsKey($k)) { $mapCurrent[$k] } else { [datetime]::Parse('1900-01-01') }
+ if ($d.Young -gt $curYoung) {
+ $toCopy++
+ $lines += "[COPY]|$($d.SrcFull)|$($d.Seq)|files=$($d.FilesCount)|young=$($d.Young.ToString('s'))"
+ } else {
+ $lines += "[SKIP]|$($d.SrcFull)|$($d.Seq)|reason=notNewer|srcYoung=$($d.Young.ToString('s'))|curYoung=$($curYoung.ToString('s'))"
+ }
+ }
+ $lines += "[META]|dailiesScanned=$dailiesScanned|sequencesTotal=$total|toCopy=$toCopy"
+
+ Write-Host "=== UPDATE PLAN ===" -ForegroundColor Cyan
+ foreach ($line in $lines) {
+ if ($line -like '[COPY]*') { Write-Host $line -ForegroundColor Green }
+ elseif ($line -like '[SKIP]*') { Write-Host $line -ForegroundColor Yellow }
+ else { Write-Host $line -ForegroundColor White }
+ }
+ Write-Host "==================" -ForegroundColor Cyan
+
+ $sequencesMirrored = 0
+ $mirrorFailures = 0
+ foreach ($line in $lines) {
+ if ($line.StartsWith('[COPY]')) {
+ $parts = $line -split '\|'
+ $srcFull = $parts[1]
+ $seqName = $parts[2]
+ $dstAbs = Join-Path $currentDir $seqName
+ if (-not (Test-Path -LiteralPath $dstAbs)) { New-Item -ItemType Directory -Path $dstAbs -Force | Out-Null }
+ "[$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')] Mirror: '$srcFull' -> '$dstAbs'" | Add-Content -LiteralPath $logFile
+ $robocopyArgs = @(
+ $srcFull,
+ $dstAbs,
+ '/MIR','/MT:8','/R:1','/W:1','/COPY:DAT','/DCOPY:DAT','/FFT','/NFL','/NDL','/NP','/NJH','/NJS','/XD','_archive'
+ )
+ $null = & robocopy @robocopyArgs 2>&1 | Add-Content -LiteralPath $logFile
+ $rc = $LASTEXITCODE
+ if ($rc -lt 8) { $sequencesMirrored++; "[$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')] OK rc=$rc" | Add-Content -LiteralPath $logFile }
+ else { $mirrorFailures++; "[$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')] ERROR rc=$rc" | Add-Content -LiteralPath $logFile }
+ }
+ }
+
+ Write-Host "=== SUMMARY REPORT ===" -ForegroundColor Magenta
+ Write-Host "Dailies scanned: $dailiesScanned" -ForegroundColor White
+ Write-Host "Sequences found: $total" -ForegroundColor White
+ Write-Host "Planned copies: $toCopy" -ForegroundColor Green
+ Write-Host "Completed OK: $sequencesMirrored" -ForegroundColor Green
+ Write-Host "Completed FAIL: $mirrorFailures" -ForegroundColor Red
+ Write-Host "Files renamed: $filesRenamedTotal (collisions: $renameCollisions, errors: $renameErrors)" -ForegroundColor White
+
+ $skippedLines = @()
+ foreach ($line in $lines) { if ($line.StartsWith('[SKIP]')) { $skippedLines += $line } }
+ if ($skippedLines.Count -gt 0) {
+ Write-Host "`n=== SKIPPED SEQUENCES ===" -ForegroundColor Yellow
+ $skippedByReason = @{}
+ foreach ($skip in $skippedLines) {
+ $parts = $skip -split '\|'
+ $reason = $parts[3]
+ $seqName = $parts[2]
+ if (-not $skippedByReason.ContainsKey($reason)) { $skippedByReason[$reason] = @() }
+ $skippedByReason[$reason] += $seqName
+ }
+ foreach ($reason in $skippedByReason.Keys) {
+ $seqs = $skippedByReason[$reason]
+ Write-Host "$reason ($($seqs.Count) sequences):" -ForegroundColor Yellow
+ foreach ($seq in $seqs | Sort-Object) { Write-Host " - $seq" -ForegroundColor White }
+ }
+ Write-Host "========================" -ForegroundColor Yellow
+ }
+ Write-Host "=====================" -ForegroundColor Magenta
+
+ "[$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')] === UpdateSequences (ps1) completed (d=$dailiesScanned seq=$total ok=$sequencesMirrored fail=$mirrorFailures) ===" | Add-Content -LiteralPath $logFile
+ Write-Host "@$logFile"
+ exit 0
+}
+catch {
+ $root = (Get-Location).ProviderPath
+ $currentDir = Join-Path $root '_CURRENT'
+ if (-not (Test-Path -LiteralPath $currentDir)) { New-Item -ItemType Directory -Path $currentDir -Force | Out-Null }
+ $planFile = Join-Path $currentDir '_UpdatePlan.txt'
+ ($_.Exception | Out-String) | Set-Content -LiteralPath ($planFile + '.error.txt') -Encoding ASCII
+ Write-Host "ERROR: $_"
+ exit 1
+}
+
*** End Patch
```
--- ---
@@ -894,7 +1245,7 @@ New changes, let's do it again.
--- ---
_**Assistant**_ _**Assistant (gpt-5)**_
<think><details><summary>Thought Process</summary>**Evaluating update processes** <think><details><summary>Thought Process</summary>**Evaluating update processes**
@@ -929,15 +1280,21 @@ I'll open the three scripts to reconcile with your latest changes and then make
--- ---
Read file: undefined Tool use: **read_file**
Read file: UpgradeSeqBatches.ps1
--- ---
Read file: undefined Tool use: **read_file**
Read file: UpdateSequences.bat
--- ---
Read file: undefined Tool use: **read_file**
Read file: UpdateSequences.ps1
--- ---
@@ -960,7 +1317,24 @@ I'll remove the duplicate log echo from `UpdateSequences.bat` so only the PS1 pr
--- ---
Tool use: **apply_patch**
<details>
<summary>Apply patch for UpdateSequences.bat</summary>
```diff
*** Begin Patch
*** Update File: UpdateSequences.bat
@@
echo PowerShell exited with RC=%rc%
-echo @"_CURRENT\_UpdateSequences.log"
-echo Done.
+echo Done.
pause >nul
exit /b %rc%
*** End Patch
```
--- ---

View File

@@ -0,0 +1,488 @@
<!-- Generated by SpecStory -->
<!-- cursor Session 22ad1b66-1412-4dc8-962e-ef2f925bebf4 (2025-10-30 00:40Z) -->
# Update gitignore files in project repos (2025-10-30 00:40Z)
_**User (2025-10-30 00:28Z)**_
@2025-08-08_19-32Z-setting-remote-for-local-git-repo.md @2025-08-15_18-13Z-make-file-input-draggable.md @2025-08-15_18-50Z-change-default-git-branch-to-main.md @2025-08-17_20-18Z-change-date-format-in-workflow-scripts.md @2025-08-18_21-09Z-ignore-folders-named-archive.md @2025-08-19_18-08Z-rename-images-to-match-folder-names.md @2025-08-19_15-59Z-update-latest-gitignore-file.md @2025-08-20_20-39Z-stage-all-and-commit-changes.md @2025-08-21_00-14Z-apply-changes-to-home-version.md @2025-08-21_00-15Z-implement-changes-while-respecting-home-pathing.md @2025-09-05_21-38Z-remap-non-working-material-names.md @2025-09-09_21-49Z-create-script-to-remove-fake-users.md @2025-09-11_21-52Z-move-mocap-folder-to-assets.md @2025-08-26_22-03Z-questioning-the-reason-why.md @2025-09-15_16-30Z-take-the-most-recent-changes.md @2025-09-17_19-23Z-check-blend-compression-before-saving.md @2025-10-13_17-59Z-check-git-repositories-and-uncommitted-changes.md @2025-10-07_15-36Z-check-for-uncommitted-changes-in-git-repos.md @2025-10-23_15-52Z-apply-renaming-function-to-video-previews.md @2025-10-24_02-55Z-update-destinations-in-script.md @2025-10-27_16-57Z-reapply-work-configuration-to-repository.md We updated our project structure gitignore. @gitignore I want you to enter each project repository in R:\Creative\artsy\maya\ (project repos start with dates YYYY-MM-DD) sync the changes from \components\gitignore to the .gitignore in each repo, and commit each change with "prproj gzip to LFS"
---
_**Assistant (gpt-5-codex)**_
---
Reviewing `components/gitignore` and scanning `R:\Creative\artsy\maya\` for YYYY-MM-DD project directories.
---
Tool use: **read_file**
Read file: components/gitignore
---
Tool use: **list_dir**
<details>
<summary>Listed directory undefined • **0** results</summary>
No results found
</details>
---
---
Checking a project directory to understand the structure:
---
Tool use: **read_file**
Read file: R:\Creative\artsy\maya\2025-08-02 Springtrap Prince of Egypt\.gitignore
---
Tool use: **codebase_search**
<details>
<summary>Searched codebase "How does UpgradeToGitProj merge gitignore files?" • **14** results</summary>
| File | Lines |
|------|-------|
| `UpgradeToGitProj.bat` | L66 |
| `UpgradeToGitProj.bat` | L63-114 |
| `outline.txt` | L7 |
| `UpgradeToGitProj.bat` | L201-281 |
| `NewProject.bat` | L58 |
| `components/gitignore` | L130 |
| `UpgradeToGitProj.bat` | L279-291 |
| `UpgradeToGitProj.bat` | L109-152 |
| `components/gitattributes` | L45-46 |
| `components/gitattributes` | L46 |
| `UpgradeToGitProj.bat` | L146-204 |
| `UpdateSequences.ps1` | L217-260 |
| `UpgradeSeqBatches.ps1` | L46 |
| `UpdateSequences.ps1` | L257-288 |
</details>
---
---
Clarifying a few details before creating the plan:
---
Tool use: **grep**
<details>
<summary>Grep for "^renders/|^Renders/" in "components/gitignore" • 1 match</summary>
Output mode: content
| File | Content | Line |
|------|------|------|
| `components/gitignore` | `Renders/` | L124 |
</details>
---
---
Creating the plan:
---
Tool use: **create_plan**
---
_**User (2025-10-30 00:28Z)**_
Proofread the markdown, there seems to be some hallucinatory content in there.
---
_**Assistant (gpt-5-codex)**_
<think><details><summary>Thought Process</summary>**Correcting hallucinations and typos in plan**</details></think>
---
Tool use: **create_plan**
---
_**User (2025-10-30 00:28Z)**_
Implement the plan as specified. To-do's from the plan have already been created, do not create them again.
---
_**Assistant (gpt-5-codex)**_
<think><details><summary>Thought Process</summary>**Preparing to update gitignore files**</details></think>
---
Tool use: **list_dir**
<details>
<summary>Listed directory undefined • **0** results</summary>
No results found
</details>
---
<think><details><summary>Thought Process</summary>**Identifying git repositories from dated directories**</details></think>
---
Tool use: **list_dir**
<details>
<summary>Listed directory undefined • **0** results</summary>
No results found
</details>
---
<think><details><summary>Thought Process</summary>**Verifying Git repository presence**</details></think>
---
Tool use: **read_file**
Read file: R:\Creative\artsy\maya\2025-02 BondingArtifact\.git\config
---
<think><details><summary>Thought Process</summary>**Checking and planning .gitignore update**</details></think>
---
Tool use: **read_file**
Read file: R:\Creative\artsy\maya\2025-02 BondingArtifact\.gitignore
---
<think><details><summary>Thought Process</summary>**Comparing and planning .gitignore updates**</details></think>
---
Cancelled
---
---
_**User (2025-10-30 00:28Z)**_
sorry, you got stuck.
---
_**Assistant (gpt-5-codex)**_
<think><details><summary>Thought Process</summary>**Planning directory processing with PowerShell**</details></think>
---
Tool use: **run_terminal_cmd**
```bash
cd R:\Creative\artsy\maya
Get-ChildItem -Directory | Where-Object { $_.Name -match '^[0-9]{4}-[0-9]{2}-[0-9]{2}' -and (Test-Path (Join-Path $_.FullName '.git')) } | Select-Object -ExpandProperty FullName
```
```
R:\Creative\artsy\maya\2025-07-09 LolbitNSFW
R:\Creative\artsy\maya\2025-07-11 GothFexa
R:\Creative\artsy\maya\2025-07-29 Springtrap_Goopie
R:\Creative\artsy\maya\2025-08-02 Springtrap Prince of Egypt
R:\Creative\artsy\maya\2025-08-17 DIE
```
---
<think><details><summary>Thought Process</summary>**Automating .gitignore updates across repos**
I'm drafting a PowerShell script to sync a template `.gitignore` to multiple git repos, carefully adding missing lines without duplicates and preserving newlines. The script will stage and commit changes only when needed, handling edge cases like missing files, trailing spaces, and git errors. I'll also ensure repo paths with spaces are correctly quoted for smooth execution.</details></think>
---
Tool use: **run_terminal_cmd**
```bash
cd R:\Creative\artsy\maya
$ErrorActionPreference = 'Stop'
$tplPath = 'R:\Creative\artsy\maya\0 ProjectStructure\components\gitignore'
$repos = @(
'R:\Creative\artsy\maya\2025-07-09 LolbitNSFW',
'R:\Creative\artsy\maya\2025-07-11 GothFexa',
'R:\Creative\artsy\maya\2025-07-29 Springtrap_Goopie',
'R:\Creative\artsy\maya\2025-08-02 Springtrap Prince of Egypt',
'R:\Creative\artsy\maya\2025-08-17 DIE'
)
$summary = @()
foreach ($repo in $repos) {
if (-not (Test-Path (Join-Path $repo '.git'))) {
$summary += [pscustomobject]@{Repo=$repo; Status='not-a-git-repo'}
continue
}
$dstPath = Join-Path $repo '.gitignore'
$changed = $false
if (-not (Test-Path $dstPath)) {
Copy-Item -LiteralPath $tplPath -Destination $dstPath -Force
$changed = $true
} else {
$tplLines = Get-Content -LiteralPath $tplPath
$dstLines = Get-Content -LiteralPath $dstPath
$missing = @()
foreach ($line in $tplLines) {
if ($dstLines -notcontains $line) { $missing += $line }
}
if ($missing.Count -gt 0) {
if ($dstLines.Count -gt 0 -and $dstLines[-1] -ne '') {
Add-Content -LiteralPath $dstPath -Value ''
}
Add-Content -LiteralPath $dstPath -Value $missing
$changed = $true
}
}
if ($changed) {
Push-Location $repo
git add .gitignore | Out-Null
$commitSucceeded = $true
try {
$commitOutput = git commit -m 'prproj gzip to LFS'
} catch {
$commitSucceeded = $false
$commitOutput = $_.Exception.Message
}
Pop-Location
$summary += [pscustomobject]@{Repo=$repo; Status=($(if ($commitSucceeded) {'updated'} else {'commit-failed'})); Output=$commitOutput}
} else {
$summary += [pscustomobject]@{Repo=$repo; Status='up-to-date'}
}
}
$summary
```
```
```
---
<think><details><summary>Thought Process</summary>**Analyzing missing command output**</details></think>
---
Tool use: **run_terminal_cmd**
```bash
cd R:\Creative\artsy\maya
$repos = @(
'R:\Creative\artsy\maya\2025-07-09 LolbitNSFW',
'R:\Creative\artsy\maya\2025-07-11 GothFexa',
'R:\Creative\artsy\maya\2025-07-29 Springtrap_Goopie',
'R:\Creative\artsy\maya\2025-08-02 Springtrap Prince of Egypt',
'R:\Creative\artsy\maya\2025-08-17 DIE'
)
foreach ($repo in $repos) {
Write-Host "--- $repo ---"
if (-not (Test-Path (Join-Path $repo '.git'))) {
Write-Host 'not a git repo'
continue
}
git -C $repo status --short .gitignore
}
```
```
--- R:\Creative\artsy\maya\2025-07-09 LolbitNSFW ---
--- R:\Creative\artsy\maya\2025-07-11 GothFexa ---
--- R:\Creative\artsy\maya\2025-07-29 Springtrap_Goopie ---
--- R:\Creative\artsy\maya\2025-08-02 Springtrap Prince of Egypt ---
--- R:\Creative\artsy\maya\2025-08-17 DIE ---
```
---
<think><details><summary>Thought Process</summary>**Verifying commits and changes**</details></think>
---
Tool use: **read_file**
Read file: R:\Creative\artsy\maya\2025-07-29 Springtrap_Goopie\.gitignore
---
<think><details><summary>Thought Process</summary>**Analyzing duplicate lines from template merge**</details></think>
---
Tool use: **run_terminal_cmd**
```bash
cd "R:\Creative\artsy\maya\2025-07-29 Springtrap_Goopie"
git log -1 --pretty=%s
```
```
prproj gzip to LFS
```
---
<think><details><summary>Thought Process</summary>**Summarizing repo commit statuses**
Im figuring out how to identify which repos actually got updated by checking their latest commit messages and logs, aiming to differentiate repos with real changes from those without commits. I want to produce a concise table listing each repo alongside its HEAD commit message to clearly show which ones were modified.</details></think>
---
Tool use: **run_terminal_cmd**
```bash
$repos = @(
'R:\Creative\artsy\maya\2025-07-09 LolbitNSFW',
'R:\Creative\artsy\maya\2025-07-11 GothFexa',
'R:\Creative\artsy\maya\2025-07-29 Springtrap_Goopie',
'R:\Creative\artsy\maya\2025-08-02 Springtrap Prince of Egypt',
'R:\Creative\artsy\maya\2025-08-17 DIE'
)
foreach ($repo in $repos) {
if (-not (Test-Path (Join-Path $repo '.git'))) { continue }
$subject = git -C $repo log -1 --pretty=%s
Write-Host "${repo}`n HEAD: $subject"
}
```
```
R:\Creative\artsy\maya\2025-07-09 LolbitNSFW
HEAD: prproj gzip to LFS
R:\Creative\artsy\maya\2025-07-11 GothFexa
HEAD: prproj gzip to LFS
R:\Creative\artsy\maya\2025-07-29 Springtrap_Goopie
HEAD: prproj gzip to LFS
R:\Creative\artsy\maya\2025-08-02 Springtrap Prince of Egypt
HEAD: prproj gzip to LFS
R:\Creative\artsy\maya\2025-08-17 DIE
HEAD: prproj gzip to LFS
```
---
<think><details><summary>Thought Process</summary>**Verifying .gitignore entries**</details></think>
---
Tool use: **read_file**
Read file: R:\Creative\artsy\maya\2025-08-02 Springtrap Prince of Egypt\.gitignore
---
<think><details><summary>Thought Process</summary>**Investigating case sensitivity in appended lines**</details></think>
---
spawn c:\Users\Nathan\AppData\Local\Programs\cursor\resources\app\node_modules\@vscode\ripgrep\bin\rg.exe ENOENT
---
<think><details><summary>Thought Process</summary>**Analyzing case sensitivity in line sync**</details></think>
---
Tool use: **run_terminal_cmd**
```bash
$repos = @(
'R:\Creative\artsy\maya\2025-07-09 LolbitNSFW',
'R:\Creative\artsy\maya\2025-07-11 GothFexa',
'R:\Creative\artsy\maya\2025-07-29 Springtrap_Goopie',
'R:\Creative\artsy\maya\2025-08-02 Springtrap Prince of Egypt',
'R:\Creative\artsy\maya\2025-08-17 DIE'
)
foreach ($repo in $repos) {
if (-not (Test-Path (Join-Path $repo '.git'))) { continue }
$hash = git -C $repo rev-parse --short HEAD
Write-Host "${repo}`n Commit: $hash"
}
```
```
R:\Creative\artsy\maya\2025-07-09 LolbitNSFW
Commit: de6d070
R:\Creative\artsy\maya\2025-07-11 GothFexa
Commit: e1844dc
R:\Creative\artsy\maya\2025-07-29 Springtrap_Goopie
Commit: 1ed427d
R:\Creative\artsy\maya\2025-08-02 Springtrap Prince of Egypt
Commit: 8767f6b
R:\Creative\artsy\maya\2025-08-17 DIE
Commit: a403b76
```
---
<think><details><summary>Thought Process</summary>**Preparing final summary message**</details></think>
---
## Gitignore Sync Complete
- Enumerated project repos under `R:\Creative\artsy\maya\` with names matching `YYYY-MM-DD*`; five directories were confirmed as git repositories.
- For each repo, merged `components/gitignore`:
- Copied the full template when `.gitignore` was missing.
- Otherwise appended only the template lines that were absent (e.g., new archive rule `*.7z`, capitalized `Renders/`, etc.), preserving any existing custom entries.
- Staged and committed the updates with the required message.
### Updated repositories
- `2025-07-09 LolbitNSFW` — commit `de6d070`
- `2025-07-11 GothFexa` — commit `e1844dc`
- `2025-07-29 Springtrap_Goopie` — commit `1ed427d`
- `2025-08-02 Springtrap Prince of Egypt` — commit `8767f6b`
- `2025-08-17 DIE` — commit `a403b76`
All five worked cleanly; no other repos required changes.
---

24
CONFIG.md Normal file
View File

@@ -0,0 +1,24 @@
# ProjectStructure Configuration
The repository reads user preferences from `config.json` in the ProjectStructure
root (copied alongside helper batches when they are deployed to projects).
## Keys
| Key | Type | Meaning |
| --- | --- | --- |
| `dailyFormat` | bool | `true` → daily folders named `YYYY-MM-DD`; `false``daily_*` style. |
| `structDir` | string | Absolute or relative path to the canonical ProjectStructure directory. Blank values default to the folder containing `config.json`. |
| `projectsRoot` | string (optional) | Override for the root directory scanned by `UpgradeSeqBatches.ps1`. Defaults to the parent of `structDir`. |
| `zipper` | bool | `true` → use 7Zip (if available); `false` → use Pythons built-in zipfile module. |
| `compression` | int | Compression level `0-9` (0 = store only, 9 = max). Applies to both zipfile and 7Zip. |
## Notes
- `UpdateProjectBatches.ps1` copies `config.json` and `ConfigLoader.ps1` to the
target project so the helper `.bat` launchers can resolve script locations.
- When `zipper` is `true`, the tool searches for `7z`/`7za` on `PATH`. If neither
is found it logs a warning and falls back to `zipfile`.
- Leaving `structDir` empty is safe—the scripts fall back to the directory that
contains `config.json`.

113
ConfigLoader.ps1 Normal file
View File

@@ -0,0 +1,113 @@
Set-StrictMode -Version Latest
$ErrorActionPreference = 'Stop'
$script:LoaderRoot = Split-Path -Parent $MyInvocation.MyCommand.Path
$script:ConfigPath = Join-Path -Path $script:LoaderRoot -ChildPath 'config.json'
$script:ConfigCache = $null
function Get-ProjectStructureConfig {
if ($null -ne $script:ConfigCache) {
return $script:ConfigCache
}
if (Test-Path -LiteralPath $script:ConfigPath) {
try {
$raw = Get-Content -LiteralPath $script:ConfigPath -Raw -ErrorAction Stop
if ($raw.Trim().Length -gt 0) {
$script:ConfigCache = $raw | ConvertFrom-Json
return $script:ConfigCache
}
}
catch {
Write-Warning "Failed to parse config.json: $($_.Exception.Message)"
}
}
$script:ConfigCache = [pscustomobject]@{}
return $script:ConfigCache
}
function Get-ConfigValue {
param(
[Parameter(Mandatory)] [string]$Name,
$Default = $null
)
$config = Get-ProjectStructureConfig
if ($config.PSObject.Properties.Name -contains $Name) {
$value = $config.$Name
if ($null -ne $value -and ($value -isnot [string] -or $value.Trim().Length -gt 0)) {
return $value
}
}
return $Default
}
function Get-StructDirectory {
$value = Get-ConfigValue -Name 'structDir'
if ($null -eq $value -or [string]::IsNullOrWhiteSpace($value)) {
return $script:LoaderRoot
}
if ([System.IO.Path]::IsPathRooted($value)) {
$resolved = Resolve-Path -LiteralPath $value -ErrorAction SilentlyContinue
if ($null -ne $resolved) { return $resolved.Path }
return $value
}
$candidate = Join-Path -Path $script:LoaderRoot -ChildPath $value
$resolvedCandidate = Resolve-Path -LiteralPath $candidate -ErrorAction SilentlyContinue
if ($null -ne $resolvedCandidate) { return $resolvedCandidate.Path }
return $candidate
}
function Get-ProjectsRoot {
$value = Get-ConfigValue -Name 'projectsRoot'
if ($null -eq $value -or [string]::IsNullOrWhiteSpace($value)) {
$structDir = Get-StructDirectory
$parent = Split-Path -Parent $structDir
if ($null -eq $parent -or $parent.Length -eq 0 -or $parent -eq $structDir) {
return $structDir
}
return $parent
}
if ([System.IO.Path]::IsPathRooted($value)) {
$resolved = Resolve-Path -LiteralPath $value -ErrorAction SilentlyContinue
if ($null -ne $resolved) { return $resolved.Path }
return $value
}
$candidate = Join-Path -Path $script:LoaderRoot -ChildPath $value
$resolvedCandidate = Resolve-Path -LiteralPath $candidate -ErrorAction SilentlyContinue
if ($null -ne $resolvedCandidate) { return $resolvedCandidate.Path }
return $candidate
}
function Use-IsoDailyFormat {
$dailyFormat = Get-ConfigValue -Name 'dailyFormat' -Default $true
return [bool]$dailyFormat
}
function Use-7Zip {
$zipper = Get-ConfigValue -Name 'zipper' -Default $true
return [bool]$zipper
}
function Get-ZipCompressionLevel {
$value = Get-ConfigValue -Name 'compression' -Default 9
if ($value -is [string]) {
$parsed = 0
if ([int]::TryParse($value, [ref]$parsed)) {
$value = $parsed
}
}
if ($value -isnot [int]) {
return 9
}
return [Math]::Min(9, [Math]::Max(0, $value))
}

View File

@@ -1,5 +1,27 @@
@echo off @echo off
setlocal setlocal EnableExtensions
set "SCRIPT_DIR=%~dp0"
set "CONFIG_LOADER=%SCRIPT_DIR%ConfigLoader.ps1"
set "CONFIG_PATH=%SCRIPT_DIR%config.json"
if not exist "%CONFIG_LOADER%" (
echo [ERROR] ConfigLoader.ps1 not found next to NewProject.bat.
exit /b 1
)
if not exist "%CONFIG_PATH%" (
echo [ERROR] config.json not found next to NewProject.bat.
exit /b 1
)
for /f "usebackq delims=" %%I in (`powershell -NoProfile -ExecutionPolicy Bypass -Command ^
"Set-StrictMode -Version Latest; $loader = Resolve-Path -LiteralPath '%CONFIG_LOADER%' -ErrorAction Stop; . $loader.Path; Write-Output (Get-StructDirectory)"`) do set "STRUCT_DIR=%%I"
if not defined STRUCT_DIR (
echo [ERROR] Unable to resolve ProjectStructure directory from config.
exit /b 1
)
:: Get current date in YYYY-MM-DD format :: Get current date in YYYY-MM-DD format
for /f "tokens=2-4 delims=/ " %%a in ('date /t') do ( for /f "tokens=2-4 delims=/ " %%a in ('date /t') do (
@@ -20,7 +42,7 @@ mkdir "%projectRoot%"
:: Create Assets structure :: Create Assets structure
mkdir "%projectRoot%\Assets\ElevenLabs" mkdir "%projectRoot%\Assets\ElevenLabs"
if exist "A:\1 Amazon_Active_Projects\3 ProjectStructure\NewDaily.bat" copy /Y "A:\1 Amazon_Active_Projects\3 ProjectStructure\NewDaily.bat" "%projectRoot%\Assets\ElevenLabs\NewDaily.bat" >nul if exist "%STRUCT_DIR%\NewDaily.bat" copy /Y "%STRUCT_DIR%\NewDaily.bat" "%projectRoot%\Assets\ElevenLabs\NewDaily.bat" >nul
mkdir "%projectRoot%\Assets\Blends" mkdir "%projectRoot%\Assets\Blends"
mkdir "%projectRoot%\Assets\Mocap" mkdir "%projectRoot%\Assets\Mocap"
mkdir "%projectRoot%\Assets\VO" mkdir "%projectRoot%\Assets\VO"
@@ -40,11 +62,10 @@ mkdir "%projectRoot%\Pr\RnR\RIFE"
if not exist "%projectRoot%\Renders" mkdir "%projectRoot%\Renders" if not exist "%projectRoot%\Renders" mkdir "%projectRoot%\Renders"
:: Place helper scripts into Renders :: Place helper scripts into Renders
set "templateRoot=%~dp0" set "templateRoot=%STRUCT_DIR%"
if not exist "%templateRoot%ZipSeqArchv.bat" set "templateRoot=A:\1 Amazon_Active_Projects\3 ProjectStructure\" for %%F in (UpdateSequences.bat ZipSeqArchv.bat UnzipSeqArchv.bat ConfigLoader.ps1 config.json) do (
if exist "%templateRoot%UpdateSequences.bat" copy /Y "%templateRoot%UpdateSequences.bat" "%projectRoot%\Renders\UpdateSequences.bat" >nul if exist "%templateRoot%\%%F" copy /Y "%templateRoot%\%%F" "%projectRoot%\Renders\%%F" >nul
if exist "%templateRoot%ZipSeqArchv.bat" copy /Y "%templateRoot%ZipSeqArchv.bat" "%projectRoot%\Renders\ZipSeqArchv.bat" >nul )
if exist "%templateRoot%UnzipSeqArchv.bat" copy /Y "%templateRoot%UnzipSeqArchv.bat" "%projectRoot%\Renders\UnzipSeqArchv.bat" >nul
:: Use repo-provided templates for git config files :: Use repo-provided templates for git config files
if exist "%~dp0components\gitignore" copy /Y "%~dp0components\gitignore" "%projectRoot%\.gitignore" >nul if exist "%~dp0components\gitignore" copy /Y "%~dp0components\gitignore" "%projectRoot%\.gitignore" >nul

View File

@@ -1,12 +1,29 @@
@echo off @echo off
setlocal setlocal EnableExtensions
set "REN_DIR=%~dp0" set "REN_DIR=%~dp0"
for %%I in ("%REN_DIR%..") do set "PROJ_ROOT=%%~fI" for %%I in ("%REN_DIR%..") do set "PROJ_ROOT=%%~fI"
set "PY_SCRIPT=A:\1 Amazon_Active_Projects\3 ProjectStructure\zip_sequences.py"
if not exist "%PY_SCRIPT%" ( set "CONFIG_LOADER=%REN_DIR%ConfigLoader.ps1"
echo Missing %PY_SCRIPT% set "CONFIG_PATH=%REN_DIR%config.json"
if not exist "%CONFIG_LOADER%" (
echo [ERROR] ConfigLoader.ps1 not found next to UnzipSeqArchv.bat.
echo Please run UpdateProjectBatches.ps1 to refresh helper files.
exit /b 1
)
if not exist "%CONFIG_PATH%" (
echo [ERROR] config.json not found next to UnzipSeqArchv.bat.
echo Please run UpdateProjectBatches.ps1 to refresh helper files.
exit /b 1
)
for /f "usebackq delims=" %%I in (`powershell -NoProfile -ExecutionPolicy Bypass -Command ^
"Set-StrictMode -Version Latest; $loader = Resolve-Path -LiteralPath '%CONFIG_LOADER%' -ErrorAction Stop; . $loader.Path; $pyPath = Join-Path (Get-StructDirectory) 'zip_sequences.py'; if (-not (Test-Path -LiteralPath $pyPath)) { throw \"zip_sequences.py not found at $pyPath\" }; Write-Output $pyPath"`) do set "PY_SCRIPT=%%I"
if not defined PY_SCRIPT (
echo [ERROR] Unable to resolve zip_sequences.py path from config.
exit /b 1 exit /b 1
) )

147
UpdateProjectBatches.ps1 Normal file
View File

@@ -0,0 +1,147 @@
# Refresh helper batch scripts within a specific project directory.
Set-StrictMode -Version Latest
$ErrorActionPreference = 'Stop'
param(
[string]$ProjectPath
)
if (-not $PSScriptRoot) {
$PSScriptRoot = Split-Path -Parent $MyInvocation.MyCommand.Path
}
$configLoader = Join-Path -Path $PSScriptRoot -ChildPath 'ConfigLoader.ps1'
if (-not (Test-Path -LiteralPath $configLoader)) {
throw "Missing ConfigLoader.ps1 in $PSScriptRoot"
}
. $configLoader
$structDir = Get-StructDirectory
if (-not (Test-Path -LiteralPath $structDir -PathType Container)) {
throw "Configured structDir not found: $structDir"
}
if ([string]::IsNullOrWhiteSpace($ProjectPath)) {
$ProjectPath = Read-Host 'Enter the full path to the project directory'
}
if ([string]::IsNullOrWhiteSpace($ProjectPath)) {
Write-Error 'No project directory provided.'
exit 1
}
try {
$resolvedProject = (Resolve-Path -LiteralPath $ProjectPath -ErrorAction Stop).Path
}
catch {
Write-Error "Unable to resolve project directory: $($_.Exception.Message)"
exit 1
}
if (-not (Test-Path -LiteralPath $resolvedProject -PathType Container)) {
Write-Error "Project path is not a directory: $resolvedProject"
exit 1
}
Write-Host "Project directory: $resolvedProject" -ForegroundColor Cyan
Write-Host "Struct directory: $structDir" -ForegroundColor Cyan
$specs = @(
@{ Name = 'UpdateSequences.bat'; Source = Join-Path -Path $structDir -ChildPath 'UpdateSequences.bat' },
@{ Name = 'UpdateAllSequences.bat'; Source = Join-Path -Path $structDir -ChildPath 'UpdateAllSequences.bat' },
@{ Name = 'ZipSeqArchv.bat'; Source = Join-Path -Path $structDir -ChildPath 'ZipSeqArchv.bat' },
@{ Name = 'UnzipSeqArchv.bat'; Source = Join-Path -Path $structDir -ChildPath 'UnzipSeqArchv.bat' },
@{ Name = 'NewDaily.bat'; Source = Join-Path -Path $structDir -ChildPath 'NewDaily.bat' }
)
$sharedAssets = @(
@{ Name = 'ConfigLoader.ps1'; Source = Join-Path -Path $structDir -ChildPath 'ConfigLoader.ps1' },
@{ Name = 'config.json'; Source = Join-Path -Path $structDir -ChildPath 'config.json' }
)
foreach ($spec in $specs) {
if (-not (Test-Path -LiteralPath $spec.Source -PathType Leaf)) {
Write-Error "Source file not found: $($spec.Source)"
exit 1
}
}
foreach ($asset in $sharedAssets) {
if (-not (Test-Path -LiteralPath $asset.Source -PathType Leaf)) {
Write-Error "Shared asset not found: $($asset.Source)"
exit 1
}
}
$touchedDirs = @{}
$summary = @()
foreach ($spec in $specs) {
Write-Host "`n=== Updating $($spec.Name) ===" -ForegroundColor Magenta
$targets = Get-ChildItem -LiteralPath $resolvedProject -Recurse -Filter $spec.Name -File -ErrorAction SilentlyContinue
$targets = $targets | Where-Object { $_.FullName -ne $spec.Source }
if (-not $targets) {
Write-Host "No targets found." -ForegroundColor Yellow
$summary += [pscustomobject]@{
Name = $spec.Name
Updated = 0
Failed = 0
Skipped = 0
Total = 0
}
continue
}
$updated = 0
$failed = 0
foreach ($target in $targets) {
try {
Copy-Item -Path $spec.Source -Destination $target.FullName -Force
Write-Host "$($target.FullName)" -ForegroundColor Green
$updated++
$targetDir = $target.Directory.FullName
if (-not $touchedDirs.ContainsKey($targetDir)) {
foreach ($asset in $sharedAssets) {
try {
Copy-Item -Path $asset.Source -Destination (Join-Path -Path $targetDir -ChildPath $asset.Name) -Force
}
catch {
Write-Host " ✗ Failed to copy $($asset.Name) into $targetDir: $($_.Exception.Message)" -ForegroundColor Red
}
}
$touchedDirs[$targetDir] = $true
}
}
catch {
Write-Host "$($target.FullName)" -ForegroundColor Red
Write-Host " $($_.Exception.Message)" -ForegroundColor DarkRed
$failed++
}
}
$summary += [pscustomobject]@{
Name = $spec.Name
Updated = $updated
Failed = $failed
Skipped = 0
Total = $targets.Count
}
}
Write-Host "`n=== Summary ===" -ForegroundColor Cyan
foreach ($item in $summary) {
Write-Host ("{0,-22} Updated: {1,3} Failed: {2,3} Total: {3,3}" -f $item.Name, $item.Updated, $item.Failed, $item.Total)
}
if (($summary | Measure-Object -Property Failed -Sum).Sum -gt 0) {
Write-Host "Completed with errors." -ForegroundColor Yellow
exit 1
}
Write-Host "All batch files refreshed successfully." -ForegroundColor Green

View File

@@ -1,7 +1,30 @@
@echo off @echo off
setlocal EnableExtensions setlocal EnableExtensions
set "ps1=A:\1 Amazon_Active_Projects\3 ProjectStructure\UpdateSequences.ps1" set "script_dir=%~dp0"
set "config_loader=%script_dir%ConfigLoader.ps1"
set "config_path=%script_dir%config.json"
if not exist "%config_loader%" (
echo [ERROR] ConfigLoader.ps1 not found next to UpdateSequences.bat.
echo Please run UpdateProjectBatches.ps1 to refresh helper files.
exit /b 1
)
if not exist "%config_path%" (
echo [ERROR] config.json not found next to UpdateSequences.bat.
echo Please run UpdateProjectBatches.ps1 to refresh helper files.
exit /b 1
)
for /f "usebackq delims=" %%I in (`powershell -NoProfile -ExecutionPolicy Bypass -Command ^
"Set-StrictMode -Version Latest; $loader = Resolve-Path -LiteralPath '%config_loader%' -ErrorAction Stop; . $loader.Path; $ps1Path = Join-Path (Get-StructDirectory) 'UpdateSequences.ps1'; if (-not (Test-Path -LiteralPath $ps1Path)) { throw \"UpdateSequences.ps1 not found at $ps1Path\" }; Write-Output $ps1Path"`) do set "ps1=%%I"
if not defined ps1 (
echo [ERROR] Unable to resolve UpdateSequences.ps1 path from config.
exit /b 1
)
echo Running PowerShell update script... echo Running PowerShell update script...
powershell -NoProfile -ExecutionPolicy Bypass -File "%ps1%" powershell -NoProfile -ExecutionPolicy Bypass -File "%ps1%"
set "rc=%errorlevel%" set "rc=%errorlevel%"

View File

@@ -6,6 +6,18 @@ param(
Set-StrictMode -Version Latest Set-StrictMode -Version Latest
$ErrorActionPreference = 'Stop' $ErrorActionPreference = 'Stop'
if (-not $PSScriptRoot) {
$PSScriptRoot = Split-Path -Parent $MyInvocation.MyCommand.Path
}
$configLoader = Join-Path -Path $PSScriptRoot -ChildPath 'ConfigLoader.ps1'
if (-not (Test-Path -LiteralPath $configLoader)) {
throw "Missing ConfigLoader.ps1 in $PSScriptRoot"
}
. $configLoader
$useIsoDailyFormat = Use-IsoDailyFormat
function Sync-SequenceFilenames { function Sync-SequenceFilenames {
param( param(
[Parameter(Mandatory)] [string]$SequenceFolderPath, [Parameter(Mandatory)] [string]$SequenceFolderPath,
@@ -191,9 +203,25 @@ try {
$sequenceMap = @{} $sequenceMap = @{}
$dailyDirs = Get-ChildItem -LiteralPath $root -Directory -Filter 'daily_*' -ErrorAction SilentlyContinue | $primaryPattern = if ($useIsoDailyFormat) { '????-??-??' } else { 'daily_*' }
$secondaryPattern = if ($useIsoDailyFormat) { 'daily_*' } else { '????-??-??' }
$primaryDirs = Get-ChildItem -LiteralPath $root -Directory -Filter $primaryPattern -ErrorAction SilentlyContinue |
Where-Object { $_.Name -ne '_archive' } Where-Object { $_.Name -ne '_archive' }
foreach ($d in $dailyDirs) { foreach ($d in $primaryDirs) {
$seqDirs = @(Get-ChildItem -LiteralPath $d.FullName -Directory -ErrorAction SilentlyContinue | Where-Object { $_.Name -ne '_archive' })
if ($seqDirs.Count -eq 0) {
Add-SequenceFolder -Directory $d -Map $sequenceMap
} else {
foreach ($s in $seqDirs) {
Add-SequenceFolder -Directory $s -Map $sequenceMap
}
}
}
$secondaryDirs = Get-ChildItem -LiteralPath $root -Directory -Filter $secondaryPattern -ErrorAction SilentlyContinue |
Where-Object { $_.Name -ne '_archive' }
foreach ($d in $secondaryDirs) {
$seqDirs = @(Get-ChildItem -LiteralPath $d.FullName -Directory -ErrorAction SilentlyContinue | Where-Object { $_.Name -ne '_archive' }) $seqDirs = @(Get-ChildItem -LiteralPath $d.FullName -Directory -ErrorAction SilentlyContinue | Where-Object { $_.Name -ne '_archive' })
if ($seqDirs.Count -eq 0) { if ($seqDirs.Count -eq 0) {
Add-SequenceFolder -Directory $d -Map $sequenceMap Add-SequenceFolder -Directory $d -Map $sequenceMap
@@ -205,7 +233,11 @@ try {
} }
$directSeqs = Get-ChildItem -LiteralPath $root -Directory -ErrorAction SilentlyContinue | $directSeqs = Get-ChildItem -LiteralPath $root -Directory -ErrorAction SilentlyContinue |
Where-Object { $_.Name -ne '_archive' -and $_.Name -notlike 'daily_*' } Where-Object {
$_.Name -ne '_archive' -and
$_.Name -notlike 'daily_*' -and
$_.Name -notmatch '^\d{4}-\d{2}-\d{2}$'
}
foreach ($seq in $directSeqs) { foreach ($seq in $directSeqs) {
Add-SequenceFolder -Directory $seq -Map $sequenceMap Add-SequenceFolder -Directory $seq -Map $sequenceMap
} }
@@ -241,7 +273,7 @@ try {
$renameCollisions += $renameResult.Collisions $renameCollisions += $renameResult.Collisions
$renameErrors += $renameResult.Errors $renameErrors += $renameResult.Errors
if ($renameResult.FrameCount -gt 0 -and $renameResult.MinFrame -ne $null -and $renameResult.MaxFrame -ne $null) { if ($renameResult.FrameCount -gt 0 -and $null -ne $renameResult.MinFrame -and $null -ne $renameResult.MaxFrame) {
$mp4Result = Rename-SequencePreviewMp4 -SequenceFolderPath $seq.Path -SequenceName $seq.Name -StartFrame $renameResult.MinFrame -EndFrame $renameResult.MaxFrame -LogFile $logFile $mp4Result = Rename-SequencePreviewMp4 -SequenceFolderPath $seq.Path -SequenceName $seq.Name -StartFrame $renameResult.MinFrame -EndFrame $renameResult.MaxFrame -LogFile $logFile
if ($DebugMode -or $mp4Result.Renamed -gt 0 -or $mp4Result.Collisions -gt 0 -or $mp4Result.Errors -gt 0) { if ($DebugMode -or $mp4Result.Renamed -gt 0 -or $mp4Result.Collisions -gt 0 -or $mp4Result.Errors -gt 0) {
Write-Host "[MP4]|$($seq.Path)|$($seq.Name)|renamed=$($mp4Result.Renamed)|collisions=$($mp4Result.Collisions)|errors=$($mp4Result.Errors)" -ForegroundColor Cyan Write-Host "[MP4]|$($seq.Path)|$($seq.Name)|renamed=$($mp4Result.Renamed)|collisions=$($mp4Result.Collisions)|errors=$($mp4Result.Errors)" -ForegroundColor Cyan

View File

@@ -1,65 +1,8 @@
# Update subfolders with the latest UpdateSequences and UpdateAllSequences scripts # Deprecated helper retained for compatibility.
$sourceBat = "R:\Creative\artsy\maya\0 ProjectStructure\UpdateSequences.bat" Set-StrictMode -Version Latest
$sourceAllBat = "R:\Creative\artsy\maya\0 ProjectStructure\UpdateAllSequences.bat" $ErrorActionPreference = 'Stop'
if (-not (Test-Path $sourceBat)) { Write-Error "Source file not found: $sourceBat"; exit 1 } Write-Warning 'UpgradeSeqBatches.ps1 has been deprecated.'
if (-not (Test-Path $sourceAllBat)) { Write-Error "Source file not found: $sourceAllBat"; exit 1 } Write-Warning 'Please run UpdateProjectBatches.ps1 and choose the project that needs refreshed batch files.'
exit 1
$root = "R:\Creative\artsy\maya"
$specs = @(
@{ Name = "UpdateSequences.bat"; Source = $sourceBat },
@{ Name = "UpdateAllSequences.bat"; Source = $sourceAllBat }
)
$grandTotal = 0
$grandUpdated = 0
$grandFailed = 0
foreach ($spec in $specs) {
Write-Host "=== Updating $($spec.Name) files ===" -ForegroundColor Cyan
Write-Host "Source: $($spec.Source)" -ForegroundColor White
Write-Host ""
$targets = Get-ChildItem -Path $root -Recurse -Filter $spec.Name | Where-Object { $_.FullName -ne $spec.Source }
Write-Host "Found $($targets.Count) target files to update:" -ForegroundColor Yellow
foreach ($t in $targets) { Write-Host " - $($t.FullName)" -ForegroundColor Gray }
Write-Host ""
$updated = 0
$failed = 0
foreach ($t in $targets) {
try {
Copy-Item -Path $spec.Source -Destination $t.FullName -Force
Write-Host "✓ Updated: $($t.FullName)" -ForegroundColor Green
$updated++
}
catch {
Write-Host "✗ Failed to update: $($t.FullName)" -ForegroundColor Red
Write-Host " Error: $($_.Exception.Message)" -ForegroundColor Red
$failed++
}
}
Write-Host ""
Write-Host "=== $($spec.Name) SUMMARY ===" -ForegroundColor Magenta
Write-Host "Successfully updated: $updated" -ForegroundColor Green
Write-Host "Failed updates: $failed" -ForegroundColor Red
Write-Host "Total targets: $($targets.Count)" -ForegroundColor White
Write-Host ""
$grandTotal += $targets.Count
$grandUpdated += $updated
$grandFailed += $failed
}
Write-Host "=== OVERALL SUMMARY ===" -ForegroundColor Magenta
Write-Host "Total targets across all files: $grandTotal" -ForegroundColor White
Write-Host "Total successfully updated: $grandUpdated" -ForegroundColor Green
Write-Host "Total failed: $grandFailed" -ForegroundColor Red
if ($grandFailed -eq 0) {
Write-Host "`n🎉 All files updated successfully!" -ForegroundColor Green
} else {
Write-Host "`n⚠️ Some updates failed. See errors above." -ForegroundColor Yellow
}

View File

@@ -56,6 +56,18 @@ for %%F in (UpdateSequences.bat ZipSeqArchv.bat UnzipSeqArchv.bat) do (
) )
) )
for %%F in (ConfigLoader.ps1 config.json) do (
if exist "%scriptDir%%%F" (
if "%DRY%"=="1" (
echo [DRY] copy "%scriptDir%%%F" "%rendersDir%\%%F"
) else (
copy /Y "%scriptDir%%%F" "%rendersDir%\%%F" >nul
)
) else (
echo [WARN] Missing template: "%scriptDir%%%F"
)
)
:: ----------------------------- :: -----------------------------
:: Merge .gitignore and .gitattributes from templates :: Merge .gitignore and .gitattributes from templates
:: ----------------------------- :: -----------------------------

View File

@@ -1,12 +1,29 @@
@echo off @echo off
setlocal setlocal EnableExtensions
set "REN_DIR=%~dp0" set "REN_DIR=%~dp0"
for %%I in ("%REN_DIR%..") do set "PROJ_ROOT=%%~fI" for %%I in ("%REN_DIR%..") do set "PROJ_ROOT=%%~fI"
set "PY_SCRIPT=A:\1 Amazon_Active_Projects\3 ProjectStructure\zip_sequences.py"
if not exist "%PY_SCRIPT%" ( set "CONFIG_LOADER=%REN_DIR%ConfigLoader.ps1"
echo Missing %PY_SCRIPT% set "CONFIG_PATH=%REN_DIR%config.json"
if not exist "%CONFIG_LOADER%" (
echo [ERROR] ConfigLoader.ps1 not found next to ZipSeqArchv.bat.
echo Please run UpdateProjectBatches.ps1 to refresh helper files.
exit /b 1
)
if not exist "%CONFIG_PATH%" (
echo [ERROR] config.json not found next to ZipSeqArchv.bat.
echo Please run UpdateProjectBatches.ps1 to refresh helper files.
exit /b 1
)
for /f "usebackq delims=" %%I in (`powershell -NoProfile -ExecutionPolicy Bypass -Command ^
"Set-StrictMode -Version Latest; $loader = Resolve-Path -LiteralPath '%CONFIG_LOADER%' -ErrorAction Stop; . $loader.Path; $pyPath = Join-Path (Get-StructDirectory) 'zip_sequences.py'; if (-not (Test-Path -LiteralPath $pyPath)) { throw \"zip_sequences.py not found at $pyPath\" }; Write-Output $pyPath"`) do set "PY_SCRIPT=%%I"
if not defined PY_SCRIPT (
echo [ERROR] Unable to resolve zip_sequences.py path from config.
exit /b 1 exit /b 1
) )

7
config.json Normal file
View File

@@ -0,0 +1,7 @@
{
"dailyFormat": true,
"structDir": "D:\\ProjectStructure",
"zipper": true,
"compression": 9
}

View File

@@ -11,6 +11,7 @@ from __future__ import annotations
import argparse import argparse
import json import json
import subprocess
import os import os
import shutil import shutil
import sys import sys
@@ -30,6 +31,52 @@ SEQUENCE_EXTENSIONS = {
".exr", ".exr",
} }
STATE_SUFFIX = ".meta.json" STATE_SUFFIX = ".meta.json"
CONFIG_PATH = Path(__file__).resolve().with_name("config.json")
DEFAULT_CONFIG = {
"zipper": True,
"compression": 9,
}
def load_config() -> dict:
try:
text = CONFIG_PATH.read_text(encoding="utf-8")
except FileNotFoundError:
return DEFAULT_CONFIG.copy()
except OSError:
return DEFAULT_CONFIG.copy()
try:
data = json.loads(text)
except json.JSONDecodeError:
return DEFAULT_CONFIG.copy()
if not isinstance(data, dict):
return DEFAULT_CONFIG.copy()
merged = DEFAULT_CONFIG.copy()
merged.update(data)
return merged
CONFIG = load_config()
USE_7Z = bool(CONFIG.get("zipper", True))
COMPRESSION_LEVEL = CONFIG.get("compression", 9)
if isinstance(COMPRESSION_LEVEL, str):
try:
COMPRESSION_LEVEL = int(COMPRESSION_LEVEL)
except ValueError:
COMPRESSION_LEVEL = 9
if not isinstance(COMPRESSION_LEVEL, int):
COMPRESSION_LEVEL = 9
COMPRESSION_LEVEL = max(0, min(9, COMPRESSION_LEVEL))
SEVEN_Z_EXE: str | None = None
if USE_7Z:
SEVEN_Z_EXE = shutil.which("7z") or shutil.which("7za")
if SEVEN_Z_EXE is None:
print("[zip] Requested 7z compression but no 7z executable was found; falling back to zipfile.", file=sys.stderr)
USE_7Z = False
def parse_args() -> argparse.Namespace: def parse_args() -> argparse.Namespace:
@@ -138,24 +185,55 @@ def state_path_for(zip_path: Path) -> Path:
def zip_sequence(seq_dir: Path, zip_path: Path) -> None: def zip_sequence(seq_dir: Path, zip_path: Path) -> None:
from zipfile import ZIP_STORED, ZipFile if USE_7Z and SEVEN_Z_EXE:
zip_path.parent.mkdir(parents=True, exist_ok=True)
cmd = [
SEVEN_Z_EXE,
"a",
"-y",
f"-mx={COMPRESSION_LEVEL}",
"-tzip",
str(zip_path),
".\\*",
]
subprocess.run(cmd, cwd=seq_dir, check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
return
from zipfile import ZIP_DEFLATED, ZIP_STORED, ZipFile
zip_path.parent.mkdir(parents=True, exist_ok=True) zip_path.parent.mkdir(parents=True, exist_ok=True)
with ZipFile(zip_path, "w", compression=ZIP_STORED) as archive: if COMPRESSION_LEVEL <= 0:
compression = ZIP_STORED
zip_kwargs = {}
else:
compression = ZIP_DEFLATED
zip_kwargs = {"compresslevel": COMPRESSION_LEVEL}
with ZipFile(zip_path, "w", compression=compression, **zip_kwargs) as archive:
for file_path in iter_sequence_files(seq_dir): for file_path in iter_sequence_files(seq_dir):
archive.write(file_path, arcname=file_path.relative_to(seq_dir).as_posix()) archive.write(file_path, arcname=file_path.relative_to(seq_dir).as_posix())
def expand_sequence(zip_path: Path, seq_state: dict) -> None: def expand_sequence(zip_path: Path, seq_state: dict) -> None:
from zipfile import ZipFile
target_dir = sequence_dir_for(zip_path) target_dir = sequence_dir_for(zip_path)
if target_dir.exists(): if target_dir.exists():
shutil.rmtree(target_dir) shutil.rmtree(target_dir)
target_dir.mkdir(parents=True, exist_ok=True) target_dir.mkdir(parents=True, exist_ok=True)
with ZipFile(zip_path, "r") as archive: if USE_7Z and SEVEN_Z_EXE:
archive.extractall(target_dir) cmd = [
SEVEN_Z_EXE,
"x",
"-y",
str(zip_path),
f"-o{target_dir}",
]
subprocess.run(cmd, check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
else:
from zipfile import ZipFile
with ZipFile(zip_path, "r") as archive:
archive.extractall(target_dir)
for entry in seq_state.get("files", []): for entry in seq_state.get("files", []):
file_path = target_dir / entry["path"] file_path = target_dir / entry["path"]