@firstpick/pi-package-webui 0.4.0 → 0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -5
- package/bin/pi-webui.mjs +161 -14
- package/package.json +1 -1
- package/public/app.js +715 -45
- package/public/index.html +37 -1
- package/public/styles.css +516 -4
- package/tests/http-endpoints-harness.test.mjs +42 -1
- package/tests/mobile-static.test.mjs +19 -10
|
@@ -267,7 +267,7 @@ assert.match(css, /\.composer-publish-menu:hover > \.composer-publish-button\[da
|
|
|
267
267
|
assert.match(css, /\.composer-publish-menu-panel \{[\s\S]*?display:\s*none;[\s\S]*?flex-direction:\s*column/, "Publish workflow menu should hide when closed and expand like grouped tabs");
|
|
268
268
|
assert.match(css, /\.composer-publish-menu:hover \.composer-publish-menu-panel,[\s\S]*?\.composer-publish-menu:focus-within \.composer-publish-menu-panel,[\s\S]*?\.composer-publish-menu\.open \.composer-publish-menu-panel \{\n\s+display:\s*flex;/, "Publish workflow menu should open on hover, focus, or explicit open state");
|
|
269
269
|
assert.match(css, /\.composer-native-command-button \{[\s\S]*?color:\s*var\(--ctp-mauve\)/, "skills/tools command menu should have a distinct slash-command button style");
|
|
270
|
-
assert.match(css, /\.composer-options-menu-panel \{[\s\S]*?max-height:\s*min\(
|
|
270
|
+
assert.match(css, /\.composer-options-menu-panel \{[\s\S]*?max-height:\s*min\(calc\(var\(--visual-viewport-height, 100dvh\) - 2rem\), 44rem\)/, "Options menu should be tall enough for common commands without scrolling on normal viewports");
|
|
271
271
|
assert.match(css, /\.composer-native-command-menu-item \{[\s\S]*?color:\s*var\(--ctp-mauve\)/, "skills/tools command menu items should be styled separately from publish actions");
|
|
272
272
|
assert.match(css, /\.composer-actions-panel > \.composer-publish-menu[\s\S]*?grid-column: span 1/, "Publish and command menu buttons should fit beside Git workflow in mobile actions");
|
|
273
273
|
assert.match(css, /\.composer-actions-panel[\s\S]*?bottom:\s*calc\(100% \+ 0\.42rem\)/, "mobile composer actions should open as an above-composer sheet");
|
|
@@ -561,7 +561,10 @@ assert.match(app, /\["skills", "tuiSkillsCommand"\][\s\S]*\["tools", "tuiToolsCo
|
|
|
561
561
|
assert.match(app, /function setNativeCommandMenuOpen\(open\)/, "frontend should track the skills/tools command menu open state separately from Publish");
|
|
562
562
|
assert.match(app, /nativeSkillsButton\.hidden = !isOptionalFeatureEnabled\("tuiSkillsCommand"\)[\s\S]*nativeToolsButton\.hidden = !isOptionalFeatureEnabled\("tuiToolsCommand"\)/, "skills/tools menu items should be hidden by their optional feature toggles");
|
|
563
563
|
assert.match(app, /function renderCommands\(\)/, "side-panel commands should be re-renderable from current optional feature state");
|
|
564
|
-
assert.match(app, /function installOptionalFeature\(featureId\)/, "optional features should expose
|
|
564
|
+
assert.match(app, /function installOptionalFeature\(featureId, \{ update = false \} = \{\}\)/, "optional features should expose install and update actions");
|
|
565
|
+
assert.match(app, /api\("\/api\/optional-features"/, "optional feature panel should fetch package install/update status from the backend");
|
|
566
|
+
assert.match(app, /packageStatus\?\.updateAvailable[\s\S]*action\.textContent = "Update…"/, "optional feature package drift should turn the install action into an update action");
|
|
567
|
+
assert.match(app, /optionalFeatureInstallMessages\.set\(featureId[\s\S]*waiting for package-manager output/, "optional feature installs should show running feedback while npm is active");
|
|
565
568
|
assert.match(app, /api\("\/api\/optional-feature-install"/, "optional feature install action should call the backend installer endpoint");
|
|
566
569
|
assert.match(app, /id: "safetyGuard"[\s\S]*?@firstpick\/pi-extension-safety-guard/, "optional features should include the safety guard companion");
|
|
567
570
|
assert.match(app, /id: "tuiSkillsCommand"[\s\S]*?@firstpick\/pi-extension-setup-skills/, "optional features should include the TUI skills command companion");
|
|
@@ -858,7 +861,7 @@ assert.match(css, /\.composer-actions-panel > \.composer-publish-menu:hover::aft
|
|
|
858
861
|
assert.match(css, /\.composer-actions-panel > \.composer-publish-menu \.composer-publish-menu-panel \{[\s\S]*?position:\s*absolute;[\s\S]*?inset:\s*auto auto calc\(100% \+ 0\.38rem\) 0;[\s\S]*?max-height:\s*min\(34dvh, 18rem\);[\s\S]*?overflow:\s*auto;/, "opened mobile Actions dropdown panels should float upward over the Actions controls with their own scrollbar");
|
|
859
862
|
assert.match(css, /\.composer-actions-panel > \.composer-publish-menu \.composer-publish-menu-panel \{[\s\S]*?width:\s*100%;[\s\S]*?min-width:\s*0;[\s\S]*?max-width:\s*100%;/, "mobile Actions dropdown panels should align to the width of their trigger buttons");
|
|
860
863
|
assert.match(css, /\.composer-actions-panel > \.composer-publish-menu \.composer-publish-menu-item \{[\s\S]*?width:\s*100%;[\s\S]*?min-width:\s*0;[\s\S]*?white-space:\s*normal;/, "mobile Actions dropdown option buttons should not keep desktop min-widths that misalign with triggers");
|
|
861
|
-
assert.match(css, /\.composer-actions-panel > \.composer-options-menu \.composer-publish-menu-panel \{[\s\S]*?inset-inline:\s*auto 0;[\s\S]*?max-height:\s*min\(
|
|
864
|
+
assert.match(css, /\.composer-actions-panel > \.composer-options-menu \.composer-publish-menu-panel \{[\s\S]*?inset-inline:\s*auto 0;[\s\S]*?max-height:\s*min\(calc\(var\(--visual-viewport-height, 100dvh\) - 2rem\), 44rem\);/, "mobile Options dropdown should be tall enough to avoid scrolling for the standard option list");
|
|
862
865
|
assert.match(app, /function setMobileTabsExpanded\(/, "mobile tab strip should be JS-toggleable");
|
|
863
866
|
assert.match(css, /@media \(max-width: 720px\), \(max-device-width: 720px\), \(pointer: coarse\) and \(hover: none\) \{[\s\S]*?\.terminal-tab-group \{\n\s+display:\s*grid;\n\s+grid-template-columns:\s*minmax\(0, 1fr\) auto;/, "mobile terminal tab groups should use a stable grid row for the tab and close button when expanded");
|
|
864
867
|
assert.match(css, /@media \(max-width: 720px\), \(max-device-width: 720px\), \(pointer: coarse\) and \(hover: none\) \{[\s\S]*?\.terminal-tab-group-menu \{[\s\S]*?grid-column:\s*1 \/ -1;[\s\S]*?margin:\s*0\.34rem 0 0;/, "mobile terminal tab group menus should not add horizontal margins that overflow and distort the tab card");
|
|
@@ -956,7 +959,7 @@ assert.match(server, /WEBUI_CONTROLLED_PACKAGES = new Set\(\[WEBUI_PACKAGE, \.\.
|
|
|
956
959
|
assert.match(server, /const args = \["--mode", "rpc", "--no-extensions", "--no-skills", "--no-prompt-templates", "--no-themes"\]/, "Web UI tabs should disable implicit resource loading before adding curated resource paths");
|
|
957
960
|
assert.match(server, /normalPiResourcePathsForTab[\s\S]*WEBUI_CONTROLLED_PACKAGES\.has\(packageName\)[\s\S]*continue/, "Web UI tab resource resolution should exclude separately installed Web UI feature packages");
|
|
958
961
|
assert.match(server, /startedWebuiResourcePaths\(resourceType\)/, "Web UI tabs should load feature resources from the started Web UI package");
|
|
959
|
-
assert.match(server, /
|
|
962
|
+
assert.match(server, /resolveInstalledPackageSubpath\(nodeModulesRef\.packageName, nodeModulesRef\.subpath\)/, "Web UI should prefer workspace/global/package-root installed packages for node_modules manifest entries");
|
|
960
963
|
assert.match(server, /const CODEX_TOKEN_REFRESH_SKEW_MS = 5 \* 60 \* 1000/, "server should refresh Codex OAuth tokens before they expire");
|
|
961
964
|
assert.match(server, /url\.pathname === "\/api\/codex-usage" && req\.method === "GET"/, "server should expose a sanitized Codex usage endpoint");
|
|
962
965
|
assert.match(server, /OPENAI_CODEX_USAGE_ENDPOINT/, "server should query Codex usage from the backend, not the browser");
|
|
@@ -1072,12 +1075,16 @@ assert.match(server, /const OPTIONAL_FEATURE_PACKAGES = new Map/, "server should
|
|
|
1072
1075
|
assert.match(server, /\["safetyGuard", "@firstpick\/pi-extension-safety-guard"\]/, "server should allow installing the safety guard optional feature");
|
|
1073
1076
|
assert.match(server, /\["tuiSkillsCommand", "@firstpick\/pi-extension-setup-skills"\]/, "server should allow installing the TUI skills optional feature");
|
|
1074
1077
|
assert.match(server, /\["tuiToolsCommand", "@firstpick\/pi-extension-tools"\]/, "server should allow installing the TUI tools optional feature");
|
|
1078
|
+
assert.match(server, /function optionalFeaturePackageStatus\(featureId\)/, "server should report optional feature package install/update status");
|
|
1075
1079
|
assert.match(server, /function installOptionalFeaturePackage\(featureId\)/, "server should provide optional feature package installation helper");
|
|
1076
1080
|
assert.match(server, /PI_WEBUI_OPTIONAL_FEATURE_INSTALL_ROOT/, "optional feature installs should support an explicit package-manager root override");
|
|
1077
|
-
assert.match(server, /function configuredAgentNpmRoot\(\)/, "global Web UI launches should
|
|
1078
|
-
assert.match(server, /installRootDeclaresPackage\(.*?@firstpick\/pi-package-webui/s, "optional feature installs should
|
|
1081
|
+
assert.match(server, /function configuredAgentNpmRoot\(\)/, "global Web UI launches should consider Pi's agent npm root for optional packages");
|
|
1082
|
+
assert.match(server, /installRootDeclaresPackage\(.*?@firstpick\/pi-package-webui/s, "optional feature installs should reuse a node_modules parent that declares the Web UI package dependency");
|
|
1083
|
+
assert.match(server, /installRootContainsPackage\(.*?@firstpick\/pi-package-webui/s, "global npm Web UI launches should also accept the prefix containing the Web UI package folder");
|
|
1084
|
+
assert.match(server, /resolveInstalledPackageSubpath\(nodeModulesRef\.packageName, nodeModulesRef\.subpath\)/, "started Web UI resource resolution should fall back to globally installed sibling optional packages");
|
|
1079
1085
|
assert.match(server, /if \(webuiDevServer\) return installRoot/, "source-checkout Web UI launches should still use the checkout root for optional feature installs");
|
|
1080
|
-
assert.match(server, /Could not determine a safe optional feature install root/, "optional feature installs should fail closed when no
|
|
1086
|
+
assert.match(server, /Could not determine a safe optional feature install root/, "optional feature installs should fail closed when no safe package root can be found");
|
|
1087
|
+
assert.match(server, /url\.pathname === "\/api\/optional-features" && req\.method === "GET"/, "server should expose optional feature package status endpoint");
|
|
1081
1088
|
assert.match(server, /url\.pathname === "\/api\/optional-feature-install" && req\.method === "POST"/, "server should expose optional feature install endpoint");
|
|
1082
1089
|
assert.match(server, /requireLocalhostRoute\(req, url\.pathname\)/, "optional feature install endpoint should use shared localhost trust policy");
|
|
1083
1090
|
assert.match(server, /url\.pathname === "\/api\/skill-file" && req\.method === "GET"[\s\S]*?getSkillFileData/, "server should expose GET /api/skill-file for editable skill content");
|
|
@@ -1102,6 +1109,7 @@ assert.match(readme, /Feedback reactions \(`👍`, `👎`, `\?`\) on final assis
|
|
|
1102
1109
|
assert.match(readme, /POST \/api\/action-feedback\?tab=<tabId>/, "README should document the action-feedback endpoint");
|
|
1103
1110
|
assert.match(readme, /`@` file\/path references with live suggestions/, "README should describe @ file/path reference autocomplete");
|
|
1104
1111
|
assert.match(readme, /GET \/api\/path-suggestions\?tab=<tabId>&query=<path>/, "README should document the path-suggestions endpoint");
|
|
1112
|
+
assert.match(readme, /GET \/api\/optional-features/, "README should document optional feature status endpoint");
|
|
1105
1113
|
assert.match(readme, /POST \/api\/optional-feature-install/, "README should document optional feature install endpoint");
|
|
1106
1114
|
assert.match(readme, /server-persisted fast picks/, "README should describe server-persisted fast picks");
|
|
1107
1115
|
assert.match(readme, /browser notifications when a tab needs an extension UI response and an optional side-panel toggle for agent-done notifications/, "README should describe blocked-tab and agent-done notifications");
|
|
@@ -1109,10 +1117,11 @@ assert.match(readme, /blocked-tab browser notifications, and optional agent-done
|
|
|
1109
1117
|
assert.match(readme, /Side-panel theme picker backed by optional `@firstpick\/pi-themes-bundle` themes when loaded/, "README should describe optional theme selection");
|
|
1110
1118
|
assert.match(readme, /## Optional companion packages/, "README should document optional Web UI companion packages");
|
|
1111
1119
|
assert.match(readme, /curates Pi resources from the Web UI package that started the server/, "README should document started-package-based Web UI feature loading");
|
|
1112
|
-
assert.match(readme, /
|
|
1120
|
+
assert.match(readme, /Companion packages installed as global\/npm-prefix siblings/, "README should document global sibling companion discovery");
|
|
1121
|
+
assert.match(readme, /avoiding duplicate loads while keeping global `pi-webui` launches working/, "README should document duplicate companion suppression");
|
|
1113
1122
|
assert.match(readme, /checks loaded Pi capabilities directly through RPC-visible commands and live widget events/, "README should document capability-based startup checks");
|
|
1114
|
-
assert.match(readme, /side panel shows each optional feature as enabled, disabled, or install-needed/, "README should document optional feature side-panel controls");
|
|
1115
|
-
assert.match(readme, /Installing a
|
|
1123
|
+
assert.match(readme, /side panel shows each optional feature as enabled, disabled, installed-but-not-loaded, update-available, or install-needed/, "README should document optional feature side-panel controls");
|
|
1124
|
+
assert.match(readme, /Installing or updating a feature is an explicit, warned action with running\/failure feedback/, "README should document optional feature install and update warning behavior");
|
|
1116
1125
|
assert.match(readme, /\.\/start-webui\.sh --dev --cwd \/path\/to\/project/, "README should document the dev helper launcher");
|
|
1117
1126
|
assert.match(readme, /sync-pi-package-symlinks\.sh[\s\S]*only one copy is loaded/, "README should document dev companion symlink setup");
|
|
1118
1127
|
assert.match(startScript, /--dev\)/, "start-webui.sh should accept a --dev flag");
|