parapet-rails 0.1.0
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.
- checksums.yaml +7 -0
- data/MIT-LICENSE +20 -0
- data/README.md +48 -0
- data/Rakefile +7 -0
- data/app/assets/config/parapet/grammar-registry.json +52 -0
- data/app/assets/images/parapet/icons/activities/component-inspector.svg +4 -0
- data/app/assets/images/parapet/icons/activities/coverage-heatmap.svg +3 -0
- data/app/assets/images/parapet/icons/activities/discovery-sidebar.svg +3 -0
- data/app/assets/images/parapet/icons/activities/environment-toggles.svg +4 -0
- data/app/assets/images/parapet/icons/activities/failure-inspector.svg +5 -0
- data/app/assets/images/parapet/icons/activities/flaky-history.svg +3 -0
- data/app/assets/images/parapet/icons/activities/flight-recorder.svg +5 -0
- data/app/assets/images/parapet/icons/activities/health-graph.svg +3 -0
- data/app/assets/images/parapet/icons/activities/injection-engine.svg +3 -0
- data/app/assets/images/parapet/icons/activities/live-sql-stream.svg +5 -0
- data/app/assets/images/parapet/icons/activities/live-web-preview.svg +4 -0
- data/app/assets/images/parapet/icons/activities/monaco-editor.svg +5 -0
- data/app/assets/images/parapet/icons/activities/progress-area.svg +3 -0
- data/app/assets/images/parapet/icons/activities/registry-metadata.svg +5 -0
- data/app/assets/images/parapet/icons/activities/seed-inspector.svg +4 -0
- data/app/assets/images/parapet/icons/activities/slow-test-bottlenecks.svg +4 -0
- data/app/assets/images/parapet/icons/activities/smart-search.svg +4 -0
- data/app/assets/images/parapet/icons/activities/snippet-library.svg +4 -0
- data/app/assets/images/parapet/icons/activities/terminal.svg +4 -0
- data/app/assets/images/parapet/icons/activities/unified-schema-view.svg +4 -0
- data/app/assets/images/parapet/icons/activities/visual-comparison.svg +3 -0
- data/app/assets/images/parapet/icons/activities/visual-summary-bar.svg +5 -0
- data/app/assets/images/parapet/icons/nav/ideas.svg +4 -0
- data/app/assets/images/parapet/icons/nav/languages.svg +8 -0
- data/app/assets/images/parapet/icons/nav/profile.svg +4 -0
- data/app/assets/images/parapet/icons/nav/pulse.svg +7 -0
- data/app/assets/images/parapet/icons/nav/settings.svg +4 -0
- data/app/assets/images/parapet/icons/nav/state.svg +5 -0
- data/app/assets/images/parapet/icons/nav/styles.svg +7 -0
- data/app/assets/images/parapet/icons/nav/tests.svg +4 -0
- data/app/assets/images/parapet/icons/nav/traffic.svg +12 -0
- data/app/assets/javascripts/parapet/activity-card.js +439 -0
- data/app/assets/javascripts/parapet/activity-cards.js +291 -0
- data/app/assets/javascripts/parapet/activity-registry.js +181 -0
- data/app/assets/javascripts/parapet/activity-toggles.js +76 -0
- data/app/assets/javascripts/parapet/application.js +37 -0
- data/app/assets/javascripts/parapet/card-failure-inspector.js +134 -0
- data/app/assets/javascripts/parapet/card-file-editor.js +1722 -0
- data/app/assets/javascripts/parapet/card-progress-area.js +297 -0
- data/app/assets/javascripts/parapet/card-smart-search.js +114 -0
- data/app/assets/javascripts/parapet/card-snippet-library.js +251 -0
- data/app/assets/javascripts/parapet/explorer-resizer.js +92 -0
- data/app/assets/javascripts/parapet/parapet_qss.js +342 -0
- data/app/assets/javascripts/parapet/proficiency-filter.js +53 -0
- data/app/assets/javascripts/parapet/sidebar-resizer.js +197 -0
- data/app/assets/javascripts/parapet/styles-workbench.js +819 -0
- data/app/assets/javascripts/parapet/tree-logic.js +320 -0
- data/app/assets/stylesheets/parapet/_qss_variables.scss +122 -0
- data/app/assets/stylesheets/parapet/parapet_qss.scss +69 -0
- data/app/assets/stylesheets/parapet/qss_application.css +260940 -0
- data/app/assets/stylesheets/parapet/qss_application.css.map +1 -0
- data/app/assets/stylesheets/parapet/qss_application.scss +5 -0
- data/app/assets/stylesheets/parapet/qss_workspace.scss +209 -0
- data/app/assets/stylesheets/parapet/sample.qss +22 -0
- data/app/controllers/parapet/application_controller.rb +54 -0
- data/app/controllers/parapet/base_controller.rb +18 -0
- data/app/controllers/parapet/build_suite/dashboard_controller.rb +10 -0
- data/app/controllers/parapet/css_suite/compiler_controller.rb +95 -0
- data/app/controllers/parapet/css_suite/dashboard_controller.rb +10 -0
- data/app/controllers/parapet/css_suite/preview_controller.rb +46 -0
- data/app/controllers/parapet/dashboard_controller.rb +8 -0
- data/app/controllers/parapet/drafts_controller.rb +30 -0
- data/app/controllers/parapet/explorers_controller.rb +53 -0
- data/app/controllers/parapet/files_controller.rb +208 -0
- data/app/controllers/parapet/footers_controller.rb +24 -0
- data/app/controllers/parapet/intentions_suite/dashboard_controller.rb +10 -0
- data/app/controllers/parapet/landing_controller.rb +14 -0
- data/app/controllers/parapet/monitor_suite/dashboard_controller.rb +10 -0
- data/app/controllers/parapet/pm_suite/publish_controller.rb +16 -0
- data/app/controllers/parapet/polyglot_suite/dashboard_controller.rb +10 -0
- data/app/controllers/parapet/runner_controller.rb +34 -0
- data/app/controllers/parapet/sessions_controller.rb +35 -0
- data/app/controllers/parapet/signal_suite/dashboard_controller.rb +10 -0
- data/app/controllers/parapet/test_suite/dashboard_controller.rb +10 -0
- data/app/controllers/parapet/widgets_controller.rb +33 -0
- data/app/helpers/parapet/application_helper.rb +23 -0
- data/app/helpers/parapet/icon_helper.rb +57 -0
- data/app/jobs/parapet/application_job.rb +4 -0
- data/app/mailers/parapet/application_mailer.rb +6 -0
- data/app/models/parapet/activity.rb +14 -0
- data/app/models/parapet/application_record.rb +5 -0
- data/app/models/parapet/current.rb +6 -0
- data/app/models/parapet/draft_recovery.rb +9 -0
- data/app/models/parapet/internal_record.rb +34 -0
- data/app/models/parapet/run_history.rb +22 -0
- data/app/models/parapet/runtime_setting.rb +8 -0
- data/app/models/parapet/session.rb +7 -0
- data/app/models/parapet/suite_assignment.rb +30 -0
- data/app/models/parapet/user.rb +12 -0
- data/app/services/parapet/activity_phrase_renderer.rb +35 -0
- data/app/services/parapet/activity_writer.rb +26 -0
- data/app/services/parapet/authorization.rb +198 -0
- data/app/services/parapet/consistency_auditor.rb +58 -0
- data/app/services/parapet/directory_scanner.rb +159 -0
- data/app/services/parapet/draft_recovery_store.rb +18 -0
- data/app/services/parapet/explorer_manager.rb +402 -0
- data/app/services/parapet/file_save_service.rb +21 -0
- data/app/services/parapet/git_side_ref_committer.rb +50 -0
- data/app/services/parapet/noun_discovery.rb +26 -0
- data/app/services/parapet/publish_gate.rb +83 -0
- data/app/services/parapet/test_runner.rb +178 -0
- data/app/views/layouts/parapet/application.html.erb +83 -0
- data/app/views/layouts/parapet/landing.html.erb +19 -0
- data/app/views/parapet/activities/_ai_error_explainer.html.erb +33 -0
- data/app/views/parapet/activities/_ai_explainer_widget.html.erb +20 -0
- data/app/views/parapet/activities/_calendar_widget.html.erb +31 -0
- data/app/views/parapet/activities/_code_snippets_widget.html.erb +22 -0
- data/app/views/parapet/activities/_coverage_explorer.html.erb +1 -0
- data/app/views/parapet/activities/_dropdown_test.html.erb +20 -0
- data/app/views/parapet/activities/_explorer_node.html.erb +102 -0
- data/app/views/parapet/activities/_explorer_tree.html.erb +16 -0
- data/app/views/parapet/activities/_file_editor.html.erb +183 -0
- data/app/views/parapet/activities/_file_explorer.html.erb +23 -0
- data/app/views/parapet/activities/_fix_suggestions_widget.html.erb +13 -0
- data/app/views/parapet/activities/_generic.html.erb +6 -0
- data/app/views/parapet/activities/_live_preview.html.erb +13 -0
- data/app/views/parapet/activities/_perspective_filters.html.erb +36 -0
- data/app/views/parapet/activities/_progress_area.html.erb +37 -0
- data/app/views/parapet/activities/_project_explorer.html.erb +1 -0
- data/app/views/parapet/activities/_registry_explorer.html.erb +1 -0
- data/app/views/parapet/activities/_run_history.html.erb +2 -0
- data/app/views/parapet/activities/_smart_search.html.erb +11 -0
- data/app/views/parapet/activities/file_explorer/_perspective_scripts.html.erb +58 -0
- data/app/views/parapet/activities/file_explorer/_perspectives.html.erb +0 -0
- data/app/views/parapet/activities/file_explorer/_viewport_scripts.html.erb +33 -0
- data/app/views/parapet/css_suite/_workbench.html.erb +51 -0
- data/app/views/parapet/dashboards/index.html.erb +113 -0
- data/app/views/parapet/debug_panel.html.erb +79 -0
- data/app/views/parapet/debug_panel_tailwind.html.erb +98 -0
- data/app/views/parapet/erb_patch_test.html.erb +5 -0
- data/app/views/parapet/explorers/show.html.erb +1 -0
- data/app/views/parapet/git_viewer.html.erb +62 -0
- data/app/views/parapet/git_viewer_after.html.erb +14 -0
- data/app/views/parapet/git_viewer_before.html.erb +14 -0
- data/app/views/parapet/git_viewer_governed.html.erb +88 -0
- data/app/views/parapet/git_viewer_governed_after.html.erb +36 -0
- data/app/views/parapet/git_viewer_governed_before.html.erb +36 -0
- data/app/views/parapet/git_viewer_tailwind.html.erb +88 -0
- data/app/views/parapet/git_viewer_thin_wrapper.html.erb +85 -0
- data/app/views/parapet/hierarchical_layout_test.html.erb +85 -0
- data/app/views/parapet/hybrid_stress_test.html.erb +25 -0
- data/app/views/parapet/index.html.erb +35 -0
- data/app/views/parapet/mutation_stress_test.html.erb +82 -0
- data/app/views/parapet/recursive_anchoring_test.html.erb +66 -0
- data/app/views/parapet/sessions/new.html.erb +28 -0
- data/app/views/parapet/shared/_cad_inspector.html.erb +92 -0
- data/app/views/parapet/shared/_discovery_sidebar.html.erb +48 -0
- data/app/views/parapet/shared/_explorer_bar.html.erb +71 -0
- data/app/views/parapet/shared/_footer.html.erb +10 -0
- data/app/views/parapet/shared/_footer_ideas.html.erb +36 -0
- data/app/views/parapet/shared/_footer_languages.html.erb +33 -0
- data/app/views/parapet/shared/_footer_pulse.html.erb +33 -0
- data/app/views/parapet/shared/_footer_state.html.erb +33 -0
- data/app/views/parapet/shared/_footer_styles.html.erb +37 -0
- data/app/views/parapet/shared/_footer_tests.html.erb +39 -0
- data/app/views/parapet/shared/_footer_traffic.html.erb +45 -0
- data/app/views/parapet/shared/_global_nav.html.erb +55 -0
- data/app/views/parapet/shared/_head.html.erb +4 -0
- data/app/views/parapet/shared/_header.html.erb +20 -0
- data/app/views/parapet/shared/_object_inspector.html.erb +76 -0
- data/app/views/parapet/shared/_ribbon_header.html.erb +3 -0
- data/app/views/parapet/shared/_root_selector_modal.html.erb +15 -0
- data/app/views/parapet/shared/_tab_bar.html.erb +62 -0
- data/app/views/parapet/shared/activities_ribbon/_agent_group.html.erb +15 -0
- data/app/views/parapet/shared/activities_ribbon/_analysis_group.html.erb +15 -0
- data/app/views/parapet/shared/activities_ribbon/_architect_group.html.erb +21 -0
- data/app/views/parapet/shared/activities_ribbon/_explorer_group.html.erb +12 -0
- data/app/views/parapet/shared/activities_ribbon/_inspector_group.html.erb +15 -0
- data/app/views/parapet/shared/activities_ribbon/_proficiency_filter.html.erb +24 -0
- data/app/views/parapet/shared/activities_ribbon/_runner_group.html.erb +21 -0
- data/app/views/parapet/shared/activities_ribbon/_spatial_inspector_group.html.erb +18 -0
- data/app/views/parapet/shared/activities_ribbon/_studio_group.html.erb +18 -0
- data/app/views/parapet/shared/activities_ribbon/_stylist_group.html.erb +18 -0
- data/app/views/parapet/shared/explorers/_base.html.erb +107 -0
- data/app/views/parapet/shared/explorers/_css.html.erb +1 -0
- data/app/views/parapet/shared/explorers/_intentions.html.erb +1 -0
- data/app/views/parapet/shared/explorers/_project.html.erb +1 -0
- data/app/views/parapet/shared/explorers/_tests.html.erb +1 -0
- data/app/views/parapet/shared/head/_meta.html.erb +3 -0
- data/app/views/parapet/shared/head/_styles_activities.html.erb +152 -0
- data/app/views/parapet/shared/head/_styles_shared.html.erb +52 -0
- data/app/views/parapet/shared/head/_styles_workspace.html.erb +67 -0
- data/app/views/parapet/shared/ribbon_header/_diagnostic_controls.html.erb +17 -0
- data/app/views/parapet/shared/ribbon_header/_execution_controls.html.erb +28 -0
- data/app/views/parapet/shared/ribbon_header/_focus_search.html.erb +5 -0
- data/app/views/parapet/shared/root_selector/_header.html.erb +10 -0
- data/app/views/parapet/shared/root_selector/_path_input.html.erb +13 -0
- data/app/views/parapet/shared/root_selector/_quick_select.html.erb +20 -0
- data/app/views/parapet/shared/root_selector/_scripts.html.erb +61 -0
- data/app/views/parapet/shared/root_selector/_warning.html.erb +11 -0
- data/app/views/parapet/shared/widgets/_base.html.erb +6 -0
- data/app/views/parapet/shared/widgets/_css.html.erb +79 -0
- data/app/views/parapet/widgets/_explainer.html.erb +17 -0
- data/app/views/parapet/widgets/_hotkeys.html.erb +20 -0
- data/app/views/parapet/widgets/_search.html.erb +68 -0
- data/app/views/parapet/widgets/_spatial_inspector.html.erb +54 -0
- data/app/views/parapet/widgets/_widget-explainer.html.erb +17 -0
- data/app/views/parapet/widgets/_widget-hotkeys.html.erb +20 -0
- data/app/views/parapet/widgets/_widget-search.html.erb +68 -0
- data/app/views/parapet/widgets/_widget-snippets.html.erb +18 -0
- data/app/views/parapet/widgets/_widget-suggestions.html.erb +15 -0
- data/app/views/parapet/widgets/show.html.erb +3 -0
- data/app/views/shared/_footer.html.erb +0 -0
- data/config/parapet/qss_config.yml +117 -0
- data/config/parapet/qss_registry.yml +14 -0
- data/config/routes.rb +40 -0
- data/db/migrate/20260916035300_create_run_histories.rb +16 -0
- data/db/migrate/20261002000000_expand_run_histories_for_activity_tracking.rb +7 -0
- data/db/parapet_migrate/20260929184200_create_parapet_users.rb +12 -0
- data/db/parapet_migrate/20260929184300_create_parapet_sessions.rb +9 -0
- data/db/parapet_migrate/20260930000000_create_parapet_runtime_settings.rb +12 -0
- data/db/parapet_migrate/20260930000100_create_parapet_suite_assignments.rb +14 -0
- data/db/parapet_migrate/20261002000000_create_parapet_activities.rb +16 -0
- data/db/parapet_migrate/20261002000100_create_parapet_draft_recoveries.rb +13 -0
- data/db/parapet_schema.rb +64 -0
- data/db/schema.rb +21 -0
- data/db/schema.released.rb +0 -0
- data/lib/parapet/engine.rb +11 -0
- data/lib/parapet/environment_guard.rb +14 -0
- data/lib/parapet/version.rb +3 -0
- data/lib/parapet-rails.rb +1 -0
- data/lib/parapet.rb +59 -0
- data/lib/tasks/parapet_qss.rake +26 -0
- data/lib/tasks/parapet_tasks.rake +25 -0
- data/lib/tasks/randomize_explorer_health.rb +101 -0
- metadata +423 -0
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
<!-- Studio Group -->
|
|
2
|
+
<div class="qss-ribbon-group">
|
|
3
|
+
<div class="qss-ribbon-activities">
|
|
4
|
+
<div class="qss-activity-item" data-proficiency="0" data-activity-id="file-editor" title="File Editor (N) - Studio">
|
|
5
|
+
<%= pp_icon 'monaco-editor' %>
|
|
6
|
+
</div>
|
|
7
|
+
<div class="qss-activity-item" data-proficiency="2" data-activity-id="snippet-library" title="Snippet Library (A) - Studio">
|
|
8
|
+
<%= pp_icon 'snippet-library' %>
|
|
9
|
+
</div>
|
|
10
|
+
<div class="qss-activity-item" data-proficiency="3" data-activity-id="flight-recorder" title="Flight Recorder (P) - Studio">
|
|
11
|
+
<%= pp_icon 'flight-recorder' %>
|
|
12
|
+
</div>
|
|
13
|
+
<div class="qss-activity-item" data-proficiency="3" data-activity-id="health-graph" title="Health Graph (P) - Studio">
|
|
14
|
+
<%= pp_icon 'health-graph' %>
|
|
15
|
+
</div>
|
|
16
|
+
</div>
|
|
17
|
+
<span class="qss-text-[7px] qss-font-bold qss-text-slate-500 qss-uppercase qss-tracking-tight">Studio</span>
|
|
18
|
+
</div>
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
<!-- Stylist Group -->
|
|
2
|
+
<div class="qss-ribbon-group">
|
|
3
|
+
<div class="qss-ribbon-activities">
|
|
4
|
+
<div class="qss-activity-item" data-proficiency="0" data-activity-id="live-preview" title="Live Web Preview (N) - Stylist">
|
|
5
|
+
<%= pp_icon 'live-web-preview' %>
|
|
6
|
+
</div>
|
|
7
|
+
<div class="qss-activity-item" data-proficiency="1" data-activity-id="environment-toggles" title="Environment Toggles (I) - Stylist">
|
|
8
|
+
<%= pp_icon 'environment-toggles' %>
|
|
9
|
+
</div>
|
|
10
|
+
<div class="qss-activity-item" data-proficiency="2" data-activity-id="component-inspector" title="Component Inspector (A) - Stylist">
|
|
11
|
+
<%= pp_icon 'component-inspector' %>
|
|
12
|
+
</div>
|
|
13
|
+
<div class="qss-activity-item" data-proficiency="2" data-activity-id="injection-engine" title="Injection Engine (A) - Stylist">
|
|
14
|
+
<%= pp_icon 'injection-engine' %>
|
|
15
|
+
</div>
|
|
16
|
+
</div>
|
|
17
|
+
<span class="qss-text-[7px] qss-font-bold qss-text-slate-500 qss-uppercase qss-tracking-tight">Stylist</span>
|
|
18
|
+
</div>
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
<%# locals: (type: 'project', tree_data: nil) %>
|
|
2
|
+
<%
|
|
3
|
+
type ||= 'project'
|
|
4
|
+
unless tree_data
|
|
5
|
+
seed_path = storage_path("seeds-#{type}-explorer.json")
|
|
6
|
+
if File.exist?(seed_path)
|
|
7
|
+
tree_data = JSON.parse(File.read(seed_path)).deep_symbolize_keys
|
|
8
|
+
end
|
|
9
|
+
end
|
|
10
|
+
%>
|
|
11
|
+
|
|
12
|
+
<turbo-frame id="qss-explorer-content" class="qss anchored h-full">
|
|
13
|
+
<div class="qss anchored vertical h-full">
|
|
14
|
+
<!-- Watermark -->
|
|
15
|
+
<div class="qss detached pos-x[center] pos-y[center] centered ghost opacity[15]">
|
|
16
|
+
<span class="qss anchored font-black -rotate[12] tracking-tighter text-size[36] uppercase"><%= type.upcase %></span>
|
|
17
|
+
</div>
|
|
18
|
+
|
|
19
|
+
<!-- File Tree Container -->
|
|
20
|
+
<div id="qss-explorer-tree-wrapper" class="qss anchored vertical scroll[auto] w-full h-full">
|
|
21
|
+
<%= render partial: 'parapet/activities/explorer_tree', locals: { tree_data: tree_data } %>
|
|
22
|
+
</div>
|
|
23
|
+
</div>
|
|
24
|
+
|
|
25
|
+
<script>
|
|
26
|
+
(function() {
|
|
27
|
+
const wrapper = document.getElementById('qss-explorer-tree-wrapper');
|
|
28
|
+
if (!wrapper) return;
|
|
29
|
+
|
|
30
|
+
const STORAGE_KEY = 'parapet-<%= type %>-explorer-expanded';
|
|
31
|
+
let expandedPaths = JSON.parse(localStorage.getItem(STORAGE_KEY) || 'null');
|
|
32
|
+
|
|
33
|
+
// Default expanded paths for different perspectives
|
|
34
|
+
const DEFAULT_EXPANDED = {
|
|
35
|
+
'project': ['/project-tests', 'spec', 'test', 'features', '/spec', '/test', '/features'],
|
|
36
|
+
'registry': ['/registry'],
|
|
37
|
+
'coverage': ['/coverage'],
|
|
38
|
+
'grammar': ['/grammar', '/grammar/core-syntax', '/grammar/spatial-coordinates', '/grammar/dimensions', '/grammar/visual-depth'],
|
|
39
|
+
'ideas': ['/intentions', 'controllers', 'models', 'views', 'services', 'helpers'],
|
|
40
|
+
'css': ['/styles'],
|
|
41
|
+
'tests': ['/project-tests']
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
function updateExpandedState() {
|
|
45
|
+
const raw = localStorage.getItem(STORAGE_KEY);
|
|
46
|
+
if (raw === null) {
|
|
47
|
+
expandedPaths = DEFAULT_EXPANDED['<%= type %>'] || ['/'];
|
|
48
|
+
saveState();
|
|
49
|
+
} else {
|
|
50
|
+
expandedPaths = JSON.parse(raw);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
updateExpandedState();
|
|
55
|
+
|
|
56
|
+
function saveState() {
|
|
57
|
+
localStorage.setItem(STORAGE_KEY, JSON.stringify(expandedPaths));
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function hydrate() {
|
|
61
|
+
const nodes = wrapper.querySelectorAll('.qss-explorer-node[data-type="directory"]');
|
|
62
|
+
nodes.forEach(node => {
|
|
63
|
+
const path = node.getAttribute('data-path');
|
|
64
|
+
if (expandedPaths.includes(path)) {
|
|
65
|
+
node.classList.add('qss-is-open');
|
|
66
|
+
} else {
|
|
67
|
+
node.classList.remove('qss-is-open');
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
const observer = new MutationObserver((mutations) => {
|
|
73
|
+
hydrate();
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
observer.observe(wrapper, { childList: true, subtree: true });
|
|
77
|
+
hydrate();
|
|
78
|
+
|
|
79
|
+
wrapper.addEventListener('click', (e) => {
|
|
80
|
+
const row = e.target.closest('.qss-tree-row');
|
|
81
|
+
if (!row) return;
|
|
82
|
+
|
|
83
|
+
const node = row.closest('.qss-explorer-node');
|
|
84
|
+
if (!node) return;
|
|
85
|
+
|
|
86
|
+
const path = node.getAttribute('data-path');
|
|
87
|
+
const nodeType = node.getAttribute('data-type');
|
|
88
|
+
|
|
89
|
+
if (nodeType === 'directory') {
|
|
90
|
+
e.preventDefault();
|
|
91
|
+
e.stopPropagation();
|
|
92
|
+
node.classList.toggle('qss-is-open');
|
|
93
|
+
|
|
94
|
+
setTimeout(() => {
|
|
95
|
+
const newExpanded = [];
|
|
96
|
+
wrapper.querySelectorAll('.qss-explorer-node.qss-is-open').forEach(el => {
|
|
97
|
+
const p = el.getAttribute('data-path');
|
|
98
|
+
if (p) newExpanded.push(p);
|
|
99
|
+
});
|
|
100
|
+
expandedPaths = newExpanded;
|
|
101
|
+
saveState();
|
|
102
|
+
}, 0);
|
|
103
|
+
}
|
|
104
|
+
});
|
|
105
|
+
})();
|
|
106
|
+
</script>
|
|
107
|
+
</turbo-frame>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<%= render partial: 'parapet/shared/explorers/base', locals: { type: 'css', tree_data: @tree_data } %>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<%= render partial: 'parapet/shared/explorers/base', locals: { type: 'ideas', tree_data: @tree_data } %>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<%= render partial: 'parapet/shared/explorers/base', locals: { type: 'project', tree_data: @tree_data } %>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<%= render partial: 'parapet/shared/explorers/base', locals: { type: 'tests', tree_data: @tree_data } %>
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/lucide-static@0.321.0/font/lucide.min.css">
|
|
2
|
+
<script src="https://unpkg.com/@hotwired/turbo@8.0.4/dist/turbo.es2017-umd.js"></script>
|
|
3
|
+
<script src="https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.45.0/min/vs/loader.min.js"></script>
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
<style>
|
|
2
|
+
.qss-chevron-hitbox {
|
|
3
|
+
display: flex;
|
|
4
|
+
flex-direction: column;
|
|
5
|
+
align-items: center;
|
|
6
|
+
justify-content: center;
|
|
7
|
+
cursor: pointer;
|
|
8
|
+
transition: all 0.2s ease;
|
|
9
|
+
width: 36px;
|
|
10
|
+
height: 36px;
|
|
11
|
+
border: 1px solid rgba(255, 255, 255, 0.05);
|
|
12
|
+
border-radius: 6px;
|
|
13
|
+
background: rgba(255, 255, 255, 0.02);
|
|
14
|
+
gap: 2px;
|
|
15
|
+
}
|
|
16
|
+
.qss-chevron-hitbox:hover {
|
|
17
|
+
background: rgba(255, 255, 255, 0.05);
|
|
18
|
+
border-color: rgba(255, 255, 255, 0.1);
|
|
19
|
+
}
|
|
20
|
+
.qss-chevron-bar {
|
|
21
|
+
width: 18px;
|
|
22
|
+
height: 3px;
|
|
23
|
+
clip-path: polygon(0 0, 50% 40%, 100% 0, 100% 60%, 50% 100%, 0 60%);
|
|
24
|
+
transition: all 0.2s ease;
|
|
25
|
+
pointer-events: none;
|
|
26
|
+
opacity: 0.7;
|
|
27
|
+
}
|
|
28
|
+
.qss-chevron-hitbox:hover .qss-chevron-bar,
|
|
29
|
+
.qss-chevron-hitbox:not(.off) .qss-chevron-bar {
|
|
30
|
+
opacity: 1;
|
|
31
|
+
}
|
|
32
|
+
.qss-chevron-hitbox.off .qss-chevron-bar {
|
|
33
|
+
background-color: #1e293b;
|
|
34
|
+
opacity: 0.15;
|
|
35
|
+
}
|
|
36
|
+
.qss-chevron-hitbox:not(.off) {
|
|
37
|
+
border-color: rgba(255, 255, 255, 0.15);
|
|
38
|
+
background: rgba(255, 255, 255, 0.04);
|
|
39
|
+
}
|
|
40
|
+
#qss-hitbox-novice:not(.off) { border-color: var(--novice); }
|
|
41
|
+
#qss-hitbox-intermediate:not(.off) { border-color: var(--intermediate); }
|
|
42
|
+
#qss-hitbox-advanced:not(.off) { border-color: var(--advanced); }
|
|
43
|
+
#qss-hitbox-power:not(.off) { border-color: var(--power); }
|
|
44
|
+
|
|
45
|
+
.qss-activity-item {
|
|
46
|
+
width: 36px;
|
|
47
|
+
height: 36px;
|
|
48
|
+
display: flex;
|
|
49
|
+
align-items: center;
|
|
50
|
+
justify-content: center;
|
|
51
|
+
border-radius: 6px;
|
|
52
|
+
border: 1px solid transparent;
|
|
53
|
+
transition: all 0.2s ease;
|
|
54
|
+
cursor: pointer;
|
|
55
|
+
background-color: transparent;
|
|
56
|
+
}
|
|
57
|
+
.qss-activity-item[data-proficiency="0"] { border-color: rgba(16, 185, 129, 0.2); }
|
|
58
|
+
.qss-activity-item[data-proficiency="1"] { border-color: rgba(245, 158, 11, 0.2); }
|
|
59
|
+
.qss-activity-item[data-proficiency="2"] { border-color: rgba(239, 68, 68, 0.2); }
|
|
60
|
+
.qss-activity-item[data-proficiency="3"] { border-color: rgba(139, 92, 246, 0.2); }
|
|
61
|
+
|
|
62
|
+
.qss-activity-item[data-proficiency="0"]:hover,
|
|
63
|
+
.qss-activity-item[data-proficiency="0"].qss-active { border-color: var(--novice); }
|
|
64
|
+
.qss-activity-item[data-proficiency="1"]:hover,
|
|
65
|
+
.qss-activity-item[data-proficiency="1"].qss-active { border-color: var(--intermediate); }
|
|
66
|
+
.qss-activity-item[data-proficiency="2"]:hover,
|
|
67
|
+
.qss-activity-item[data-proficiency="2"].qss-active { border-color: var(--advanced); }
|
|
68
|
+
.qss-activity-item[data-proficiency="3"]:hover,
|
|
69
|
+
.qss-activity-item[data-proficiency="3"].qss-active { border-color: var(--power); }
|
|
70
|
+
|
|
71
|
+
.qss-activity-item.qss-active { background-color: rgba(255, 255, 255, 0.03); }
|
|
72
|
+
.qss-activity-item svg { width: 24px; height: 24px; transition: all 0.2s ease; }
|
|
73
|
+
.qss-activity-item svg .icon-path { fill: #475569; stroke: #475569; }
|
|
74
|
+
.qss-activity-item.qss-active[data-proficiency="0"] svg .icon-path { fill: var(--novice); stroke: var(--novice); }
|
|
75
|
+
.qss-activity-item.qss-active[data-proficiency="1"] svg .icon-path { fill: var(--intermediate); stroke: var(--intermediate); }
|
|
76
|
+
.qss-activity-item.qss-active[data-proficiency="2"] svg .icon-path { fill: var(--advanced); stroke: var(--advanced); }
|
|
77
|
+
.qss-activity-item.qss-active[data-proficiency="3"] svg .icon-path { fill: var(--power); stroke: var(--power); }
|
|
78
|
+
|
|
79
|
+
.qss-activity-card {
|
|
80
|
+
background: transparent;
|
|
81
|
+
border: none;
|
|
82
|
+
display: flex;
|
|
83
|
+
flex-direction: column;
|
|
84
|
+
overflow: hidden;
|
|
85
|
+
padding: 3px;
|
|
86
|
+
box-sizing: border-box;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
.qss-card-inner-container {
|
|
90
|
+
background: #1a1d23;
|
|
91
|
+
border: 1px solid #334155;
|
|
92
|
+
border-radius: var(--qss-card-radius);
|
|
93
|
+
display: flex;
|
|
94
|
+
flex-direction: column;
|
|
95
|
+
width: 100%;
|
|
96
|
+
height: 100%;
|
|
97
|
+
overflow: hidden;
|
|
98
|
+
box-sizing: border-box;
|
|
99
|
+
padding: 1px;
|
|
100
|
+
transition: border-color 0.2s ease, box-shadow 0.2s ease;
|
|
101
|
+
box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.4), 0 4px 6px -2px rgba(0, 0, 0, 0.2);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
.qss-activity-card:hover .qss-card-inner-container {
|
|
105
|
+
border-color: #475569;
|
|
106
|
+
box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.4),
|
|
107
|
+
0 4px 6px -2px rgba(0, 0, 0, 0.2),
|
|
108
|
+
inset 0 0 0 1px #475569;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
.qss-activity-card.qss-pinned .qss-card-inner-container { border-color: rgba(99, 102, 241, 0.4); box-shadow: none; }
|
|
112
|
+
|
|
113
|
+
.qss-activity-card:not([class*="qss-proficiency-border"]):hover .qss-card-inner-container {
|
|
114
|
+
border-color: #475569;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
.qss-activity-card:focus-within .qss-card-inner-container, .qss-activity-card.qss-active .qss-card-inner-container {
|
|
118
|
+
border-color: rgba(99, 102, 241, 0.8);
|
|
119
|
+
box-shadow: 0 0 15px rgba(99, 102, 241, 0.2),
|
|
120
|
+
0 10px 15px -3px rgba(0, 0, 0, 0.4);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
.qss-card-header {
|
|
124
|
+
background: #111418;
|
|
125
|
+
padding: 4px 5px;
|
|
126
|
+
border-bottom: 1px solid #334155;
|
|
127
|
+
display: flex;
|
|
128
|
+
align-items: center;
|
|
129
|
+
justify-content: space-between;
|
|
130
|
+
cursor: move;
|
|
131
|
+
}
|
|
132
|
+
.qss-card-title {
|
|
133
|
+
font-size: 11px;
|
|
134
|
+
font-weight: 700;
|
|
135
|
+
text-transform: uppercase;
|
|
136
|
+
letter-spacing: 0.05em;
|
|
137
|
+
color: #94a3b8;
|
|
138
|
+
}
|
|
139
|
+
.qss-activity-card-icon svg { width: 14px; height: 14px; }
|
|
140
|
+
.qss-activity-card-icon svg .icon-path { fill: currentColor; stroke: currentColor; }
|
|
141
|
+
.qss-card-content { flex-grow: 1; padding: 8px; overflow-y: auto; position: relative; }
|
|
142
|
+
|
|
143
|
+
.qss-proficiency-border-0 .qss-card-inner-container { border-color: rgba(16, 185, 129, 0.4); }
|
|
144
|
+
.qss-proficiency-border-1 .qss-card-inner-container { border-color: rgba(245, 158, 11, 0.4); }
|
|
145
|
+
.qss-proficiency-border-2 .qss-card-inner-container { border-color: rgba(239, 68, 68, 0.4); }
|
|
146
|
+
.qss-proficiency-border-3 .qss-card-inner-container { border-color: rgba(139, 92, 246, 0.4); }
|
|
147
|
+
|
|
148
|
+
.qss-proficiency-border-0:hover .qss-card-inner-container { border-color: rgba(16, 185, 129, 0.8); box-shadow: 0 10px 15px -3px rgba(0,0,0,0.4), inset 0 0 0 1px rgba(16, 185, 129, 0.8); }
|
|
149
|
+
.qss-proficiency-border-1:hover .qss-card-inner-container { border-color: rgba(245, 158, 11, 0.8); box-shadow: 0 10px 15px -3px rgba(0,0,0,0.4), inset 0 0 0 1px rgba(245, 158, 11, 0.8); }
|
|
150
|
+
.qss-proficiency-border-2:hover .qss-card-inner-container { border-color: rgba(239, 68, 68, 0.8); box-shadow: 0 10px 15px -3px rgba(0,0,0,0.4), inset 0 0 0 1px rgba(239, 68, 68, 0.8); }
|
|
151
|
+
.qss-proficiency-border-3:hover .qss-card-inner-container { border-color: rgba(139, 92, 246, 0.8); box-shadow: 0 10px 15px -3px rgba(0,0,0,0.4), inset 0 0 0 1px rgba(139, 92, 246, 0.8); }
|
|
152
|
+
</style>
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
<style>
|
|
2
|
+
:root {
|
|
3
|
+
--novice: #10B981;
|
|
4
|
+
--intermediate: #F59E0B;
|
|
5
|
+
--advanced: #EF4444;
|
|
6
|
+
--power: #8B5CF6;
|
|
7
|
+
--qss-grid-size: 5px;
|
|
8
|
+
--qss-card-radius: 5px;
|
|
9
|
+
}
|
|
10
|
+
.qss-badge {
|
|
11
|
+
font-size: 0.6rem;
|
|
12
|
+
padding: 1px 4px;
|
|
13
|
+
border-radius: 4px;
|
|
14
|
+
color: white;
|
|
15
|
+
font-weight: bold;
|
|
16
|
+
text-transform: uppercase;
|
|
17
|
+
}
|
|
18
|
+
.bg-novice { background-color: var(--novice); }
|
|
19
|
+
.bg-intermediate { background-color: var(--intermediate); }
|
|
20
|
+
.bg-advanced { background-color: var(--advanced); }
|
|
21
|
+
.bg-power { background-color: var(--power); }
|
|
22
|
+
|
|
23
|
+
::-webkit-scrollbar { width: 7px; height: 7px; }
|
|
24
|
+
::-webkit-scrollbar-track { background: transparent; }
|
|
25
|
+
::-webkit-scrollbar-thumb {
|
|
26
|
+
background: #334155;
|
|
27
|
+
border-radius: 100px;
|
|
28
|
+
border: 1.5px solid transparent;
|
|
29
|
+
background-clip: content-box;
|
|
30
|
+
}
|
|
31
|
+
::-webkit-scrollbar-thumb:hover { background: #475569; background-clip: content-box; }
|
|
32
|
+
|
|
33
|
+
[class^="lucide-"], [class*=" lucide-"],
|
|
34
|
+
[class^="qss-icon-"], [class*=" qss-icon-"],
|
|
35
|
+
[class^="icon-"], [class*=" icon-"] {
|
|
36
|
+
font-family: 'lucide';
|
|
37
|
+
speak: none;
|
|
38
|
+
font-style: normal;
|
|
39
|
+
font-weight: normal;
|
|
40
|
+
font-variant: normal;
|
|
41
|
+
text-transform: none;
|
|
42
|
+
line-height: 1;
|
|
43
|
+
-webkit-font-smoothing: antialiased;
|
|
44
|
+
-moz-osx-font-smoothing: grayscale;
|
|
45
|
+
display: inline-flex;
|
|
46
|
+
align-items: center;
|
|
47
|
+
justify-content: center;
|
|
48
|
+
font-size: 14px;
|
|
49
|
+
width: 14px;
|
|
50
|
+
height: 14px;
|
|
51
|
+
}
|
|
52
|
+
</style>
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
<style>
|
|
2
|
+
.qss-resizer-h {
|
|
3
|
+
width: 4px;
|
|
4
|
+
cursor: col-resize;
|
|
5
|
+
background: #1e293b;
|
|
6
|
+
transition: background 0.2s;
|
|
7
|
+
display: flex;
|
|
8
|
+
align-items: center;
|
|
9
|
+
justify-content: center;
|
|
10
|
+
position: relative;
|
|
11
|
+
z-index: 100;
|
|
12
|
+
}
|
|
13
|
+
.qss-resizer-h:hover, .qss-resizer-h.active { background: #4f46e5; }
|
|
14
|
+
.qss-resizer-grip {
|
|
15
|
+
background: rgba(255, 255, 255, 0.2);
|
|
16
|
+
width: 1px;
|
|
17
|
+
height: 24px;
|
|
18
|
+
border-radius: 1px;
|
|
19
|
+
opacity: 1;
|
|
20
|
+
}
|
|
21
|
+
.qss-resizer-grip-h {
|
|
22
|
+
background: rgba(99, 102, 241, 0.4);
|
|
23
|
+
width: 32px;
|
|
24
|
+
height: 2px;
|
|
25
|
+
border-radius: 1px;
|
|
26
|
+
opacity: 1;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
header i[class^="lucide-"],
|
|
30
|
+
header i[class^="icon-"],
|
|
31
|
+
#qss-activity-icons svg,
|
|
32
|
+
.qss-tab-bar-icon,
|
|
33
|
+
.qss-command-bar-icon {
|
|
34
|
+
opacity: 0.5;
|
|
35
|
+
transition: opacity 0.2s ease;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
header i[class^="lucide-"]:hover,
|
|
39
|
+
.qss-activity-item:hover svg,
|
|
40
|
+
.qss-activity-item.qss-active svg,
|
|
41
|
+
.h-8:hover .qss-tab-bar-icon,
|
|
42
|
+
button:hover .qss-command-bar-icon {
|
|
43
|
+
opacity: 0.8;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
.qss-workspace-layer {
|
|
47
|
+
position: absolute;
|
|
48
|
+
top: 60px;
|
|
49
|
+
left: 0;
|
|
50
|
+
right: 0;
|
|
51
|
+
bottom: 0;
|
|
52
|
+
pointer-events: none;
|
|
53
|
+
display: flex;
|
|
54
|
+
flex-wrap: wrap;
|
|
55
|
+
align-content: flex-start;
|
|
56
|
+
padding: 8px;
|
|
57
|
+
gap: 8px;
|
|
58
|
+
overflow: hidden;
|
|
59
|
+
}
|
|
60
|
+
.qss-workspace-layer .qss-activity-card { pointer-events: auto; }
|
|
61
|
+
|
|
62
|
+
.qss-layer-novice { z-index: 10; }
|
|
63
|
+
.qss-layer-intermediate { z-index: 20; }
|
|
64
|
+
.qss-layer-advanced { z-index: 30; }
|
|
65
|
+
.qss-layer-power { z-index: 40; }
|
|
66
|
+
.qss-layer-floating { z-index: 100; }
|
|
67
|
+
</style>
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
<!-- Section: Diagnostic & Debugging -->
|
|
2
|
+
<div class="qss-flex qss-items-center qss-gap-1">
|
|
3
|
+
<button class="qss-w-[67px] qss-h-[22px] qss-text-center qss-border qss-border-amber-500/20 qss-text-amber-500/50 qss-text-[11px] qss-rounded hover:qss-text-amber-500/70 hover:qss-bg-amber-600/10 qss-transition-colors qss-tracking-tight proficiency-target" data-proficiency="1">Headful</button>
|
|
4
|
+
<button class="qss-w-[67px] qss-h-[22px] qss-text-center qss-border qss-border-red-500/20 qss-text-red-500/50 qss-text-[11px] qss-rounded hover:qss-text-red-500/70 hover:qss-bg-red-600/10 qss-transition-colors qss-tracking-tight proficiency-target" data-proficiency="2">Full Trace</button>
|
|
5
|
+
<button class="qss-w-[67px] qss-h-[22px] qss-text-center qss-border qss-border-red-500/20 qss-text-red-500/50 qss-text-[11px] qss-rounded hover:qss-text-red-500/70 hover:qss-bg-red-600/10 qss-transition-colors qss-tracking-tight proficiency-target" data-proficiency="2">Baseline</button>
|
|
6
|
+
<button class="qss-w-[67px] qss-h-[22px] qss-text-center qss-border qss-border-violet-500/20 qss-text-violet-500/50 qss-text-[11px] qss-rounded hover:qss-text-violet-500/70 hover:qss-bg-violet-600/10 qss-transition-colors qss-tracking-tight proficiency-target" data-proficiency="3">Bisection</button>
|
|
7
|
+
<button class="qss-w-[67px] qss-h-[22px] qss-text-center qss-border qss-border-violet-500/20 qss-text-violet-500/50 qss-text-[11px] qss-rounded hover:qss-text-violet-500/70 hover:qss-bg-violet-600/10 qss-transition-colors qss-tracking-tight proficiency-target" data-proficiency="3">Profile</button>
|
|
8
|
+
<button class="qss-w-[67px] qss-h-[22px] qss-text-center qss-border qss-border-amber-500/20 qss-text-amber-500/50 qss-text-[11px] qss-rounded hover:qss-text-amber-500/70 hover:qss-bg-amber-600/10 qss-transition-colors qss-tracking-tight proficiency-target" data-proficiency="1">Warnings</button>
|
|
9
|
+
|
|
10
|
+
<!-- Utility Icons -->
|
|
11
|
+
<button class="qss-px-2 qss-h-[22px] qss-border qss-border-red-500/20 qss-text-red-500/50 qss-text-[11px] qss-rounded hover:qss-text-red-500/70 hover:qss-bg-red-600/10 qss-transition-colors qss-flex qss-items-center qss-gap-1.5 proficiency-target" data-proficiency="2" title="Debug Context">
|
|
12
|
+
<svg class="command-bar-icon" viewBox="0 0 24 24" width="11" height="11" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><rect width="8" height="14" x="8" y="2" rx="4"/><path d="m19 7-3 2"/><path d="m5 7 3 2"/><path d="m19 19-3-2"/><path d="m5 19 3-2"/><path d="M20 13h-4"/><path d="M4 13h4"/><path d="m10 19 1 2"/><path d="m14 19-1 2"/></svg>
|
|
13
|
+
</button>
|
|
14
|
+
<button class="qss-px-2 qss-h-[22px] qss-border qss-border-emerald-500/20 qss-text-emerald-500/50 qss-text-[11px] qss-rounded hover:qss-text-emerald-500/70 hover:qss-bg-emerald-600/10 qss-transition-colors qss-flex qss-items-center qss-gap-1.5 proficiency-target" data-proficiency="0" title="Clear Terminal">
|
|
15
|
+
<svg class="command-bar-icon" viewBox="0 0 24 24" width="11" height="11" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><path d="M3 6h18"/><path d="M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6"/><path d="M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2"/><line x1="10" x2="10" y1="11" y2="17"/><line x1="14" x2="14" y1="11" y2="17"/></svg>
|
|
16
|
+
</button>
|
|
17
|
+
</div>
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
<!-- Primary Action: Run (Novice - Green) -->
|
|
2
|
+
<button class="qss-h-[26px] qss-bg-emerald-600/10 qss-text-emerald-500/70 qss-border qss-border-emerald-500/20 qss-px-4 qss-rounded qss-text-[11px] qss-flex qss-items-center qss-gap-1.5 hover:qss-bg-emerald-600/20 qss-transition-colors qss-tracking-tight proficiency-target qss-whitespace-nowrap qss-flex-shrink-0" data-proficiency="0">
|
|
3
|
+
<svg class="command-bar-icon" viewBox="0 0 24 24" width="12" height="12" stroke="currentColor" stroke-width="2.5" fill="currentColor" stroke-linecap="round" stroke-linejoin="round"><polygon points="5 3 19 12 5 21 5 3"></polygon></svg>
|
|
4
|
+
Run All
|
|
5
|
+
</button>
|
|
6
|
+
|
|
7
|
+
<!-- Rerun (Novice - Green) -->
|
|
8
|
+
<button class="qss-w-[42px] qss-h-[22px] qss-flex qss-items-center qss-justify-center qss-bg-emerald-600/10 qss-text-emerald-500/70 qss-border qss-border-emerald-500/20 qss-rounded hover:qss-bg-emerald-600/20 qss-transition-colors proficiency-target" data-proficiency="0" title="Rerun Failed">
|
|
9
|
+
<svg class="command-bar-icon" viewBox="0 0 24 24" width="12" height="12" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><path d="M21 2v6h-6"></path><path d="M3 12a9 9 0 0 1 15-6.7L21 8"></path><path d="M3 22v-6h6"></path><path d="M21 12a9 9 0 0 1-15 6.7L3 16"></path></svg>
|
|
10
|
+
</button>
|
|
11
|
+
|
|
12
|
+
<!-- Stop (Novice - Green) -->
|
|
13
|
+
<button class="qss-w-[42px] qss-h-[22px] qss-flex qss-items-center qss-justify-center qss-bg-emerald-600/10 qss-text-emerald-500/70 qss-border qss-border-emerald-500/20 qss-rounded hover:qss-bg-emerald-600/20 qss-transition-colors proficiency-target" data-proficiency="0" title="Stop All Processes">
|
|
14
|
+
<svg class="command-bar-icon" viewBox="0 0 24 24" width="12" height="12" fill="currentColor" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><rect x="6" y="6" width="12" height="12"></rect></svg>
|
|
15
|
+
</button>
|
|
16
|
+
|
|
17
|
+
<div class="qss-w-px qss-h-3 qss-bg-slate-800 qss-mx-0.5 proficiency-target" data-proficiency="0"></div>
|
|
18
|
+
|
|
19
|
+
<div class="qss-flex qss-items-center qss-gap-1">
|
|
20
|
+
<!-- Section: Execution Control -->
|
|
21
|
+
<button class="qss-w-[67px] qss-h-[22px] qss-text-center qss-border qss-border-emerald-500/20 qss-text-emerald-500/50 qss-text-[11px] qss-rounded hover:qss-text-emerald-500/70 hover:qss-bg-emerald-600/10 qss-transition-colors qss-tracking-tight proficiency-target" data-proficiency="0">Fail Fast</button>
|
|
22
|
+
<button class="qss-px-3 qss-h-[22px] qss-border qss-border-amber-500/20 qss-text-amber-500/50 qss-text-[11px] qss-rounded hover:qss-text-amber-500/70 hover:qss-bg-amber-600/10 qss-transition-colors qss-tracking-tight proficiency-target" data-proficiency="1">Randomize</button>
|
|
23
|
+
<button class="qss-w-[67px] qss-h-[22px] qss-text-center qss-bg-amber-600/10 qss-text-amber-500/70 qss-text-[11px] qss-rounded qss-border qss-border-amber-500/20 qss-tracking-tight proficiency-target" data-proficiency="1">Failures Only</button>
|
|
24
|
+
<button class="qss-w-[67px] qss-h-[22px] qss-text-center qss-border qss-border-amber-500/20 qss-text-amber-500/50 qss-text-[11px] qss-rounded hover:qss-text-amber-500/70 hover:qss-bg-amber-600/10 qss-tracking-tight proficiency-target" data-proficiency="1">Watch: <span class="qss-text-amber-500/70">ON</span></button>
|
|
25
|
+
<button class="qss-w-[67px] qss-h-[22px] qss-text-center qss-border qss-border-amber-500/20 qss-text-amber-500/50 qss-text-[11px] qss-rounded hover:qss-text-amber-500/70 hover:qss-bg-amber-600/10 qss-transition-colors qss-tracking-tight proficiency-target" data-proficiency="1">Dry Run</button>
|
|
26
|
+
<button class="qss-w-[67px] qss-h-[22px] qss-text-center qss-border qss-border-amber-500/20 qss-text-amber-500/50 qss-text-[11px] qss-rounded hover:qss-text-amber-500/70 hover:qss-bg-amber-600/10 qss-transition-colors qss-tracking-tight proficiency-target" data-proficiency="1">Seed Reset</button>
|
|
27
|
+
<button class="qss-w-[67px] qss-h-[22px] qss-text-center qss-border qss-border-red-500/20 qss-text-red-500/50 qss-text-[11px] qss-rounded hover:qss-text-red-500/70 hover:qss-bg-red-600/10 qss-transition-colors qss-tracking-tight proficiency-target" data-proficiency="2">Parallel</button>
|
|
28
|
+
</div>
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
<!-- Filter Scope (Matches Run All Height) -->
|
|
2
|
+
<div class="qss-flex qss-items-center qss-bg-slate-800/30 qss-border qss-border-slate-700 qss-rounded qss-h-[26px] qss-px-2 qss-gap-2 proficiency-target" data-proficiency="0">
|
|
3
|
+
<span class="qss-text-[10px] qss-font-bold qss-text-slate-500 qss-uppercase qss-tracking-tight qss-whitespace-nowrap">Focus:</span>
|
|
4
|
+
<input type="text" placeholder="@metadata, #status, :type" class="qss-bg-transparent qss-border-none qss-outline-none qss-text-[11px] qss-text-slate-300 qss-w-48 placeholder:qss-text-slate-600 qss-font-medium">
|
|
5
|
+
</div>
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
<!-- Header -->
|
|
2
|
+
<div class="qss-px-4 qss-py-3 qss-border-b qss-border-slate-700 qss-flex qss-items-center qss-justify-between qss-bg-[#111418]">
|
|
3
|
+
<div class="qss-flex qss-items-center qss-gap-2">
|
|
4
|
+
<i class="icon-folder-tree qss-text-amber-500"></i>
|
|
5
|
+
<h3 class="qss-text-xs qss-font-bold qss-uppercase qss-tracking-wider qss-text-slate-200">Select Suite Root</h3>
|
|
6
|
+
</div>
|
|
7
|
+
<button onclick="closeRootModal()" class="qss-text-slate-500 hover:qss-text-white qss-transition-colors">
|
|
8
|
+
<i class="icon-x qss-text-size[16]"></i>
|
|
9
|
+
</button>
|
|
10
|
+
</div>
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
<!-- Path Input -->
|
|
2
|
+
<div class="qss-p-4 qss-border-b qss-border-slate-800 qss-flex qss-flex-col qss-gap-2">
|
|
3
|
+
<label class="qss-text-[9px] qss-uppercase qss-font-bold qss-text-slate-500">Manual Path Entrance</label>
|
|
4
|
+
<div class="qss-flex qss-gap-2">
|
|
5
|
+
<input type="text" id="root-path-input"
|
|
6
|
+
class="qss-flex-1 qss-bg-[#0f1115] qss-border qss-border-slate-800 qss-rounded qss-px-2 qss-py-1.5 qss-text-xs qss-text-slate-300 qss-font-mono qss-outline-none focus:qss-border-indigo-500 qss-transition-colors"
|
|
7
|
+
placeholder="e.g. /test or /spec">
|
|
8
|
+
<button onclick="confirmRootSelection()"
|
|
9
|
+
class="qss-px-4 qss-py-1.5 qss-bg-indigo-600 hover:qss-bg-indigo-500 qss-text-white qss-text-[10px] qss-font-bold qss-uppercase qss-rounded qss-transition-all qss-shadow-lg qss-shadow-indigo-600/20">
|
|
10
|
+
Apply
|
|
11
|
+
</button>
|
|
12
|
+
</div>
|
|
13
|
+
</div>
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
<!-- Selection Area -->
|
|
2
|
+
<div class="qss-flex-1 qss-overflow-y-auto qss-p-4 qss-flex qss-flex-col qss-gap-3 custom-scrollbar">
|
|
3
|
+
<div class="qss-flex qss-flex-col qss-gap-2">
|
|
4
|
+
<span class="qss-text-[9px] qss-uppercase qss-font-bold qss-text-slate-500">Workspace Contexts</span>
|
|
5
|
+
<div class="qss-grid qss-grid-cols-1 qss-gap-1">
|
|
6
|
+
<button onclick="selectQuickRoot('test')" class="qss-flex qss-items-center qss-gap-2 qss-px-3 qss-py-2 qss-rounded qss-bg-white/5 hover:qss-bg-white/10 qss-border qss-border-transparent hover:qss-border-slate-600 qss-transition-all qss-text-left qss-group">
|
|
7
|
+
<i class="icon-beaker qss-text-amber-500"></i>
|
|
8
|
+
<span class="qss-text-xs qss-text-slate-300 group-hover:qss-text-white">Test Suite (/test)</span>
|
|
9
|
+
</button>
|
|
10
|
+
<button onclick="selectQuickRoot('app')" class="qss-flex qss-items-center qss-gap-2 qss-px-3 qss-py-2 qss-rounded qss-bg-white/5 hover:qss-bg-white/10 qss-border qss-border-transparent hover:qss-border-slate-600 qss-transition-all qss-text-left qss-group">
|
|
11
|
+
<i class="icon-cpu qss-text-blue-400"></i>
|
|
12
|
+
<span class="qss-text-xs qss-text-slate-300 group-hover:qss-text-white">Application Source (/app)</span>
|
|
13
|
+
</button>
|
|
14
|
+
<button onclick="selectQuickRoot('/')" class="qss-flex qss-items-center qss-gap-2 qss-px-3 qss-py-2 qss-rounded qss-bg-white/5 hover:qss-bg-white/10 qss-border qss-border-red-900/30 hover:qss-border-red-500/50 qss-transition-all qss-text-left qss-group">
|
|
15
|
+
<i class="icon-alert-triangle qss-text-red-500"></i>
|
|
16
|
+
<span class="qss-text-xs qss-text-slate-300 group-hover:qss-text-white">Full Project Root (Warning: Exposure)</span>
|
|
17
|
+
</button>
|
|
18
|
+
</div>
|
|
19
|
+
</div>
|
|
20
|
+
</div>
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
<script>
|
|
2
|
+
function openRootModal() {
|
|
3
|
+
const modal = document.getElementById('root-selector-modal');
|
|
4
|
+
const input = document.getElementById('root-path-input');
|
|
5
|
+
const suite = document.getElementById('sidebar-title')?.textContent?.trim() || 'default';
|
|
6
|
+
const currentRoot = localStorage.getItem(`parapet-root-${suite}`) || '/test';
|
|
7
|
+
|
|
8
|
+
input.value = currentRoot;
|
|
9
|
+
modal.classList.remove('qss-hidden');
|
|
10
|
+
modal.classList.add('qss-flex');
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
function closeRootModal() {
|
|
14
|
+
const modal = document.getElementById('root-selector-modal');
|
|
15
|
+
modal.classList.add('qss-hidden');
|
|
16
|
+
modal.classList.remove('qss-flex');
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function selectQuickRoot(path) {
|
|
20
|
+
document.getElementById('root-path-input').value = path;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function confirmRootSelection() {
|
|
24
|
+
const path = document.getElementById('root-path-input').value;
|
|
25
|
+
const suite = document.getElementById('sidebar-title')?.textContent?.trim() || 'default';
|
|
26
|
+
|
|
27
|
+
localStorage.setItem(`parapet-root-${suite}`, path);
|
|
28
|
+
|
|
29
|
+
// Update label immediately
|
|
30
|
+
const label = document.getElementById('current-root-label');
|
|
31
|
+
if (label) label.textContent = path.startsWith('/') ? path : '/' + path;
|
|
32
|
+
|
|
33
|
+
closeRootModal();
|
|
34
|
+
|
|
35
|
+
// Trigger reload of explorer content based on active perspective
|
|
36
|
+
const activeBtn = document.querySelector('.perspective-btn.active');
|
|
37
|
+
if (activeBtn) {
|
|
38
|
+
activeBtn.click();
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function syncRootLabel() {
|
|
43
|
+
const suite = document.getElementById('sidebar-title')?.textContent?.trim() || 'default';
|
|
44
|
+
const currentRoot = localStorage.getItem(`parapet-root-${suite}`) || '/test';
|
|
45
|
+
const label = document.getElementById('current-root-label');
|
|
46
|
+
if (label) {
|
|
47
|
+
label.textContent = currentRoot.startsWith('/') ? currentRoot : '/' + currentRoot;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// Global delegation for the pill
|
|
52
|
+
document.addEventListener('click', (e) => {
|
|
53
|
+
const pill = e.target.closest('#root-selector-pill');
|
|
54
|
+
if (pill) {
|
|
55
|
+
openRootModal();
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
document.addEventListener('turbo:load', syncRootLabel);
|
|
60
|
+
document.addEventListener('turbo:render', syncRootLabel);
|
|
61
|
+
</script>
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
<!-- Warning Area -->
|
|
2
|
+
<div class="qss-px-4 qss-py-3 qss-bg-amber-500/5 qss-border-b qss-border-amber-500/10 qss-flex qss-gap-3">
|
|
3
|
+
<i class="icon-alert-triangle qss-text-amber-500 qss-flex-shrink-0 qss-mt-0.5" style="font-size: 14px;"></i>
|
|
4
|
+
<div class="qss-flex qss-flex-col qss-gap-1">
|
|
5
|
+
<span class="qss-text-[10px] qss-font-bold qss-text-amber-500 qss-uppercase">Warning: Structural Exposure</span>
|
|
6
|
+
<p class="qss-text-[10px] qss-text-amber-600/80 qss-leading-relaxed">
|
|
7
|
+
Setting a new root will expose the underlying filesystem from that point downward.
|
|
8
|
+
Ensure you only select directories relevant to the current suite to avoid performance degradation or accidental modification of sensitive files.
|
|
9
|
+
</p>
|
|
10
|
+
</div>
|
|
11
|
+
</div>
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
<turbo-frame id="qss-widget-content" class="anchored vertical h-full">
|
|
2
|
+
<div class="anchored vertical p[8] gap[4] centered h-full">
|
|
3
|
+
<i class="icon-info text-slate-700 text-size[12] mb[4]"></i>
|
|
4
|
+
<span class="anchored text-size[7] text-slate-500 italic">No suite-specific monitors available for this context.</span>
|
|
5
|
+
</div>
|
|
6
|
+
</turbo-frame>
|