total-recall-brain 3.41.2 → 3.41.4

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.
Files changed (128) hide show
  1. package/bin/total-recall.mjs +19 -4
  2. package/frontend/dist/assets/{index-BG9NkVUy.css → index-BIQmqDKP.css} +1 -1
  3. package/frontend/dist/assets/{index-BtuiZqwP.js → index-CRzjQLu7.js} +7 -7
  4. package/frontend/dist/index.html +2 -2
  5. package/frontend/dist/sw.js +8 -5
  6. package/frontend/src/api/auth.ts +0 -3
  7. package/frontend/src/components/plugins/PluginPanel.tsx +7 -3
  8. package/frontend/src/components/plugins/card/CardEngine.tsx +1 -1
  9. package/frontend/src/pages/LoginPage.tsx +1 -41
  10. package/frontend/src/pages/PluginsPage.tsx +14 -7
  11. package/package.json +7 -5
  12. package/scaffold/.agent/skills/plugin/scripts/record.mjs +6 -3
  13. package/scaffold/.agent/skills/total-recall/plugins/auth/cli.mjs +197 -31
  14. package/scaffold/.agent/skills/total-recall/plugins/auth/package-lock.json +6 -6
  15. package/scaffold/.agent/skills/total-recall/plugins/auth/package.json +1 -1
  16. package/scaffold/.agent/skills/total-recall/plugins/auth/plugin.json +8 -1
  17. package/scaffold/.agent/skills/total-recall/plugins/auth/src/cli-secret.mjs +48 -0
  18. package/scaffold/.agent/skills/total-recall/plugins/auth/src/login-projections.mjs +42 -0
  19. package/scaffold/.agent/skills/total-recall/plugins/auth/src/mesh-secrets.mjs +18 -0
  20. package/scaffold/.agent/skills/total-recall/plugins/auth/src/routes/secrets.mjs +5 -2
  21. package/scaffold/.agent/skills/total-recall/plugins/auth/src/secrets-carriers.mjs +76 -0
  22. package/scaffold/.agent/skills/total-recall/plugins/auth/src/secrets-prune.mjs +37 -0
  23. package/scaffold/.agent/skills/total-recall/plugins/auth/src/secrets-sync.mjs +53 -17
  24. package/scaffold/.agent/skills/total-recall/plugins/auth/ui/DESIGN.md +56 -8
  25. package/scaffold/.agent/skills/total-recall/plugins/auth/ui/card.js +1068 -204
  26. package/scaffold/.agent/skills/total-recall/plugins/auth/ui/panel.js +4 -2
  27. package/scaffold/.agent/skills/total-recall/plugins/cli-agents/ui/DESIGN.md +32 -0
  28. package/scaffold/.agent/skills/total-recall/plugins/cli-agents/ui/card.js +436 -274
  29. package/scaffold/.agent/skills/total-recall/plugins/code-quality/package-lock.json +12 -12
  30. package/scaffold/.agent/skills/total-recall/plugins/code-quality/package.json +1 -1
  31. package/scaffold/.agent/skills/total-recall/plugins/code-quality/ui/DESIGN.md +16 -2
  32. package/scaffold/.agent/skills/total-recall/plugins/code-quality/ui/card.js +461 -242
  33. package/scaffold/.agent/skills/total-recall/plugins/composable-cli/package-lock.json +12 -12
  34. package/scaffold/.agent/skills/total-recall/plugins/composable-cli/package.json +1 -1
  35. package/scaffold/.agent/skills/total-recall/plugins/composable-cli/plugin.json +1 -7
  36. package/scaffold/.agent/skills/total-recall/plugins/composable-cli/ui/DESIGN.md +17 -2
  37. package/scaffold/.agent/skills/total-recall/plugins/composable-cli/ui/card.js +426 -300
  38. package/scaffold/.agent/skills/total-recall/plugins/embeddings/package-lock.json +23 -8
  39. package/scaffold/.agent/skills/total-recall/plugins/embeddings/package.json +6 -2
  40. package/scaffold/.agent/skills/total-recall/plugins/embeddings/ui/DESIGN.md +32 -0
  41. package/scaffold/.agent/skills/total-recall/plugins/embeddings/ui/card.js +350 -283
  42. package/scaffold/.agent/skills/total-recall/plugins/git-sentinel/package-lock.json +23 -8
  43. package/scaffold/.agent/skills/total-recall/plugins/git-sentinel/package.json +5 -1
  44. package/scaffold/.agent/skills/total-recall/plugins/git-sentinel/ui/card.js +31 -19
  45. package/scaffold/.agent/skills/total-recall/plugins/mesh/package-lock.json +23 -10
  46. package/scaffold/.agent/skills/total-recall/plugins/mesh/package.json +5 -3
  47. package/scaffold/.agent/skills/total-recall/plugins/mesh/plugin.json +1 -1
  48. package/scaffold/.agent/skills/total-recall/plugins/mesh/src/cli/grants.mjs +7 -3
  49. package/scaffold/.agent/skills/total-recall/plugins/mesh/src/cli/mesh.mjs +61 -38
  50. package/scaffold/.agent/skills/total-recall/plugins/mesh/src/core/leader-election.mjs +57 -2
  51. package/scaffold/.agent/skills/total-recall/plugins/mesh/src/core/mesh.mjs +220 -36
  52. package/scaffold/.agent/skills/total-recall/plugins/mesh/src/server/routes/mesh.mjs +7 -2
  53. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/README.md +65 -0
  54. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/capability/BRICK.md +59 -0
  55. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/capability/index.mjs +534 -0
  56. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/cli.mjs +139 -0
  57. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/package-lock.json +2849 -0
  58. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/package.json +26 -0
  59. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/plugin.json +376 -0
  60. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/skills/meta-harness/SKILL.md +37 -0
  61. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/adapters/dsh.mjs +446 -0
  62. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/alerts.mjs +23 -0
  63. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/coordinator.mjs +398 -0
  64. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/documentation.mjs +152 -0
  65. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/executor.mjs +82 -0
  66. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/learner.mjs +90 -0
  67. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/router.mjs +415 -0
  68. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/runtime.mjs +36 -0
  69. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/setup.mjs +35 -0
  70. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/tracker.mjs +133 -0
  71. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/worker.mjs +233 -0
  72. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/ui/DESIGN.md +32 -0
  73. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/ui/card.js +845 -0
  74. package/scaffold/.agent/skills/total-recall/plugins/openwiki/capability/BRICK.md +64 -0
  75. package/scaffold/.agent/skills/total-recall/plugins/openwiki/capability/index.mjs +250 -0
  76. package/scaffold/.agent/skills/total-recall/plugins/openwiki/cli.mjs +344 -14
  77. package/scaffold/.agent/skills/total-recall/plugins/openwiki/package-lock.json +2917 -140
  78. package/scaffold/.agent/skills/total-recall/plugins/openwiki/package.json +9 -3
  79. package/scaffold/.agent/skills/total-recall/plugins/openwiki/plugin.json +223 -5
  80. package/scaffold/.agent/skills/total-recall/plugins/openwiki/src/config.mjs +129 -0
  81. package/scaffold/.agent/skills/total-recall/plugins/openwiki/src/refresh.mjs +355 -0
  82. package/scaffold/.agent/skills/total-recall/plugins/openwiki/src/upstream-watcher.mjs +375 -0
  83. package/scaffold/.agent/skills/total-recall/plugins/openwiki/ui/DESIGN.md +37 -10
  84. package/scaffold/.agent/skills/total-recall/plugins/openwiki/ui/card.js +986 -280
  85. package/scaffold/.agent/skills/total-recall/plugins/security/cli.mjs +7 -1
  86. package/scaffold/.agent/skills/total-recall/plugins/security/package-lock.json +25 -10
  87. package/scaffold/.agent/skills/total-recall/plugins/security/package.json +6 -2
  88. package/scaffold/.agent/skills/total-recall/plugins/security/plugin.json +1 -1
  89. package/scaffold/.agent/skills/total-recall/plugins/security/src/scanner.mjs +17 -3
  90. package/scaffold/.agent/skills/total-recall/plugins/security/ui/DESIGN.md +38 -15
  91. package/scaffold/.agent/skills/total-recall/plugins/security/ui/card.js +60 -34
  92. package/src/cli/command.mjs +23 -18
  93. package/src/cli/config.mjs +3 -0
  94. package/src/cli/connect.mjs +12 -116
  95. package/src/cli/daemon.mjs +23 -1
  96. package/src/cli/harness.mjs +0 -1
  97. package/src/cli/plugin/copies.mjs +8 -5
  98. package/src/cli/plugin/create.mjs +56 -3
  99. package/src/cli/plugin/index.mjs +40 -5
  100. package/src/cli/plugin/monetization.mjs +232 -12
  101. package/src/cli/preflight.mjs +161 -0
  102. package/src/cli/rebuild.mjs +22 -0
  103. package/src/cli/reset-password.mjs +3 -2
  104. package/src/cli/skill.mjs +8 -2
  105. package/src/cli/status.mjs +25 -7
  106. package/src/core/automatic-brain-updates.mjs +9 -3
  107. package/src/core/brain-updates.mjs +63 -5
  108. package/src/core/cli-commands.mjs +2 -0
  109. package/src/core/context-compiler.mjs +8 -1
  110. package/src/core/default-plugins.mjs +1 -1
  111. package/src/core/global-brain-updates.mjs +21 -1
  112. package/src/core/mesh-brain-updates.mjs +5 -2
  113. package/src/core/meta-harness.mjs +32 -79
  114. package/src/core/plugin-dependencies.mjs +6 -1
  115. package/src/core/plugin-runner.mjs +6 -1
  116. package/src/core/plugin-store.mjs +67 -1
  117. package/src/core/plugin-updates.mjs +1 -1
  118. package/src/core/portable-skills-maintenance.mjs +19 -0
  119. package/src/core/preflight-gate.mjs +77 -0
  120. package/src/core/preflight-receipt.mjs +123 -0
  121. package/src/core/required-plugins.mjs +7 -0
  122. package/src/core/runtime.mjs +0 -3
  123. package/src/core/skills-registry.mjs +33 -3
  124. package/src/core/surface.mjs +38 -1
  125. package/src/server/auth.mjs +41 -1
  126. package/src/server/memory-app.mjs +2 -1
  127. package/src/server/routes/auth.mjs +25 -1
  128. package/src/server/routes/plugins.mjs +17 -4
@@ -1,445 +1,571 @@
1
1
  /**
2
- * CmdSmith — Dynamic Agent Command Composition Engine
3
- * Bespoke Purpose-Built Web Component Card Face.
2
+ * Pipe Dream — Composable CLI Pipeline Forge Console
4
3
  *
5
- * Exposes live composed command inventory, dynamic execution inspection,
6
- * version history, and interactive pipeline actions with zero decorative gimmicks.
7
- *
8
- * Zero emojis, authentic commercial brand identity, touch-first ergonomics (>=44px).
4
+ * Bespoke operator interface for dynamic agent command composition.
5
+ * Displays real-time command matrix, risk classifications, argument schema,
6
+ * and version snapshot controls with zero template wrappers or terminal dumps.
9
7
  */
10
8
 
9
+ const DASH = '\u2014';
10
+
11
+ function escapeHtml(str) {
12
+ if (str === null || str === undefined) return '';
13
+ return String(str).replace(/[&<>"']/g, c => ({
14
+ '&': '&amp;',
15
+ '<': '&lt;',
16
+ '>': '&gt;',
17
+ '"': '&quot;',
18
+ "'": '&#39;'
19
+ }[c]));
20
+ }
21
+
11
22
  export class PipelineComposerCard extends HTMLElement {
12
23
  constructor() {
13
24
  super();
25
+ this.commands = [];
26
+ this.selectedCommand = null;
27
+ this.commandDetail = null;
14
28
  this.executing = false;
15
- this.telemetry = {
16
- commandsCount: '7 Active',
17
- scope: 'Global / Project',
18
- status: 'Engine Ready'
19
- };
29
+ this.activeScope = 'all';
30
+ this.screens = [{ id: 'forge', label: 'Command Forge' }];
31
+ this.screen = 'forge';
20
32
  }
21
33
 
22
34
  connectedCallback() {
23
- if (!this.shadowRoot) this.attachShadow({ mode: 'open' });
35
+ if (!this.shadowRoot) {
36
+ this.attachShadow({ mode: 'open' });
37
+ }
24
38
  this.render();
25
- this.refreshTelemetry();
39
+ this.refreshCommands();
26
40
  }
27
41
 
28
- async refreshTelemetry() {
42
+ async refreshCommands() {
43
+ if (!this.host) return;
29
44
  try {
30
- const res = await this.host?.run('list', []);
31
- let text = '';
32
- if (typeof res === 'object') {
33
- text = res.output || JSON.stringify(res, null, 2);
45
+ const res = await this.host.run('library', ['--json']);
46
+ let parsed = [];
47
+ if (Array.isArray(res)) {
48
+ parsed = res;
49
+ } else if (res && typeof res === 'object' && Array.isArray(res.commands)) {
50
+ parsed = res.commands;
51
+ } else if (typeof res === 'string' && res.trim().startsWith('[')) {
52
+ parsed = JSON.parse(res);
34
53
  } else {
35
- text = String(res || '');
54
+ // Fallback to list
55
+ const listRes = await this.host.run('list', ['--json']);
56
+ if (Array.isArray(listRes)) parsed = listRes;
57
+ else if (listRes && typeof listRes === 'object' && Array.isArray(listRes.commands)) parsed = listRes.commands;
36
58
  }
37
59
 
38
- const lines = text.split('\n').filter(l => l.trim().startsWith('-'));
39
- const count = lines.length;
40
-
41
- this.telemetry = {
42
- commandsCount: count > 0 ? `${count} Commands` : '0 Commands',
43
- scope: text.includes('global') ? 'Global & Project' : 'Project Scope',
44
- status: 'Engine Ready'
45
- };
46
- this.updateView();
60
+ this.commands = parsed;
61
+ if (this.commands.length > 0 && !this.selectedCommand) {
62
+ this.selectedCommand = this.commands[0].name;
63
+ await this.inspectCommand(this.selectedCommand);
64
+ } else {
65
+ this.render();
66
+ }
47
67
  } catch {
48
- this.telemetry = {
49
- commandsCount: 'Registry Active',
50
- scope: 'Local Scope',
51
- status: 'Online'
52
- };
53
- this.updateView();
68
+ this.commands = [];
69
+ this.render();
54
70
  }
55
71
  }
56
72
 
57
- updateView() {
58
- const root = this.shadowRoot;
59
- if (!root) return;
60
-
61
- const countEl = root.querySelector('#stat-count');
62
- const scopeEl = root.querySelector('#stat-scope');
63
- const statusEl = root.querySelector('#stat-status');
64
- if (countEl) countEl.textContent = this.telemetry.commandsCount;
65
- if (scopeEl) scopeEl.textContent = this.telemetry.scope;
66
- if (statusEl) statusEl.textContent = this.telemetry.status;
73
+ async inspectCommand(name) {
74
+ this.selectedCommand = name;
75
+ if (!this.host) return;
76
+ try {
77
+ const detail = await this.host.run('read', [name, '--json']);
78
+ this.commandDetail = detail && typeof detail === 'object' ? detail : { name, code: String(detail || '') };
79
+ } catch {
80
+ this.commandDetail = null;
81
+ }
82
+ this.render();
67
83
  }
68
84
 
69
- async execute(action, args = []) {
70
- const out = this.shadowRoot?.querySelector('#card-out');
71
- const statusBadge = this.shadowRoot?.querySelector('#status-pill');
72
- const actionLabel = action.toUpperCase();
73
-
74
- if (out) out.textContent = `[CMDSMITH ROUTER] Invoking ${actionLabel} ${args.join(' ')}...`;
75
- if (statusBadge) statusBadge.textContent = 'ROUTING';
85
+ async testCommand(name) {
86
+ if (!this.host || this.executing) return;
76
87
  this.executing = true;
88
+ this.render();
77
89
 
78
90
  try {
79
- const res = await this.host?.run(action, args);
80
- let text = '';
81
- if (typeof res === 'object') {
82
- text = res.output || JSON.stringify(res, null, 2);
83
- } else {
84
- text = String(res || 'Execution completed with no return payload.');
85
- }
86
- if (out) out.textContent = text.trim();
87
- if (statusBadge) statusBadge.textContent = 'READY';
88
-
89
- if (['create', 'update', 'remove', 'rollback', 'promote'].includes(action)) {
90
- this.refreshTelemetry();
91
+ const result = await this.host.run('test', [name, '--json']);
92
+ if (this.commandDetail) {
93
+ this.commandDetail.lastResult = result;
91
94
  }
92
95
  } catch (err) {
93
- if (out) out.textContent = `[CMDSMITH FAULT] ${err.message}`;
94
- if (statusBadge) statusBadge.textContent = 'ERROR';
96
+ if (this.commandDetail) {
97
+ this.commandDetail.lastError = err instanceof Error ? err.message : 'Execution failed';
98
+ }
95
99
  } finally {
96
100
  this.executing = false;
101
+ this.render();
97
102
  }
98
103
  }
99
104
 
100
- copyOutput() {
101
- const out = this.shadowRoot?.querySelector('#card-out');
102
- const copyBtn = this.shadowRoot?.querySelector('#btn-copy');
103
- if (!out) return;
104
-
105
- navigator.clipboard?.writeText(out.textContent || '').then(() => {
106
- if (copyBtn) {
107
- const prev = copyBtn.textContent;
108
- copyBtn.textContent = 'COPIED';
109
- setTimeout(() => { copyBtn.textContent = prev; }, 1600);
110
- }
111
- }).catch(() => {});
105
+ setScopeFilter(scope) {
106
+ this.activeScope = scope;
107
+ this.render();
112
108
  }
113
109
 
114
110
  render() {
115
111
  const root = this.shadowRoot;
116
112
  if (!root) return;
117
113
 
114
+ const filtered = this.commands.filter(c => {
115
+ if (this.activeScope === 'project') return c.scope === 'project';
116
+ if (this.activeScope === 'global') return c.scope === 'global';
117
+ return true;
118
+ });
119
+
120
+ const activeCmd = this.commands.find(c => c.name === this.selectedCommand) || this.commands[0];
121
+ const detail = this.commandDetail;
122
+
118
123
  root.innerHTML = `
119
124
  <style>
120
125
  :host {
126
+ --face-bg: #09090b;
127
+ --face-surface: #18181b;
128
+ --face-line: #27272a;
129
+ --face-text: #f4f4f5;
130
+ --face-muted: #a1a1aa;
131
+ --face-brand: #a855f7;
132
+ --face-brand-hover: #c084fc;
133
+ --face-accent: #22c55e;
134
+ --face-ok: #22c55e;
135
+ --face-warn: #eab308;
136
+ --face-danger: #ef4444;
137
+ --face-info: #38bdf8;
138
+ --face-dark: #09090b;
139
+
121
140
  display: block;
122
- font-family: 'Space Grotesk', -apple-system, sans-serif;
123
- background: #03151e;
124
- color: #ecfeff;
125
- border-radius: 12px;
126
- border: 1px solid #0e4a5e;
127
- padding: 14px;
141
+ font-family: var(--font-sans, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif);
142
+ color: var(--text-primary, var(--face-text));
143
+ background: var(--bg-secondary, var(--face-bg));
144
+ border: 1px solid var(--border, var(--face-line));
145
+ border-radius: 8px;
146
+ padding: 16px;
128
147
  box-sizing: border-box;
129
- user-select: none;
148
+ overflow: hidden;
130
149
  }
131
150
 
132
- * { box-sizing: border-box; }
151
+ @media (prefers-reduced-motion: reduce) {
152
+ *, ::before, ::after {
153
+ animation-duration: 0.01ms !important;
154
+ animation-iteration-count: 1 !important;
155
+ transition-duration: 0.01ms !important;
156
+ }
157
+ }
133
158
 
134
- /* Bespoke Header */
135
- .card-header {
159
+ /* Header Bar */
160
+ .header {
136
161
  display: flex;
137
162
  align-items: center;
138
163
  justify-content: space-between;
139
- margin-bottom: 12px;
140
- padding-bottom: 8px;
141
- border-bottom: 1px solid rgba(6, 182, 212, 0.2);
164
+ flex-wrap: wrap;
165
+ gap: 12px;
166
+ padding-bottom: 14px;
167
+ border-bottom: 1px solid var(--border, var(--face-line));
168
+ margin-bottom: 16px;
142
169
  }
143
170
 
144
- .brand-cluster {
171
+ .brand-group {
145
172
  display: flex;
146
173
  align-items: center;
147
174
  gap: 10px;
148
175
  }
149
176
 
150
- .brand-mark {
151
- width: 32px;
152
- height: 32px;
153
- border-radius: 8px;
154
- background: rgba(8, 145, 178, 0.2);
155
- border: 1px solid rgba(6, 182, 212, 0.4);
156
- display: flex;
157
- align-items: center;
158
- justify-content: center;
159
- flex-shrink: 0;
177
+ .wordmark-badge {
178
+ font-family: var(--font-mono, 'JetBrains Mono', monospace);
179
+ font-size: 13px;
180
+ font-weight: 800;
181
+ letter-spacing: 0.05em;
182
+ color: var(--card-accent, var(--face-brand));
183
+ background: rgba(168, 85, 247, 0.12);
184
+ padding: 6px 10px;
185
+ border-radius: 6px;
186
+ border: 1px solid rgba(168, 85, 247, 0.3);
160
187
  }
161
188
 
162
- .brand-meta {
189
+ .title-meta {
163
190
  display: flex;
164
191
  flex-direction: column;
165
192
  }
166
193
 
167
- .brand-title {
194
+ .plugin-title {
168
195
  font-size: 14px;
169
196
  font-weight: 700;
170
- color: #cffafe;
171
- letter-spacing: 0.03em;
172
- text-transform: uppercase;
197
+ color: var(--text-primary, var(--face-text));
173
198
  margin: 0;
174
199
  }
175
200
 
176
- .brand-subtitle {
201
+ .plugin-subtitle {
177
202
  font-size: 11px;
178
- color: #67e8f9;
203
+ color: var(--text-secondary, var(--face-muted));
179
204
  margin: 0;
180
- font-family: 'JetBrains Mono', monospace;
181
205
  }
182
206
 
183
- .status-pill {
184
- font-family: 'JetBrains Mono', monospace;
185
- font-size: 10px;
207
+ .inventory-chip {
208
+ display: flex;
209
+ align-items: center;
210
+ gap: 6px;
211
+ font-family: var(--font-mono, 'JetBrains Mono', monospace);
212
+ font-size: 11px;
186
213
  font-weight: 700;
187
- padding: 3px 8px;
214
+ color: var(--face-accent);
215
+ background: rgba(34, 197, 94, 0.12);
216
+ border: 1px solid rgba(34, 197, 94, 0.3);
217
+ padding: 5px 12px;
188
218
  border-radius: 6px;
189
- background: rgba(6, 182, 212, 0.15);
190
- border: 1px solid rgba(6, 182, 212, 0.4);
191
- color: #22d3ee;
192
- letter-spacing: 0.05em;
219
+ text-transform: uppercase;
193
220
  }
194
221
 
195
- /* Telemetry Metric Cards */
196
- .telemetry-row {
222
+ /* Main Workspace Split */
223
+ .workspace-split {
197
224
  display: grid;
198
- grid-template-columns: repeat(3, 1fr);
199
- gap: 8px;
200
- margin-bottom: 12px;
201
- }
202
-
203
- .metric-card {
204
- background: rgba(8, 47, 61, 0.6);
205
- border: 1px solid rgba(6, 182, 212, 0.25);
206
- border-radius: 8px;
207
- padding: 8px 10px;
208
- display: flex;
209
- flex-direction: column;
210
- gap: 2px;
225
+ grid-template-columns: minmax(220px, 1fr) minmax(320px, 1.6fr);
226
+ gap: 14px;
227
+ margin-bottom: 16px;
211
228
  }
212
229
 
213
- .metric-label {
214
- font-family: 'JetBrains Mono', monospace;
215
- font-size: 9px;
216
- font-weight: 700;
217
- color: #67e8f9;
218
- letter-spacing: 0.05em;
219
- text-transform: uppercase;
230
+ @media (max-width: 680px) {
231
+ .workspace-split {
232
+ grid-template-columns: 1fr;
233
+ }
220
234
  }
221
235
 
222
- .metric-value {
223
- font-size: 13px;
224
- font-weight: 700;
225
- color: #ffffff;
226
- font-family: 'JetBrains Mono', monospace;
227
- overflow: hidden;
228
- text-overflow: ellipsis;
229
- white-space: nowrap;
236
+ /* Command List Deck */
237
+ .deck-column {
238
+ display: flex;
239
+ flex-direction: column;
240
+ gap: 10px;
230
241
  }
231
242
 
232
- /* Target Command Input Selector */
233
- .target-box {
243
+ .scope-filters {
234
244
  display: flex;
235
245
  align-items: center;
236
- gap: 8px;
237
- margin-bottom: 10px;
238
- background: rgba(0, 0, 0, 0.35);
239
- border: 1px solid rgba(6, 182, 212, 0.2);
240
- border-radius: 8px;
241
- padding: 4px 8px;
242
- }
243
-
244
- .target-label {
245
- font-family: 'JetBrains Mono', monospace;
246
- font-size: 10px;
247
- color: #67e8f9;
248
- text-transform: uppercase;
249
- white-space: nowrap;
246
+ gap: 6px;
250
247
  }
251
248
 
252
- .target-input {
253
- flex: 1;
249
+ .btn-scope {
250
+ min-height: 44px;
251
+ min-width: 44px;
252
+ padding: 6px 12px;
253
+ font-family: var(--font-mono, 'JetBrains Mono', monospace);
254
+ font-size: 11px;
255
+ font-weight: 600;
256
+ color: var(--text-secondary, var(--face-muted));
254
257
  background: transparent;
255
- border: none;
256
- color: #ecfeff;
257
- font-family: 'JetBrains Mono', monospace;
258
- font-size: 12px;
259
- outline: none;
258
+ border: 1px solid var(--border, var(--face-line));
259
+ border-radius: 5px;
260
+ cursor: pointer;
260
261
  }
261
262
 
262
- .target-input::placeholder {
263
- color: rgba(103, 232, 249, 0.4);
263
+ .btn-scope[data-active="true"] {
264
+ color: var(--text-primary, var(--face-text));
265
+ background: rgba(168, 85, 247, 0.15);
266
+ border-color: var(--card-accent, var(--face-brand));
264
267
  }
265
268
 
266
- /* Action Buttons Grid (>=44px touch targets) */
267
- .actions-grid {
268
- display: grid;
269
- grid-template-columns: repeat(3, 1fr);
269
+ .command-list {
270
+ display: flex;
271
+ flex-direction: column;
270
272
  gap: 6px;
271
- margin-bottom: 10px;
273
+ max-height: 320px;
274
+ overflow-y: auto;
275
+ border: 1px solid var(--border, var(--face-line));
276
+ border-radius: 6px;
277
+ padding: 6px;
278
+ background: rgba(24, 24, 27, 0.5);
272
279
  }
273
280
 
274
- .touch-btn {
281
+ .command-item {
275
282
  min-height: 44px;
276
- background: rgba(8, 145, 178, 0.16);
277
- border: 1px solid rgba(6, 182, 212, 0.3);
278
- border-radius: 8px;
279
- color: #ecfeff;
280
- font-family: 'JetBrains Mono', monospace;
281
- font-size: 11px;
282
- font-weight: 600;
283
- letter-spacing: 0.03em;
283
+ padding: 8px 10px;
284
284
  display: flex;
285
285
  align-items: center;
286
- justify-content: center;
286
+ justify-content: space-between;
287
+ border: 1px solid transparent;
288
+ border-radius: 5px;
289
+ background: transparent;
290
+ color: var(--text-primary, var(--face-text));
287
291
  cursor: pointer;
288
- transition: background 0.15s, border-color 0.15s, transform 0.05s;
289
- padding: 4px 6px;
290
- text-align: center;
292
+ text-align: left;
293
+ width: 100%;
294
+ box-sizing: border-box;
295
+ transition: background 0.15s ease;
291
296
  }
292
297
 
293
- .touch-btn:hover {
294
- background: rgba(8, 145, 178, 0.3);
295
- border-color: rgba(6, 182, 212, 0.6);
298
+ .command-item:hover {
299
+ background: rgba(39, 39, 42, 0.5);
296
300
  }
297
301
 
298
- .touch-btn:active {
299
- transform: translateY(1px);
302
+ .command-item[data-selected="true"] {
303
+ background: rgba(168, 85, 247, 0.18);
304
+ border-color: var(--face-brand);
300
305
  }
301
306
 
302
- /* Terminal Execution Output */
303
- .terminal-deck {
304
- background: #010c12;
305
- border: 1px solid rgba(6, 182, 212, 0.25);
306
- border-radius: 8px;
307
- overflow: hidden;
307
+ .cmd-name {
308
+ font-family: var(--font-mono, 'JetBrains Mono', monospace);
309
+ font-size: 12px;
310
+ font-weight: 700;
308
311
  }
309
312
 
310
- .terminal-header {
313
+ .badges-group {
311
314
  display: flex;
312
315
  align-items: center;
313
- justify-content: space-between;
314
- padding: 6px 10px;
315
- background: rgba(8, 47, 61, 0.4);
316
- border-bottom: 1px solid rgba(6, 182, 212, 0.2);
316
+ gap: 6px;
317
317
  }
318
318
 
319
- .terminal-title {
320
- font-family: 'JetBrains Mono', monospace;
321
- font-size: 10px;
322
- color: #67e8f9;
319
+ .risk-badge {
320
+ font-family: var(--font-mono, 'JetBrains Mono', monospace);
321
+ font-size: 9px;
322
+ font-weight: 700;
323
+ padding: 2px 6px;
324
+ border-radius: 4px;
323
325
  text-transform: uppercase;
324
- letter-spacing: 0.05em;
325
326
  }
326
327
 
327
- .terminal-btn {
328
- background: rgba(6, 182, 212, 0.15);
329
- border: 1px solid rgba(6, 182, 212, 0.3);
330
- border-radius: 4px;
331
- color: #cffafe;
332
- font-family: 'JetBrains Mono', monospace;
328
+ .risk-read {
329
+ color: var(--face-ok);
330
+ background: rgba(34, 197, 94, 0.15);
331
+ }
332
+
333
+ .risk-write {
334
+ color: var(--face-warn);
335
+ background: rgba(234, 179, 8, 0.15);
336
+ }
337
+
338
+ .risk-destructive {
339
+ color: var(--face-danger);
340
+ background: rgba(239, 68, 68, 0.15);
341
+ }
342
+
343
+ .risk-send {
344
+ color: var(--face-info);
345
+ background: rgba(56, 189, 248, 0.15);
346
+ }
347
+
348
+ .scope-tag {
333
349
  font-size: 9px;
334
- padding: 2px 6px;
335
- cursor: pointer;
350
+ color: var(--text-secondary, var(--face-muted));
351
+ border: 1px solid var(--border, var(--face-line));
352
+ padding: 1px 4px;
353
+ border-radius: 3px;
336
354
  }
337
355
 
338
- .terminal-btn:hover {
339
- background: rgba(6, 182, 212, 0.3);
356
+ /* Inspector View */
357
+ .inspector-panel {
358
+ border: 1px solid var(--border, var(--face-line));
359
+ border-radius: 6px;
360
+ background: rgba(24, 24, 27, 0.5);
361
+ padding: 14px;
362
+ display: flex;
363
+ flex-direction: column;
364
+ gap: 12px;
340
365
  }
341
366
 
342
- .terminal-body {
367
+ .inspector-header {
368
+ display: flex;
369
+ align-items: center;
370
+ justify-content: space-between;
371
+ padding-bottom: 10px;
372
+ border-bottom: 1px solid var(--border, var(--face-line));
373
+ }
374
+
375
+ .inspector-title {
376
+ font-family: var(--font-mono, 'JetBrains Mono', monospace);
377
+ font-size: 13px;
378
+ font-weight: 700;
379
+ color: var(--text-primary, var(--face-text));
343
380
  margin: 0;
344
- padding: 8px 10px;
345
- font-family: 'JetBrains Mono', monospace;
381
+ }
382
+
383
+ .action-run {
384
+ min-height: 44px;
385
+ padding: 8px 16px;
386
+ font-family: var(--font-sans, sans-serif);
387
+ font-size: 12px;
388
+ font-weight: 700;
389
+ color: var(--face-dark);
390
+ background: var(--face-brand);
391
+ border: none;
392
+ border-radius: 5px;
393
+ cursor: pointer;
394
+ display: flex;
395
+ align-items: center;
396
+ gap: 6px;
397
+ transition: background 0.2s ease;
398
+ }
399
+
400
+ .action-run:hover {
401
+ background: var(--face-brand-hover);
402
+ }
403
+
404
+ .action-run:disabled {
405
+ opacity: 0.6;
406
+ cursor: not-allowed;
407
+ }
408
+
409
+ .detail-meta-row {
410
+ display: flex;
411
+ flex-wrap: wrap;
412
+ gap: 12px;
413
+ font-size: 11px;
414
+ color: var(--text-secondary, var(--face-muted));
415
+ }
416
+
417
+ .meta-entry {
418
+ display: flex;
419
+ align-items: center;
420
+ gap: 4px;
421
+ }
422
+
423
+ .meta-entry strong {
424
+ color: var(--text-primary, var(--face-text));
425
+ }
426
+
427
+ .code-preview-box {
428
+ background: rgba(9, 9, 11, 0.8);
429
+ border: 1px solid var(--border, var(--face-line));
430
+ border-radius: 5px;
431
+ padding: 10px;
432
+ font-family: var(--font-mono, 'JetBrains Mono', monospace);
346
433
  font-size: 11px;
347
- line-height: 1.45;
348
- color: #cffafe;
349
- min-height: 60px;
350
- max-height: 100px;
434
+ line-height: 1.5;
435
+ color: var(--text-primary, var(--face-text));
436
+ max-height: 160px;
351
437
  overflow-y: auto;
352
438
  white-space: pre-wrap;
353
- word-break: break-word;
439
+ word-break: break-all;
440
+ }
441
+
442
+ .result-container {
443
+ padding: 8px 12px;
444
+ border-radius: 5px;
445
+ font-family: var(--font-mono, 'JetBrains Mono', monospace);
446
+ font-size: 11px;
447
+ }
448
+
449
+ .result-success {
450
+ background: rgba(34, 197, 94, 0.12);
451
+ border: 1px solid rgba(34, 197, 94, 0.3);
452
+ color: var(--face-ok);
453
+ }
454
+
455
+ .result-failure {
456
+ background: rgba(239, 68, 68, 0.12);
457
+ border: 1px solid rgba(239, 68, 68, 0.3);
458
+ color: var(--face-danger);
459
+ }
460
+
461
+ .empty-command-box {
462
+ padding: 32px 16px;
463
+ text-align: center;
464
+ font-size: 12px;
465
+ color: var(--text-secondary, var(--face-muted));
466
+ }
467
+
468
+ /* Footer Telemetry */
469
+ .footer-bar {
470
+ display: flex;
471
+ justify-content: space-between;
472
+ align-items: center;
473
+ padding-top: 12px;
474
+ margin-top: 14px;
475
+ border-top: 1px solid var(--border, var(--face-line));
476
+ font-size: 10px;
477
+ color: var(--text-secondary, var(--face-muted));
354
478
  }
355
479
  </style>
356
480
 
357
- <div class="card-header">
358
- <div class="brand-cluster">
359
- <div class="brand-mark">
360
- <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="#22d3ee" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
361
- <path d="M4 17l6-6-6-6"/>
362
- <path d="M12 19h8"/>
363
- <circle cx="16" cy="8" r="2"/>
364
- </svg>
365
- </div>
366
- <div class="brand-meta">
367
- <h3 class="brand-title">CmdSmith</h3>
368
- <span class="brand-subtitle">Pipeline Forge • v0.2.1</span>
481
+ <div class="header">
482
+ <div class="brand-group">
483
+ <div class="wordmark-badge">[PIPE//DREAM]</div>
484
+ <div class="title-meta">
485
+ <h3 class="plugin-title">Composable CLI Forge</h3>
486
+ <p class="plugin-subtitle">Dynamic agent command composition and execution</p>
369
487
  </div>
370
488
  </div>
371
- <div id="status-pill" class="status-pill">READY</div>
372
- </div>
373
-
374
- <div class="telemetry-row">
375
- <div class="metric-card">
376
- <span class="metric-label">Commands</span>
377
- <span id="stat-count" class="metric-value">7 Active</span>
378
- </div>
379
- <div class="metric-card">
380
- <span class="metric-label">Scope</span>
381
- <span id="stat-scope" class="metric-value">Global / Project</span>
382
- </div>
383
- <div class="metric-card">
384
- <span class="metric-label">Engine</span>
385
- <span id="stat-status" class="metric-value">Engine Ready</span>
489
+ <div class="inventory-chip">
490
+ ${this.commands.length > 0 ? `${this.commands.length} Verbs Active` : 'No Commands'}
386
491
  </div>
387
492
  </div>
388
493
 
389
- <div class="target-box">
390
- <span class="target-label">Target Command:</span>
391
- <input id="cmd-input" class="target-input" type="text" value="tr-first" placeholder="e.g. tr-first, brand-lint" />
392
- </div>
494
+ <div class="workspace-split">
495
+ <div class="deck-column">
496
+ <div class="scope-filters">
497
+ <button class="btn-scope" data-active="${this.activeScope === 'all'}" type="button" id="scope-all">All</button>
498
+ <button class="btn-scope" data-active="${this.activeScope === 'project'}" type="button" id="scope-project">Project</button>
499
+ <button class="btn-scope" data-active="${this.activeScope === 'global'}" type="button" id="scope-global">Global</button>
500
+ </div>
393
501
 
394
- <div class="actions-grid">
395
- <button id="btn-library" class="touch-btn" type="button">LIBRARY</button>
396
- <button id="btn-list" class="touch-btn" type="button">LIST</button>
397
- <button id="btn-show" class="touch-btn" type="button">SHOW</button>
398
- <button id="btn-history" class="touch-btn" type="button">HISTORY</button>
399
- <button id="btn-test" class="touch-btn" type="button">TEST</button>
400
- <button id="btn-status" class="touch-btn" type="button">STATUS</button>
401
- </div>
502
+ <div class="command-list">
503
+ ${filtered.length > 0 ? filtered.map(c => `
504
+ <button class="command-item" data-selected="${c.name === this.selectedCommand}" type="button" data-cmd="${escapeHtml(c.name)}">
505
+ <span class="cmd-name">${escapeHtml(c.name)}</span>
506
+ <div class="badges-group">
507
+ <span class="risk-badge risk-${escapeHtml(c.risk || 'read')}">${escapeHtml(c.risk || 'read')}</span>
508
+ <span class="scope-tag">${escapeHtml(c.scope || 'proj')}</span>
509
+ </div>
510
+ </button>
511
+ `).join('') : `
512
+ <div class="empty-command-box">No composed commands in this scope.</div>
513
+ `}
514
+ </div>
515
+ </div>
402
516
 
403
- <div class="terminal-deck">
404
- <div class="terminal-header">
405
- <span class="terminal-title">Console Output</span>
406
- <button id="btn-copy" class="terminal-btn" type="button">COPY</button>
517
+ <div class="inspector-panel">
518
+ ${activeCmd ? `
519
+ <div class="inspector-header">
520
+ <h4 class="inspector-title">${escapeHtml(activeCmd.name)}</h4>
521
+ <button class="action-run" type="button" id="btn-test" ${this.executing ? 'disabled' : ''}>
522
+ ${this.executing ? 'Executing...' : 'Test Verb'}
523
+ </button>
524
+ </div>
525
+
526
+ <div class="detail-meta-row">
527
+ <div class="meta-entry"><span>Scope:</span> <strong>${escapeHtml(activeCmd.scope || 'project')}</strong></div>
528
+ <div class="meta-entry"><span>Risk:</span> <strong class="risk-badge risk-${escapeHtml(activeCmd.risk || 'read')}">${escapeHtml(activeCmd.risk || 'read')}</strong></div>
529
+ <div class="meta-entry"><span>Updated:</span> <strong>${activeCmd.updated_at ? new Date(activeCmd.updated_at).toLocaleDateString() : DASH}</strong></div>
530
+ </div>
531
+
532
+ ${detail?.lastResult ? `
533
+ <div class="result-container result-success">
534
+ Return: ${escapeHtml(JSON.stringify(detail.lastResult))}
535
+ </div>
536
+ ` : detail?.lastError ? `
537
+ <div class="result-container result-failure">
538
+ Failure: ${escapeHtml(detail.lastError)}
539
+ </div>
540
+ ` : ''}
541
+
542
+ <div class="code-preview-box">${escapeHtml(detail?.code || detail?.source || '// Select a composed verb to inspect implementation')}</div>
543
+ ` : `
544
+ <div class="empty-command-box">Select or create a composed command to inspect properties.</div>
545
+ `}
407
546
  </div>
408
- <pre id="card-out" class="terminal-body">Dynamic agent command composition engine ready. Click any action above to inspect pipeline state.</pre>
409
547
  </div>
410
- `;
411
548
 
412
- const getTarget = () => {
413
- const input = root.querySelector('#cmd-input');
414
- return (input?.value || 'tr-first').trim();
415
- };
416
-
417
- root.querySelector('#btn-library')?.addEventListener('click', () => {
418
- this.execute('library');
419
- });
549
+ <div class="footer-bar">
550
+ <span>Engine: Composable CLI v0.2.2</span>
551
+ <span>Scope: ${this.activeScope.toUpperCase()}</span>
552
+ </div>
553
+ `;
420
554
 
421
- root.querySelector('#btn-list')?.addEventListener('click', () => {
422
- this.execute('list');
423
- });
555
+ // Event listeners
556
+ root.querySelector('#scope-all')?.addEventListener('click', () => this.setScopeFilter('all'));
557
+ root.querySelector('#scope-project')?.addEventListener('click', () => this.setScopeFilter('project'));
558
+ root.querySelector('#scope-global')?.addEventListener('click', () => this.setScopeFilter('global'));
424
559
 
425
- root.querySelector('#btn-show')?.addEventListener('click', () => {
426
- this.execute('show', [getTarget()]);
427
- });
428
-
429
- root.querySelector('#btn-history')?.addEventListener('click', () => {
430
- this.execute('history', [getTarget()]);
560
+ root.querySelectorAll('.command-item').forEach(btn => {
561
+ btn.addEventListener('click', () => {
562
+ const cmd = btn.getAttribute('data-cmd');
563
+ if (cmd) this.inspectCommand(cmd);
564
+ });
431
565
  });
432
566
 
433
567
  root.querySelector('#btn-test')?.addEventListener('click', () => {
434
- this.execute('test', [getTarget()]);
435
- });
436
-
437
- root.querySelector('#btn-status')?.addEventListener('click', () => {
438
- this.execute('status');
439
- });
440
-
441
- root.querySelector('#btn-copy')?.addEventListener('click', () => {
442
- this.copyOutput();
568
+ if (this.selectedCommand) this.testCommand(this.selectedCommand);
443
569
  });
444
570
  }
445
571
  }