Skip to content

Commit 9a066d1

Browse files
committed
Remove duplicate Session Library actions and make saved session cards authoritative - PR_11_268
1 parent 9231999 commit 9a066d1

7 files changed

Lines changed: 207 additions & 13 deletions
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
# PR_11_268 Workspace V2 Session Library Action Cleanup Report
2+
3+
## Scope
4+
Workspace V2 Session Library only.
5+
6+
## Files Changed
7+
- tools/workspace-v2/index.html
8+
- tools/workspace-v2/index.js
9+
- tests/runtime/V2SessionLibraryActionCleanup.test.mjs
10+
- tests/runtime/V2SessionLibraryActions.test.mjs
11+
- docs/pr/PLAN_PR_11_268_WORKSPACE_V2_SESSION_LIBRARY_ACTION_CLEANUP.md
12+
- docs/pr/BUILD_PR_11_268_WORKSPACE_V2_SESSION_LIBRARY_ACTION_CLEANUP.md
13+
- docs/dev/reports/PR_11_268_workspace_v2_session_library_action_cleanup_report.md
14+
15+
## Implementation Summary
16+
- Session Library input area now communicates "new save" intent:
17+
- Label changed to `New Session ID (Save Session)`.
18+
- Helper text updated to direct management to Saved Sessions cards.
19+
- Top action controls cleaned up:
20+
- `Save Session` remains visible.
21+
- Top `Overwrite Session`, `Load Session`, `Delete Saved Session` are hidden.
22+
- Saved-session card actions remain authoritative for existing entries:
23+
- `Copy ID`
24+
- `Use in Diff/Merge`
25+
- `Load`
26+
- `Delete Saved`
27+
- Save messaging updated for clarity:
28+
- Duplicate ID: `Saved session already exists. Manage it from its Saved Sessions card.`
29+
- Save success: `Saved session created. Manage this session from its Saved Sessions card.`
30+
31+
## Validation Commands
32+
1. `node --check tools/workspace-v2/index.js`
33+
- PASS
34+
2. `node --check tests/runtime/V2SessionLibraryActionCleanup.test.mjs`
35+
- PASS
36+
3. `node --check tests/runtime/V2SessionLibraryActions.test.mjs`
37+
- PASS
38+
4. `node tests/runtime/V2SessionLibraryActionCleanup.test.mjs`
39+
- PASS
40+
- Results: `tmp/v2-session-library-action-cleanup-results.json`
41+
5. `node tests/runtime/V2SessionLibraryActions.test.mjs`
42+
- PASS
43+
- Results: `tmp/v2-session-library-actions-results.json`
44+
45+
## Full Samples Smoke Decision
46+
- Skipped full samples smoke test.
47+
- Reason: changes are limited to Workspace V2 Session Library UI/action messaging and covered by targeted runtime tests.
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# BUILD_PR_11_268_WORKSPACE_V2_SESSION_LIBRARY_ACTION_CLEANUP
2+
3+
## Purpose
4+
Remove duplicate Session Library action paths and make card-level actions authoritative for existing saved sessions.
5+
6+
## Files
7+
- tools/workspace-v2/index.html
8+
- tools/workspace-v2/index.js
9+
- tests/runtime/V2SessionLibraryActionCleanup.test.mjs
10+
- tests/runtime/V2SessionLibraryActions.test.mjs
11+
- docs/dev/reports/PR_11_268_workspace_v2_session_library_action_cleanup_report.md
12+
13+
## Implementation
14+
1. Update Session Library input label/help text to "new save" workflow language.
15+
2. Keep top `Save Session` action visible.
16+
3. Hide top Overwrite/Load/Delete controls.
17+
4. Keep existing row/card actions for existing saved sessions.
18+
5. Update save duplicate/success messages to card-management wording.
19+
6. Update targeted tests to match cleaned action model.
20+
21+
## Acceptance
22+
- No duplicate top-level paths for load/delete/overwrite.
23+
- Saved-session cards remain the authoritative controls for existing entries.
24+
- Save success clearly directs users to card-level management.
25+
- No unrelated Workspace V2 areas changed.
26+
27+
## Validation
28+
- node --check tools/workspace-v2/index.js
29+
- node --check tests/runtime/V2SessionLibraryActionCleanup.test.mjs
30+
- node --check tests/runtime/V2SessionLibraryActions.test.mjs
31+
- node tests/runtime/V2SessionLibraryActionCleanup.test.mjs
32+
- node tests/runtime/V2SessionLibraryActions.test.mjs
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
# PLAN_PR_11_268_WORKSPACE_V2_SESSION_LIBRARY_ACTION_CLEANUP
2+
3+
## Purpose
4+
Clean up Workspace V2 Session Library actions to remove duplicate/confusing top-level controls.
5+
6+
## Scope
7+
- tools/workspace-v2/index.html
8+
- tools/workspace-v2/index.js
9+
- tests/runtime/V2SessionLibraryActionCleanup.test.mjs
10+
- tests/runtime/V2SessionLibraryActions.test.mjs
11+
- docs/report only
12+
13+
## Goals
14+
- Keep saved-session card actions as authoritative for existing saved sessions.
15+
- Top Session Library input area supports creating new saved sessions only (`Save Session`).
16+
- Hide top Overwrite/Load/Delete controls to eliminate duplicate action paths.
17+
- Ensure save status message directs management to Saved Sessions cards.
18+
- Keep messages current-state-specific and non-stale.
19+
20+
## Out of Scope
21+
- No schema changes
22+
- No cross-tool changes
23+
- No merge/diff algorithm changes
24+
25+
## Validation
26+
- node --check tools/workspace-v2/index.js
27+
- node --check tests/runtime/V2SessionLibraryActionCleanup.test.mjs
28+
- node --check tests/runtime/V2SessionLibraryActions.test.mjs
29+
- node tests/runtime/V2SessionLibraryActionCleanup.test.mjs
30+
- node tests/runtime/V2SessionLibraryActions.test.mjs
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
import assert from "node:assert/strict";
2+
import fs from "node:fs";
3+
import path from "node:path";
4+
import { execFileSync } from "node:child_process";
5+
import { fileURLToPath, pathToFileURL } from "node:url";
6+
7+
const __filename = fileURLToPath(import.meta.url);
8+
const __dirname = path.dirname(__filename);
9+
const repoRoot = path.resolve(__dirname, "..", "..");
10+
const htmlPath = path.join(repoRoot, "tools", "workspace-v2", "index.html");
11+
const jsPath = path.join(repoRoot, "tools", "workspace-v2", "index.js");
12+
const testPath = path.join(repoRoot, "tests", "runtime", "V2SessionLibraryActionCleanup.test.mjs");
13+
const resultsPath = path.join(repoRoot, "tmp", "v2-session-library-action-cleanup-results.json");
14+
15+
function checkSyntax(filePath) {
16+
try {
17+
execFileSync(process.execPath, ["--check", filePath], {
18+
cwd: repoRoot,
19+
stdio: ["ignore", "pipe", "pipe"]
20+
});
21+
return { ok: true, error: "" };
22+
} catch (error) {
23+
return { ok: false, error: (error?.stderr || error?.stdout || error?.message || "").toString().trim() };
24+
}
25+
}
26+
27+
export function run() {
28+
const failures = [];
29+
const htmlExists = fs.existsSync(htmlPath);
30+
const jsExists = fs.existsSync(jsPath);
31+
const html = htmlExists ? fs.readFileSync(htmlPath, "utf8") : "";
32+
const js = jsExists ? fs.readFileSync(jsPath, "utf8") : "";
33+
const jsSyntax = checkSyntax(jsPath);
34+
const testSyntax = checkSyntax(testPath);
35+
36+
if (!htmlExists) failures.push("Missing tools/workspace-v2/index.html.");
37+
if (!jsExists) failures.push("Missing tools/workspace-v2/index.js.");
38+
if (!jsSyntax.ok) failures.push("tools/workspace-v2/index.js failed syntax check.");
39+
if (!testSyntax.ok) failures.push("tests/runtime/V2SessionLibraryActionCleanup.test.mjs failed syntax check.");
40+
41+
const requiredHtmlTokens = [
42+
'<label for="workspaceV2SessionName">New Session ID (Save Session)</label>',
43+
'<button id="workspaceV2SaveSessionButton" type="button">Save Session</button>',
44+
'<button id="workspaceV2OverwriteSessionButton" type="button" hidden>Overwrite Session</button>',
45+
'<button id="workspaceV2LoadSessionButton" type="button" hidden>Load Session</button>',
46+
'<button id="workspaceV2DeleteSessionButton" type="button" hidden>Delete Saved Session</button>',
47+
'Use Save Session to create a new saved entry. Manage existing saved sessions from their Saved Sessions cards.'
48+
];
49+
requiredHtmlTokens.forEach((token) => {
50+
if (!html.includes(token)) failures.push(`Missing expected Session Library cleanup HTML token: ${token}`);
51+
});
52+
53+
const requiredJsTokens = [
54+
'this.setLibraryStatus("Saved session already exists. Manage it from its Saved Sessions card.");',
55+
'Saved session created. Manage this session from its Saved Sessions card.',
56+
'loadButton.textContent = "Load";',
57+
'deleteSavedButton.textContent = "Delete Saved";',
58+
'useInLibraryButton.textContent = "Use in Diff/Merge";'
59+
];
60+
requiredJsTokens.forEach((token) => {
61+
if (!js.includes(token)) failures.push(`Missing expected Session Library cleanup JS token: ${token}`);
62+
});
63+
64+
fs.mkdirSync(path.dirname(resultsPath), { recursive: true });
65+
fs.writeFileSync(resultsPath, `${JSON.stringify({
66+
generatedAt: new Date().toISOString(),
67+
failures,
68+
checks: { htmlExists, jsExists, jsSyntax, testSyntax }
69+
}, null, 2)}
70+
`, "utf8");
71+
72+
console.log(`v2 session-library-action-cleanup results: ${resultsPath}`);
73+
assert.equal(failures.length, 0, `V2 session-library-action-cleanup failures: ${failures.join(" | ")}`);
74+
return { failures };
75+
}
76+
77+
if (process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href) {
78+
try {
79+
const summary = run();
80+
console.log(JSON.stringify(summary, null, 2));
81+
} catch (error) {
82+
console.error(error);
83+
process.exitCode = 1;
84+
}
85+
}

tests/runtime/V2SessionLibraryActions.test.mjs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,10 @@ function evaluateSaveAction(inputId, activePayload, library) {
3737
return { message: "No active Workspace V2 session is available to save.", library: libraryMap };
3838
}
3939
if (Object.prototype.hasOwnProperty.call(libraryMap, sessionId)) {
40-
return { message: "Saved session already exists. Use Overwrite Session.", library: libraryMap };
40+
return { message: "Saved session already exists. Manage it from its Saved Sessions card.", library: libraryMap };
4141
}
4242
libraryMap[sessionId] = activePayload;
43-
return { message: "Saved session created. New session ID is now available for Load, Overwrite, and Delete.", library: libraryMap };
43+
return { message: "Saved session created. Manage this session from its Saved Sessions card.", library: libraryMap };
4444
}
4545

4646
function evaluateOverwriteAction(inputId, activePayload, library) {
@@ -131,8 +131,8 @@ export function run() {
131131
const requiredMessages = [
132132
"Enter a session ID before saving.",
133133
"No active Workspace V2 session is available to save.",
134-
"Saved session already exists. Use Overwrite Session.",
135-
"Saved session created. New session ID is now available for Load, Overwrite, and Delete.",
134+
"Saved session already exists. Manage it from its Saved Sessions card.",
135+
"Saved session created. Manage this session from its Saved Sessions card.",
136136
"Enter a session ID before overwriting.",
137137
"No active Workspace V2 session is available to overwrite from.",
138138
"Saved session not found. Use Save Session to create it first.",
@@ -174,12 +174,12 @@ export function run() {
174174
if (emptyDelete.message !== "Enter a saved session ID before deleting.") failures.push("Delete empty input message mismatch.");
175175

176176
const saveCreated = evaluateSaveAction("saved-a", activePayload, {});
177-
if (saveCreated.message !== "Saved session created. New session ID is now available for Load, Overwrite, and Delete." || !Object.prototype.hasOwnProperty.call(saveCreated.library, "saved-a")) {
177+
if (saveCreated.message !== "Saved session created. Manage this session from its Saved Sessions card." || !Object.prototype.hasOwnProperty.call(saveCreated.library, "saved-a")) {
178178
failures.push("Save with valid active payload should create library entry.");
179179
}
180180

181181
const duplicateSave = evaluateSaveAction("saved-a", activePayload, { "saved-a": { toolId: "palette-manager-v2", version: "v2" } });
182-
if (duplicateSave.message !== "Saved session already exists. Use Overwrite Session.") {
182+
if (duplicateSave.message !== "Saved session already exists. Manage it from its Saved Sessions card.") {
183183
failures.push("Duplicate save should be blocked with overwrite guidance.");
184184
}
185185

tools/workspace-v2/index.html

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -57,14 +57,14 @@ <h2>Share Session Link</h2>
5757

5858
<section class="hub-panel">
5959
<h2>Session Library</h2>
60-
<label for="workspaceV2SessionName">Session ID (for Save / Load / Delete)</label>
60+
<label for="workspaceV2SessionName">New Session ID (Save Session)</label>
6161
<input id="workspaceV2SessionName" type="text" placeholder="session-id" />
62-
<p>Saved sessions are stored in Session Library. Recent sessions are temporary.</p>
62+
<p>Use Save Session to create a new saved entry. Manage existing saved sessions from their Saved Sessions cards.</p>
6363
<div>
6464
<button id="workspaceV2SaveSessionButton" type="button">Save Session</button>
65-
<button id="workspaceV2OverwriteSessionButton" type="button">Overwrite Session</button>
66-
<button id="workspaceV2LoadSessionButton" type="button">Load Session</button>
67-
<button id="workspaceV2DeleteSessionButton" type="button">Delete Saved Session</button>
65+
<button id="workspaceV2OverwriteSessionButton" type="button" hidden>Overwrite Session</button>
66+
<button id="workspaceV2LoadSessionButton" type="button" hidden>Load Session</button>
67+
<button id="workspaceV2DeleteSessionButton" type="button" hidden>Delete Saved Session</button>
6868
</div>
6969
<p id="workspaceV2LibraryStatus">No Session Library action yet.</p>
7070
<p id="workspaceV2LibraryEmptyState">No saved sessions in library.</p>

tools/workspace-v2/index.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2743,7 +2743,7 @@ class WorkspaceV2SessionProducer {
27432743
return;
27442744
}
27452745
if (!overwriteExisting && exists) {
2746-
this.setLibraryStatus("Saved session already exists. Use Overwrite Session.");
2746+
this.setLibraryStatus("Saved session already exists. Manage it from its Saved Sessions card.");
27472747
return;
27482748
}
27492749
const payloadForWrite = this.readSessionPayloadForSaveAction(sessionName);
@@ -2758,7 +2758,7 @@ class WorkspaceV2SessionProducer {
27582758
this.renderSessionLibrary();
27592759
this.setLibraryStatus(overwriteExisting
27602760
? "Saved session overwritten."
2761-
: "Saved session created. New session ID is now available for Load, Overwrite, and Delete.");
2761+
: "Saved session created. Manage this session from its Saved Sessions card.");
27622762
}
27632763

27642764
loadNamedSession() {

0 commit comments

Comments
 (0)