@sidecar-ai/cli 0.1.0-alpha.11 → 0.1.0-alpha.12

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/dist/index.js CHANGED
@@ -4060,69 +4060,77 @@ function renderDevHarnessHtml(state, options = {}) {
4060
4060
  <style>
4061
4061
  :root {
4062
4062
  color-scheme: light dark;
4063
- --radius: 14px;
4064
- --bg: oklch(0.971 0.025 97.1);
4065
- --text: oklch(0.145 0 0);
4066
- --panel: oklch(1 0 0);
4067
- --panel-soft: oklch(0.903 0.033 93.5);
4068
- --muted: oklch(0.537 0.022 97.1);
4069
- --border: oklch(0.911 0.035 96.3);
4070
- --sidebar: oklch(0.959 0.035 96.3);
4071
- --accent: oklch(0.651 0.055 65.6);
4072
- --accent-text: oklch(0.984 0.014 78.3);
4073
- --control-bg: oklch(0.145 0 0);
4074
- --control-text: oklch(0.985 0 0);
4075
- --send-bg: oklch(0.145 0 0);
4076
- --send-text: oklch(0.985 0 0);
4077
- --ring: oklch(0.708 0 0 / 28%);
4078
- --widget-bg: oklch(1 0 0);
4063
+ --radius: 12px;
4064
+ --bg: #f8f9fa;
4065
+ --text: #18181b;
4066
+ --panel: #ffffff;
4067
+ --panel-soft: #f4f4f5;
4068
+ --muted: #71717a;
4069
+ --border: #e4e4e7;
4070
+ --accent: #2563eb;
4071
+ --accent-text: #ffffff;
4072
+ --control-bg: #18181b;
4073
+ --control-text: #ffffff;
4074
+ --send-bg: var(--accent);
4075
+ --send-text: var(--accent-text);
4076
+ --ring: rgba(37, 99, 235, 0.16);
4077
+ --widget-bg: #ffffff;
4078
+ --user-bubble-bg: #f4f4f5;
4079
+ --code-bg: #f4f4f5;
4080
+ --code-inline-bg: rgba(0, 0, 0, 0.04);
4079
4081
  --sidebar-width: 80px;
4080
4082
  --chat-width: 420px;
4081
4083
  --mobile-width: min(430px, calc(100vw - 28px));
4082
- --shadow: 0 24px 70px rgb(15 23 42 / 13%);
4084
+ --shadow: 0 16px 48px rgba(0, 0, 0, 0.06);
4083
4085
  }
4084
4086
  :root[data-sidecar-theme="dark"] {
4085
- --bg: oklch(0.218 0 0);
4086
- --text: oklch(0.985 0 0);
4087
- --panel: oklch(0.205 0 0);
4088
- --panel-soft: oklch(0.269 0 0);
4089
- --muted: oklch(0.708 0 0);
4090
- --border: oklch(1 0 0 / 10%);
4091
- --sidebar: oklch(0.264 0 0);
4092
- --accent: oklch(0.755 0.049 61.8);
4093
- --accent-text: oklch(0.218 0 0);
4094
- --control-bg: oklch(0.985 0 0);
4095
- --control-text: oklch(0.218 0 0);
4096
- --send-bg: oklch(0.985 0 0);
4097
- --send-text: oklch(0.218 0 0);
4098
- --ring: oklch(0.556 0 0 / 34%);
4099
- --widget-bg: oklch(0.205 0 0);
4100
- --shadow: 0 24px 70px rgb(0 0 0 / 34%);
4087
+ --bg: #0b0b0f;
4088
+ --text: #f4f4f5;
4089
+ --panel: #16161a;
4090
+ --panel-soft: #1e1e24;
4091
+ --muted: #8a8a93;
4092
+ --border: #232329;
4093
+ --accent: #3b82f6;
4094
+ --accent-text: #ffffff;
4095
+ --control-bg: #f4f4f5;
4096
+ --control-text: #0b0b0f;
4097
+ --send-bg: var(--accent);
4098
+ --send-text: var(--accent-text);
4099
+ --ring: rgba(59, 130, 246, 0.2);
4100
+ --widget-bg: #16161a;
4101
+ --user-bubble-bg: #1c1c21;
4102
+ --code-bg: #121216;
4103
+ --code-inline-bg: rgba(255, 255, 255, 0.06);
4104
+ --shadow: 0 24px 64px rgba(0, 0, 0, 0.4);
4101
4105
  }
4102
4106
  :root[data-sidecar-host="claude"] {
4103
4107
  --accent: #c96442;
4104
4108
  --accent-text: #fffaf4;
4105
- --ring: rgb(201 100 66 / 24%);
4109
+ --ring: rgba(201, 100, 66, 0.2);
4106
4110
  }
4107
4111
  :root[data-sidecar-host="claude"][data-sidecar-theme="dark"] {
4108
4112
  --accent: #d97757;
4109
4113
  --accent-text: #ffffff;
4110
- --ring: rgb(217 119 87 / 28%);
4114
+ --ring: rgba(217, 119, 87, 0.24);
4111
4115
  }
4112
4116
  :root[data-sidecar-host="chatgpt"] {
4113
4117
  --accent: #10a37f;
4114
4118
  --accent-text: #ffffff;
4115
- --ring: rgb(16 163 127 / 20%);
4119
+ --ring: rgba(16, 163, 127, 0.2);
4116
4120
  }
4117
4121
  * { box-sizing: border-box; }
4118
- *::-webkit-scrollbar { height: 8px; width: 8px; }
4122
+ *::-webkit-scrollbar { height: 6px; width: 6px; }
4119
4123
  *::-webkit-scrollbar-track { background: transparent; }
4120
- *::-webkit-scrollbar-thumb { background: color-mix(in srgb, var(--muted) 55%, transparent); border-radius: 999px; }
4124
+ *::-webkit-scrollbar-thumb { background: var(--border); border-radius: 999px; }
4125
+
4121
4126
  body {
4122
4127
  background: var(--bg);
4123
4128
  color: var(--text);
4124
- font: 14px/1.45 ui-sans-serif, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
4129
+ font-family: ui-sans-serif, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
4130
+ font-size: 14px;
4131
+ line-height: 1.5;
4125
4132
  margin: 0;
4133
+ overflow: hidden;
4126
4134
  }
4127
4135
  .shell {
4128
4136
  display: flex;
@@ -4138,120 +4146,128 @@ function renderDevHarnessHtml(state, options = {}) {
4138
4146
  }
4139
4147
  .topbar {
4140
4148
  align-items: center;
4141
- background: color-mix(in srgb, var(--bg) 92%, var(--panel));
4149
+ background: var(--bg);
4142
4150
  border-bottom: 1px solid var(--border);
4143
4151
  display: flex;
4144
4152
  gap: 16px;
4145
4153
  justify-content: space-between;
4146
- min-height: 64px;
4147
- padding: 12px 18px;
4154
+ min-height: 56px;
4155
+ padding: 8px 24px;
4148
4156
  }
4149
- .brand { display: grid; gap: 1px; min-width: 180px; }
4150
- h1 { font-size: 15px; line-height: 1.1; margin: 0; }
4151
- .subtitle { color: var(--muted); font-size: 12px; }
4152
- .controls { align-items: center; display: flex; flex-wrap: wrap; gap: 14px; justify-content: flex-end; }
4157
+ .brand { display: flex; align-items: center; }
4158
+ h1 { font-size: 14px; font-weight: 600; letter-spacing: 0; margin: 0; color: var(--text); }
4159
+
4160
+ .controls { align-items: center; display: flex; flex-wrap: wrap; gap: 12px; justify-content: flex-end; }
4153
4161
  .control-group { align-items: center; display: flex; }
4162
+
4154
4163
  .segmented {
4155
4164
  background: var(--panel-soft);
4156
4165
  border: 1px solid var(--border);
4157
- border-radius: 15px;
4166
+ border-radius: 8px;
4158
4167
  display: grid;
4159
4168
  gap: 0;
4160
- grid-template-columns: repeat(var(--segments, 2), 38px);
4161
- padding: 3px;
4169
+ grid-template-columns: repeat(var(--segments, 2), 32px);
4170
+ padding: 2px;
4162
4171
  position: relative;
4163
4172
  }
4164
4173
  .segmented::before {
4165
4174
  background: var(--panel);
4166
- border: 1px solid color-mix(in srgb, var(--border) 72%, transparent);
4167
- border-radius: 12px;
4168
- box-shadow: 0 1px 8px rgb(0 0 0 / 16%);
4175
+ border: 1px solid var(--border);
4176
+ border-radius: 6px;
4177
+ box-shadow: 0 1px 4px rgba(0, 0, 0, 0.08);
4169
4178
  content: "";
4170
- inset: 3px auto 3px 3px;
4179
+ inset: 2px auto 2px 2px;
4171
4180
  position: absolute;
4172
- transform: translateX(calc(var(--active-index, 0) * 38px));
4173
- transition: transform 170ms cubic-bezier(.2, .8, .2, 1);
4174
- width: 38px;
4181
+ transform: translateX(calc(var(--active-index, 0) * 32px));
4182
+ transition: transform 220ms cubic-bezier(0.16, 1, 0.3, 1);
4183
+ width: 32px;
4175
4184
  }
4176
- .segmented button, .send, .icon-button, .workspace-pill, .auth-trigger, .modal-button {
4185
+ .segmented button, .send, .icon-button, .auth-trigger, .modal-button {
4177
4186
  appearance: none;
4178
4187
  cursor: pointer;
4179
4188
  font: inherit;
4189
+ outline: none;
4180
4190
  }
4181
4191
  .segmented button {
4182
4192
  align-items: center;
4183
4193
  background: transparent;
4184
4194
  border: 0;
4185
- border-radius: 12px;
4195
+ border-radius: 6px;
4186
4196
  color: var(--muted);
4187
4197
  display: inline-flex;
4188
- font-weight: 650;
4198
+ font-weight: 500;
4189
4199
  justify-content: center;
4190
- min-height: 38px;
4191
- min-width: 38px;
4200
+ min-height: 32px;
4201
+ min-width: 32px;
4192
4202
  padding: 0;
4193
4203
  position: relative;
4194
4204
  transition: color 140ms ease;
4195
4205
  z-index: 1;
4196
4206
  }
4197
4207
  .segmented button[aria-pressed="true"] {
4198
- background: transparent;
4199
- box-shadow: none;
4200
4208
  color: var(--text);
4201
4209
  }
4202
4210
  .auth-trigger {
4203
4211
  align-items: center;
4204
4212
  background: var(--panel);
4205
4213
  border: 1px solid var(--border);
4206
- border-radius: 13px;
4214
+ border-radius: 8px;
4207
4215
  color: var(--text);
4208
4216
  display: inline-flex;
4209
- font-weight: 700;
4210
- min-height: 42px;
4211
- padding: 0 18px;
4217
+ font-size: 12px;
4218
+ font-weight: 500;
4219
+ min-height: 36px;
4220
+ padding: 0 14px;
4221
+ transition: background 120ms ease, border-color 120ms ease;
4222
+ }
4223
+ .auth-trigger:hover {
4224
+ background: var(--panel-soft);
4225
+ border-color: var(--muted);
4212
4226
  }
4213
- .auth-trigger:hover { background: color-mix(in srgb, var(--panel) 88%, var(--panel-soft)); }
4214
4227
  .auth-trigger:focus-visible, .modal-button:focus-visible, .modal-close:focus-visible {
4215
- outline: 0;
4216
4228
  box-shadow: 0 0 0 3px var(--ring);
4217
4229
  }
4218
4230
  .icon {
4219
4231
  align-items: center;
4220
4232
  display: inline-flex;
4221
- height: 17px;
4233
+ height: 16px;
4222
4234
  justify-content: center;
4223
4235
  line-height: 1;
4224
- width: 17px;
4236
+ width: 16px;
4225
4237
  }
4226
4238
  .icon svg {
4227
4239
  display: block;
4228
- height: 17px;
4240
+ height: 16px;
4229
4241
  stroke: currentColor;
4230
- width: 17px;
4242
+ width: 16px;
4231
4243
  }
4232
4244
  .button-text { display: none; }
4245
+
4233
4246
  .modal-input, textarea {
4234
4247
  background: var(--panel);
4235
4248
  border: 1px solid var(--border);
4236
- border-radius: 10px;
4249
+ border-radius: 8px;
4237
4250
  color: var(--text);
4238
4251
  font: inherit;
4239
4252
  outline: 0;
4240
4253
  }
4241
- .modal-input:focus, textarea:focus { border-color: var(--accent); box-shadow: 0 0 0 3px var(--ring); }
4242
- .modal-input { min-height: 40px; padding: 0 11px; width: 100%; }
4254
+ .modal-input:focus { border-color: var(--accent); box-shadow: 0 0 0 3px var(--ring); }
4255
+ .modal-input { min-height: 38px; padding: 0 12px; width: 100%; }
4256
+
4243
4257
  .modal-overlay {
4244
4258
  align-items: center;
4245
- background: rgb(0 0 0 / 42%);
4259
+ background: rgba(0, 0, 0, 0.5);
4260
+ backdrop-filter: blur(8px);
4261
+ -webkit-backdrop-filter: blur(8px);
4246
4262
  display: flex;
4247
4263
  inset: 0;
4248
4264
  justify-content: center;
4249
4265
  opacity: 0;
4250
- padding: 20px;
4266
+ padding: 24px;
4251
4267
  pointer-events: none;
4252
4268
  position: fixed;
4253
- transition: opacity 150ms ease;
4254
- z-index: 30;
4269
+ transition: opacity 250ms cubic-bezier(0.16, 1, 0.3, 1);
4270
+ z-index: 100;
4255
4271
  }
4256
4272
  .modal-overlay[data-open="true"] {
4257
4273
  opacity: 1;
@@ -4260,15 +4276,15 @@ function renderDevHarnessHtml(state, options = {}) {
4260
4276
  .modal-panel {
4261
4277
  background: var(--panel);
4262
4278
  border: 1px solid var(--border);
4263
- border-radius: 12px;
4264
- box-shadow: var(--shadow);
4279
+ border-radius: 16px;
4280
+ box-shadow: 0 24px 64px rgba(0, 0, 0, 0.25);
4265
4281
  display: grid;
4266
- gap: 16px;
4267
- max-width: min(440px, calc(100vw - 32px));
4282
+ gap: 20px;
4283
+ max-width: 400px;
4268
4284
  opacity: 0;
4269
- padding: 20px;
4270
- transform: translateY(10px) scale(.98);
4271
- transition: opacity 150ms ease, transform 150ms ease;
4285
+ padding: 24px;
4286
+ transform: translateY(12px) scale(0.97);
4287
+ transition: opacity 250ms cubic-bezier(0.16, 1, 0.3, 1), transform 250ms cubic-bezier(0.16, 1, 0.3, 1);
4272
4288
  width: 100%;
4273
4289
  }
4274
4290
  .modal-overlay[data-open="true"] .modal-panel {
@@ -4281,8 +4297,8 @@ function renderDevHarnessHtml(state, options = {}) {
4281
4297
  gap: 16px;
4282
4298
  justify-content: space-between;
4283
4299
  }
4284
- .modal-title { font-size: 17px; font-weight: 800; margin: 0; }
4285
- .modal-description { color: var(--muted); font-size: 13px; margin: 6px 0 0; }
4300
+ .modal-title { font-size: 16px; font-weight: 600; letter-spacing: 0; margin: 0; }
4301
+ .modal-description { color: var(--muted); font-size: 13px; margin: 4px 0 0; line-height: 1.4; }
4286
4302
  .modal-close {
4287
4303
  align-items: center;
4288
4304
  appearance: none;
@@ -4292,19 +4308,21 @@ function renderDevHarnessHtml(state, options = {}) {
4292
4308
  color: var(--muted);
4293
4309
  cursor: pointer;
4294
4310
  display: inline-flex;
4295
- height: 28px;
4311
+ height: 24px;
4296
4312
  justify-content: center;
4297
4313
  padding: 0;
4298
- width: 28px;
4314
+ width: 24px;
4315
+ transition: background 120ms ease, color 120ms ease;
4299
4316
  }
4317
+ .modal-close:hover { background: var(--panel-soft); color: var(--text); }
4300
4318
  .modal-close svg {
4301
4319
  display: block;
4302
- height: 16px;
4303
- width: 16px;
4320
+ height: 14px;
4321
+ width: 14px;
4304
4322
  }
4305
- .modal-field { display: grid; gap: 7px; }
4306
- .modal-label { font-size: 13px; font-weight: 700; }
4307
- .modal-error { color: #c43b32; display: none; font-size: 13px; }
4323
+ .modal-field { display: grid; gap: 6px; }
4324
+ .modal-label { font-size: 12px; font-weight: 600; color: var(--muted); }
4325
+ .modal-error { color: #ef4444; display: none; font-size: 13px; font-weight: 500; }
4308
4326
  .modal-error[data-visible="true"] { display: block; }
4309
4327
  .modal-actions {
4310
4328
  display: flex;
@@ -4312,25 +4330,35 @@ function renderDevHarnessHtml(state, options = {}) {
4312
4330
  justify-content: flex-end;
4313
4331
  }
4314
4332
  .modal-button {
4315
- border-radius: 9px;
4316
- font-weight: 750;
4317
- min-height: 38px;
4318
- padding: 0 13px;
4333
+ border-radius: 8px;
4334
+ font-size: 13px;
4335
+ font-weight: 600;
4336
+ min-height: 36px;
4337
+ padding: 0 14px;
4338
+ transition: background 120ms ease, transform 100ms ease;
4319
4339
  }
4340
+ .modal-button:active { transform: scale(0.98); }
4320
4341
  .modal-button[data-variant="secondary"] {
4321
4342
  background: transparent;
4322
4343
  border: 1px solid var(--border);
4323
4344
  color: var(--text);
4324
4345
  }
4346
+ .modal-button[data-variant="secondary"]:hover {
4347
+ background: var(--panel-soft);
4348
+ }
4325
4349
  .modal-button[data-variant="primary"] {
4326
4350
  background: var(--control-bg);
4327
4351
  border: 1px solid var(--control-bg);
4328
4352
  color: var(--control-text);
4329
4353
  }
4354
+ .modal-button[data-variant="primary"]:hover {
4355
+ opacity: 0.9;
4356
+ }
4330
4357
  .modal-button:disabled {
4331
4358
  cursor: wait;
4332
4359
  opacity: .68;
4333
4360
  }
4361
+
4334
4362
  .stage {
4335
4363
  display: flex;
4336
4364
  flex: 1 1 auto;
@@ -4339,21 +4367,23 @@ function renderDevHarnessHtml(state, options = {}) {
4339
4367
  }
4340
4368
  .surface {
4341
4369
  background: var(--bg);
4342
- box-shadow: none;
4343
4370
  display: flex;
4344
4371
  flex-direction: column;
4345
4372
  height: 100%;
4346
4373
  min-height: 0;
4347
4374
  overflow: hidden;
4348
- transition: width 160ms ease, height 160ms ease, border-radius 160ms ease, box-shadow 160ms ease;
4375
+ margin: 0 auto;
4376
+ max-width: 800px;
4349
4377
  width: 100%;
4378
+ transition: width 160ms ease, height 160ms ease, border-radius 160ms ease, box-shadow 160ms ease;
4350
4379
  }
4351
4380
  :root[data-sidecar-device="mobile"] .surface {
4352
4381
  border: 1px solid var(--border);
4353
- border-radius: 28px;
4382
+ border-radius: 24px;
4354
4383
  box-shadow: var(--shadow);
4355
- height: min(820px, calc(100dvh - 112px));
4384
+ height: min(800px, calc(100dvh - 112px));
4356
4385
  width: var(--mobile-width);
4386
+ max-width: var(--mobile-width);
4357
4387
  }
4358
4388
  :root[data-sidecar-device="mobile"] .stage {
4359
4389
  align-items: center;
@@ -4368,162 +4398,268 @@ function renderDevHarnessHtml(state, options = {}) {
4368
4398
  display: flex;
4369
4399
  gap: 10px;
4370
4400
  justify-content: space-between;
4371
- min-height: 50px;
4372
- padding: 0 16px;
4401
+ min-height: 48px;
4402
+ padding: 0 20px;
4373
4403
  }
4374
- .surface-title { align-items: center; display: flex; gap: 8px; font-weight: 760; }
4404
+ .surface-title { align-items: center; display: flex; gap: 8px; font-weight: 600; font-size: 13px; color: var(--text); }
4375
4405
  .surface-dot {
4376
4406
  background: var(--accent);
4377
4407
  border-radius: 999px;
4378
- box-shadow: 0 0 0 4px var(--ring);
4379
- height: 8px;
4380
- width: 8px;
4408
+ box-shadow: 0 0 0 3px var(--ring);
4409
+ height: 6px;
4410
+ width: 6px;
4411
+ transition: background 150ms ease, box-shadow 150ms ease;
4381
4412
  }
4382
- .surface-meta { color: var(--muted); font-size: 12px; }
4413
+ .surface-meta { color: var(--muted); font-size: 11px; font-weight: 500; }
4414
+
4383
4415
  .messages {
4384
4416
  display: flex;
4385
4417
  flex-direction: column;
4386
4418
  flex: 1 1 auto;
4387
- gap: 14px;
4419
+ gap: 24px;
4388
4420
  min-height: 0;
4389
4421
  overflow: auto;
4390
- padding: 18px 16px;
4422
+ padding: 24px 20px;
4391
4423
  width: 100%;
4392
4424
  }
4393
4425
  .message {
4394
4426
  display: grid;
4395
4427
  gap: 8px;
4428
+ max-width: 100%;
4396
4429
  }
4397
4430
  .message[data-role="user"] {
4398
- background: color-mix(in srgb, var(--accent) 13%, transparent);
4399
- border-radius: 18px 18px 4px 18px;
4431
+ background: var(--user-bubble-bg);
4432
+ border: 1px solid var(--border);
4433
+ border-radius: 16px;
4400
4434
  color: var(--text);
4401
4435
  justify-self: end;
4402
4436
  margin-left: auto;
4403
- max-width: 85%;
4404
- padding: 9px 12px;
4437
+ max-width: 80%;
4438
+ padding: 12px 16px;
4439
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);
4440
+ }
4441
+ :root[data-sidecar-device="mobile"] .message[data-role="user"] { max-width: 90%; }
4442
+
4443
+ .message[data-role="assistant"] {
4444
+ justify-self: start;
4445
+ margin-right: auto;
4446
+ width: 100%;
4447
+ padding: 0 4px;
4405
4448
  }
4406
- :root[data-sidecar-device="mobile"] .message[data-role="user"] { max-width: 92%; }
4407
- .message[data-role="assistant"], .tool-card { width: 100%; }
4408
4449
  .role { display: none; }
4409
- .tool-title {
4410
- color: var(--muted);
4411
- font-size: 11px;
4412
- font-weight: 800;
4413
- letter-spacing: .05em;
4414
- text-transform: uppercase;
4450
+
4451
+ .content {
4452
+ font-size: 14px;
4453
+ line-height: 1.55;
4454
+ overflow-wrap: anywhere;
4455
+ white-space: pre-wrap;
4456
+ }
4457
+ .content.error {
4458
+ color: #ef4444;
4459
+ }
4460
+ .content.markdown {
4461
+ display: grid;
4462
+ gap: 12px;
4463
+ white-space: normal;
4464
+ }
4465
+ .content.markdown p {
4466
+ margin: 0;
4467
+ line-height: 1.55;
4468
+ }
4469
+ .content.markdown ul, .content.markdown ol {
4470
+ margin: 0;
4471
+ padding-left: 20px;
4472
+ }
4473
+ .content.markdown li {
4474
+ margin-bottom: 4px;
4415
4475
  }
4416
- .content { font-size: 14px; overflow-wrap: anywhere; white-space: pre-wrap; }
4417
- .content.markdown { display: grid; gap: 10px; white-space: normal; }
4418
- .content.markdown > * { margin-block: 0; }
4419
- .content.markdown p { margin: 0; }
4420
- .content.markdown ul, .content.markdown ol { margin: 0; padding-left: 20px; }
4421
4476
  .content.markdown pre {
4422
- background: color-mix(in srgb, var(--panel-soft) 78%, black);
4477
+ background: var(--code-bg);
4423
4478
  border: 1px solid var(--border);
4424
4479
  border-radius: 10px;
4425
4480
  overflow: auto;
4426
- padding: 10px;
4481
+ padding: 14px;
4482
+ margin: 8px 0;
4427
4483
  }
4428
4484
  .content.markdown code {
4429
- background: var(--panel-soft);
4430
- border-radius: 5px;
4431
- font-size: .93em;
4432
- padding: 1px 4px;
4485
+ background: var(--code-inline-bg);
4486
+ border-radius: 4px;
4487
+ font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
4488
+ font-size: 0.88em;
4489
+ padding: 2px 5px;
4490
+ }
4491
+ .content.markdown pre code {
4492
+ background: transparent;
4493
+ padding: 0;
4494
+ font-size: 0.88em;
4495
+ line-height: 1.5;
4433
4496
  }
4434
- .content.markdown pre code { background: transparent; padding: 0; }
4435
4497
  .content.markdown table {
4436
4498
  border-collapse: collapse;
4437
4499
  display: block;
4438
4500
  max-width: 100%;
4439
4501
  overflow-x: auto;
4502
+ margin: 12px 0;
4440
4503
  }
4441
4504
  .content.markdown th, .content.markdown td {
4442
4505
  border: 1px solid var(--border);
4443
- padding: 6px 8px;
4506
+ padding: 8px 12px;
4444
4507
  text-align: left;
4445
4508
  }
4509
+ .content.markdown th {
4510
+ background: var(--panel-soft);
4511
+ font-weight: 600;
4512
+ }
4513
+
4446
4514
  .tool-card {
4447
- background: transparent;
4515
+ background: var(--panel);
4448
4516
  border: 1px solid var(--border);
4449
- border-radius: 12px;
4517
+ border-radius: 14px;
4450
4518
  overflow: hidden;
4519
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.02);
4520
+ margin: 8px 0;
4521
+ width: 100%;
4451
4522
  }
4452
4523
  .tool-head {
4453
4524
  align-items: center;
4454
- background: color-mix(in srgb, var(--panel-soft) 58%, transparent);
4525
+ background: var(--panel-soft);
4455
4526
  border-bottom: 1px solid var(--border);
4456
4527
  display: flex;
4457
4528
  justify-content: space-between;
4458
- padding: 7px 10px;
4529
+ padding: 10px 14px;
4459
4530
  }
4460
- .tool-body { display: grid; gap: 10px; padding: 12px; }
4531
+ .tool-title {
4532
+ color: var(--text);
4533
+ font-size: 12px;
4534
+ font-weight: 600;
4535
+ letter-spacing: 0;
4536
+ }
4537
+ .tool-head .status {
4538
+ font-size: 11px;
4539
+ font-weight: 500;
4540
+ background: rgba(0, 0, 0, 0.04);
4541
+ padding: 2px 8px;
4542
+ border-radius: 6px;
4543
+ color: var(--muted);
4544
+ }
4545
+ :root[data-sidecar-theme="dark"] .tool-head .status {
4546
+ background: rgba(255, 255, 255, 0.05);
4547
+ }
4548
+ .tool-body { display: grid; gap: 10px; padding: 14px; background: var(--panel); }
4549
+
4461
4550
  iframe {
4462
4551
  background: var(--widget-bg);
4463
4552
  border: 1px solid var(--border);
4464
- border-radius: 14px;
4553
+ border-radius: 10px;
4465
4554
  min-height: 380px;
4466
4555
  width: 100%;
4467
4556
  }
4468
4557
  :root[data-sidecar-device="mobile"] iframe { min-height: 520px; }
4558
+
4469
4559
  .composer {
4470
4560
  background: var(--bg);
4471
- padding: 10px 16px 14px;
4561
+ padding: 14px 20px 24px;
4472
4562
  flex: 0 0 auto;
4473
4563
  }
4474
4564
  form {
4475
- align-items: end;
4476
4565
  display: flex;
4477
- gap: 8px;
4566
+ width: 100%;
4567
+ }
4568
+ .composer-container {
4569
+ background: var(--panel);
4570
+ border: 1px solid var(--border);
4571
+ border-radius: 16px;
4572
+ display: flex;
4573
+ flex-direction: column;
4574
+ width: 100%;
4575
+ transition: border-color 150ms ease, box-shadow 150ms ease;
4576
+ }
4577
+ .composer-container:focus-within {
4578
+ border-color: var(--accent);
4579
+ box-shadow: 0 0 0 1px var(--accent), 0 0 0 4px var(--ring);
4478
4580
  }
4479
4581
  textarea {
4480
- background: color-mix(in srgb, var(--panel-soft) 35%, transparent);
4582
+ background: transparent;
4481
4583
  border: 0;
4584
+ color: var(--text);
4585
+ font: inherit;
4586
+ font-size: 14px;
4482
4587
  min-height: 56px;
4483
- max-height: 124px;
4484
- padding: 10px 44px 10px 12px;
4588
+ max-height: 160px;
4589
+ padding: 14px 16px 8px;
4485
4590
  resize: none;
4486
4591
  width: 100%;
4592
+ outline: none;
4593
+ }
4594
+ .composer-toolbar {
4595
+ align-items: center;
4596
+ display: flex;
4597
+ justify-content: space-between;
4598
+ min-height: 44px;
4599
+ padding: 4px 8px 8px 16px;
4487
4600
  }
4488
4601
  .send {
4489
4602
  align-items: center;
4490
4603
  aspect-ratio: 1;
4491
- align-self: center;
4492
4604
  background: var(--send-bg);
4605
+ border: 0;
4493
4606
  border-radius: 999px;
4494
4607
  color: var(--send-text);
4495
4608
  display: inline-flex;
4496
- height: 36px;
4609
+ height: 32px;
4497
4610
  justify-content: center;
4498
- margin-left: -52px;
4499
- min-height: 36px;
4500
4611
  padding: 0;
4501
- width: 36px;
4612
+ width: 32px;
4613
+ transition: transform 120ms ease, opacity 120ms ease;
4614
+ }
4615
+ .send:hover {
4616
+ transform: scale(1.04);
4617
+ filter: brightness(1.1);
4618
+ }
4619
+ .send:active {
4620
+ transform: scale(0.96);
4502
4621
  }
4503
- .send:hover { filter: brightness(.96); }
4504
- :root[data-sidecar-theme="dark"] .send:hover { filter: brightness(1.08); }
4505
4622
  .send svg {
4506
4623
  display: block;
4507
- height: 18px;
4508
- stroke-width: 2.4;
4509
- width: 18px;
4624
+ height: 16px;
4625
+ stroke-width: 2.5;
4626
+ width: 16px;
4627
+ }
4628
+ .status {
4629
+ color: var(--muted);
4630
+ font-size: 12px;
4631
+ font-weight: 500;
4632
+ display: flex;
4633
+ align-items: center;
4634
+ gap: 6px;
4635
+ }
4636
+ .status.error {
4637
+ color: #ef4444;
4510
4638
  }
4511
- .status { color: var(--muted); font-size: 12px; }
4512
- .error { color: #c43b32; }
4513
4639
  .empty {
4514
4640
  align-self: center;
4515
4641
  color: var(--muted);
4516
- display: grid;
4642
+ display: flex;
4643
+ flex-direction: column;
4517
4644
  gap: 8px;
4518
- justify-self: center;
4519
4645
  margin: auto 0;
4520
- padding: 24px 12px;
4646
+ max-width: 320px;
4647
+ padding: 40px 16px;
4521
4648
  text-align: center;
4522
4649
  }
4523
- .empty strong { color: var(--text); font-size: 16px; }
4650
+ .empty strong {
4651
+ color: var(--text);
4652
+ font-size: 16px;
4653
+ font-weight: 500;
4654
+ letter-spacing: 0;
4655
+ }
4656
+ .empty span {
4657
+ font-size: 13px;
4658
+ line-height: 1.5;
4659
+ }
4524
4660
  pre {
4525
4661
  background: var(--panel-soft);
4526
- border-radius: 12px;
4662
+ border-radius: 10px;
4527
4663
  margin: 0;
4528
4664
  overflow: auto;
4529
4665
  padding: 12px;
@@ -4533,96 +4669,98 @@ function renderDevHarnessHtml(state, options = {}) {
4533
4669
  .topbar { align-items: stretch; flex-direction: column; min-height: 0; padding: 12px; }
4534
4670
  .brand { min-width: 0; }
4535
4671
  .controls { justify-content: flex-start; }
4536
- .auth-trigger { min-height: 38px; }
4672
+ .auth-trigger { min-height: 36px; }
4537
4673
  .stage { display: flex; justify-content: center; padding: 12px; }
4538
4674
  .surface { border: 1px solid var(--border); border-radius: 20px; box-shadow: var(--shadow); width: calc(100vw - 24px); }
4539
- .send { flex: 0 0 32px; }
4540
4675
  }
4541
4676
  </style>
4542
4677
  </head>
4543
- <body>
4544
- <main class="shell">
4545
- <section class="content-shell">
4546
- <div class="topbar">
4547
- <div class="brand">
4548
- <h1>Sidecar dev</h1>
4549
- <div class="subtitle">Local MCP app simulator</div>
4550
- </div>
4551
- <div class="controls">
4552
- <div class="control-group">
4553
- <div class="segmented" aria-label="Host">
4554
- <button type="button" data-host="chatgpt" aria-label="ChatGPT preview" title="ChatGPT"><span class="icon">${iconSvg("chatgpt")}</span><span class="button-text">ChatGPT</span></button>
4555
- <button type="button" data-host="claude" aria-label="Claude preview" title="Claude"><span class="icon">${iconSvg("claude")}</span><span class="button-text">Claude</span></button>
4556
- <button type="button" data-host="generic" aria-label="Generic MCP preview" title="MCP"><span class="icon">${iconSvg("braces")}</span><span class="button-text">MCP</span></button>
4557
- </div>
4558
- </div>
4559
- <div class="control-group">
4560
- <div class="segmented" aria-label="Theme">
4561
- <button type="button" data-theme="light" aria-label="Light theme" title="Light"><span class="icon">${iconSvg("sun")}</span><span class="button-text">Light</span></button>
4562
- <button type="button" data-theme="dark" aria-label="Dark theme" title="Dark"><span class="icon">${iconSvg("moon")}</span><span class="button-text">Dark</span></button>
4563
- </div>
4564
- </div>
4565
- <div class="control-group">
4566
- <div class="segmented" aria-label="Device">
4567
- <button type="button" data-device="desktop" aria-label="Desktop preview" title="Desktop"><span class="icon">${iconSvg("monitor")}</span><span class="button-text">Desktop</span></button>
4568
- <button type="button" data-device="mobile" aria-label="Mobile preview" title="Mobile"><span class="icon">${iconSvg("phone")}</span><span class="button-text">Mobile</span></button>
4569
- </div>
4570
- </div>
4571
- <button id="authTrigger" class="auth-trigger" type="button" data-token-set="false">
4572
- <span>Set Bearer Token</span>
4573
- </button>
4574
- </div>
4575
- </div>
4576
- <section class="stage">
4577
- <aside class="surface" aria-label="Sidecar chat preview">
4578
- <div class="surface-bar">
4579
- <div class="surface-title"><span class="surface-dot"></span><span id="surfaceTitle">Claude preview</span></div>
4580
- <div id="surfaceMeta" class="surface-meta">Desktop</div>
4581
- </div>
4582
- <section id="messages" class="messages">
4583
- <div class="empty"><strong>Start a local MCP run.</strong><span>Ask for a tool call, then inspect model text and widget output here.</span></div>
4584
- </section>
4585
- <section class="composer">
4586
- <form id="chatForm">
4587
- <textarea id="prompt" placeholder="Ask a question or request a tool call..."></textarea>
4588
- <button class="send" type="submit" aria-label="Send">
4589
- <svg aria-hidden="true" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round">
4590
- <path d="M12 19V5" />
4591
- <path d="m5 12 7-7 7 7" />
4592
- </svg>
4593
- </button>
4594
- </form>
4595
- <div id="status" class="status"></div>
4596
- </section>
4597
- </aside>
4598
- </section>
4599
- </section>
4600
- </main>
4601
- <div id="authModal" class="modal-overlay" data-open="false" aria-hidden="true">
4602
- <section class="modal-panel" role="dialog" aria-modal="true" aria-labelledby="authModalTitle" aria-describedby="authModalDescription">
4603
- <div class="modal-head">
4604
- <div>
4605
- <h2 id="authModalTitle" class="modal-title">Set bearer token</h2>
4606
- <p id="authModalDescription" class="modal-description">Sidecar will test this token against the local MCP server before saving it.</p>
4607
- </div>
4608
- <button id="authClose" class="modal-close" type="button" aria-label="Close bearer token dialog">${iconSvg("x")}</button>
4609
- </div>
4610
- <label class="modal-field" for="authToken">
4611
- <span class="modal-label">Bearer token</span>
4612
- <input id="authToken" class="modal-input" type="password" autocomplete="off" placeholder="Paste a bearer token" />
4613
- </label>
4614
- <div id="authError" class="modal-error" role="status"></div>
4615
- <div class="modal-actions">
4616
- <button id="authCancel" class="modal-button" data-variant="secondary" type="button">Cancel</button>
4617
- <button id="authSave" class="modal-button" data-variant="primary" type="button">Save</button>
4618
- </div>
4619
- </section>
4620
- </div>
4678
+ <body>
4679
+ <main class="shell">
4680
+ <section class="content-shell">
4681
+ <div class="topbar">
4682
+ <div class="brand">
4683
+ <h1>Sidecar dev</h1>
4684
+ </div>
4685
+ <div class="controls">
4686
+ <div class="control-group">
4687
+ <div class="segmented" aria-label="Host">
4688
+ <button type="button" data-host="chatgpt" aria-label="ChatGPT preview" title="ChatGPT"><span class="icon">${iconSvg("chatgpt")}</span><span class="button-text">ChatGPT</span></button>
4689
+ <button type="button" data-host="claude" aria-label="Claude preview" title="Claude"><span class="icon">${iconSvg("claude")}</span><span class="button-text">Claude</span></button>
4690
+ <button type="button" data-host="generic" aria-label="Generic MCP preview" title="MCP"><span class="icon">${iconSvg("braces")}</span><span class="button-text">MCP</span></button>
4691
+ </div>
4692
+ </div>
4693
+ <div class="control-group">
4694
+ <div class="segmented" aria-label="Theme">
4695
+ <button type="button" data-theme="light" aria-label="Light theme" title="Light"><span class="icon">${iconSvg("sun")}</span><span class="button-text">Light</span></button>
4696
+ <button type="button" data-theme="dark" aria-label="Dark theme" title="Dark"><span class="icon">${iconSvg("moon")}</span><span class="button-text">Dark</span></button>
4697
+ </div>
4698
+ </div>
4699
+ <div class="control-group">
4700
+ <div class="segmented" aria-label="Device">
4701
+ <button type="button" data-device="desktop" aria-label="Desktop preview" title="Desktop"><span class="icon">${iconSvg("monitor")}</span><span class="button-text">Desktop</span></button>
4702
+ <button type="button" data-device="mobile" aria-label="Mobile preview" title="Mobile"><span class="icon">${iconSvg("phone")}</span><span class="button-text">Mobile</span></button>
4703
+ </div>
4704
+ </div>
4705
+ <button id="authTrigger" class="auth-trigger" type="button" data-token-set="false">
4706
+ <span>Set Bearer Token</span>
4707
+ </button>
4708
+ </div>
4709
+ </div>
4710
+ <section class="stage">
4711
+ <aside class="surface" aria-label="Sidecar chat preview">
4712
+ <div class="surface-bar">
4713
+ <div class="surface-title"><span class="surface-dot"></span><span id="surfaceTitle">Claude preview</span></div>
4714
+ <div id="surfaceMeta" class="surface-meta">Desktop</div>
4715
+ </div>
4716
+ <section id="messages" class="messages">
4717
+ <div class="empty"><strong>Start a local MCP run.</strong><span>Ask for a tool call, then inspect model text and widget output here.</span></div>
4718
+ </section>
4719
+ <section class="composer">
4720
+ <form id="chatForm">
4721
+ <div class="composer-container">
4722
+ <textarea id="prompt" placeholder="Ask a question or request a tool call..."></textarea>
4723
+ <div class="composer-toolbar">
4724
+ <div id="status" class="status"></div>
4725
+ <button class="send" type="submit" aria-label="Send">
4726
+ <svg aria-hidden="true" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round">
4727
+ <path d="M12 19V5" />
4728
+ <path d="m5 12 7-7 7 7" />
4729
+ </svg>
4730
+ </button>
4731
+ </div>
4732
+ </div>
4733
+ </form>
4734
+ </section>
4735
+ </aside>
4736
+ </section>
4737
+ </section>
4738
+ </main>
4739
+ <div id="authModal" class="modal-overlay" data-open="false" aria-hidden="true">
4740
+ <section class="modal-panel" role="dialog" aria-modal="true" aria-labelledby="authModalTitle" aria-describedby="authModalDescription">
4741
+ <div class="modal-head">
4742
+ <div>
4743
+ <h2 id="authModalTitle" class="modal-title">Set bearer token</h2>
4744
+ <p id="authModalDescription" class="modal-description">Sidecar will test this token against the local MCP server before saving it.</p>
4745
+ </div>
4746
+ <button id="authClose" class="modal-close" type="button" aria-label="Close bearer token dialog">${iconSvg("x")}</button>
4747
+ </div>
4748
+ <label class="modal-field" for="authToken">
4749
+ <span class="modal-label">Bearer token</span>
4750
+ <input id="authToken" class="modal-input" type="password" autocomplete="off" placeholder="Paste a bearer token" />
4751
+ </label>
4752
+ <div id="authError" class="modal-error" role="status"></div>
4753
+ <div class="modal-actions">
4754
+ <button id="authCancel" class="modal-button" data-variant="secondary" type="button">Cancel</button>
4755
+ <button id="authSave" class="modal-button" data-variant="primary" type="button">Save</button>
4756
+ </div>
4757
+ </section>
4758
+ </div>
4621
4759
  <script>
4622
4760
  ${devHarnessBrowserScript(options.initialBearerToken)}
4623
4761
  </script>
4624
4762
  </body>
4625
- </html>`;
4763
+ </html>`;
4626
4764
  }
4627
4765
  var lobeIconCache = /* @__PURE__ */ new Map();
4628
4766
  function iconSvg(name) {
@@ -5171,8 +5309,6 @@ const authSaveEl = document.getElementById("authSave");
5171
5309
  const authErrorEl = document.getElementById("authError");
5172
5310
  const surfaceTitleEl = document.getElementById("surfaceTitle");
5173
5311
  const surfaceMetaEl = document.getElementById("surfaceMeta");
5174
- const workspaceTargetEl = document.getElementById("workspaceTarget");
5175
- const workspaceDeviceEl = document.getElementById("workspaceDevice");
5176
5312
  const initialBearerToken = ${JSON.stringify(initialBearerToken ?? "")};
5177
5313
  let bearerToken = initialBearerToken || localStorage.getItem("sidecar.dev.bearer") || "";
5178
5314
 
@@ -5194,6 +5330,19 @@ document.addEventListener("keydown", (event) => {
5194
5330
  }
5195
5331
  });
5196
5332
 
5333
+ const resizePrompt = () => {
5334
+ promptEl.style.height = "auto";
5335
+ promptEl.style.height = promptEl.scrollHeight + "px";
5336
+ };
5337
+ promptEl.addEventListener("input", resizePrompt);
5338
+ promptEl.addEventListener("keydown", (event) => {
5339
+ if (event.key === "Enter" && !event.shiftKey) {
5340
+ event.preventDefault();
5341
+ form.requestSubmit();
5342
+ }
5343
+ });
5344
+ resizePrompt();
5345
+
5197
5346
  document.querySelectorAll("[data-host]").forEach((button) => {
5198
5347
  button.addEventListener("click", () => setState({ host: button.dataset.host }));
5199
5348
  });
@@ -5214,17 +5363,23 @@ form.addEventListener("submit", async (event) => {
5214
5363
  const text = promptEl.value.trim();
5215
5364
  if (!text) return;
5216
5365
  promptEl.value = "";
5366
+ resizePrompt();
5217
5367
  clearEmpty();
5218
5368
  messages.push({ role: "user", content: text });
5219
5369
  appendMessage("user", text);
5220
5370
  const assistant = appendMessage("assistant", "");
5371
+ statusEl.classList.remove("error");
5221
5372
  statusEl.textContent = "Thinking...";
5222
5373
  try {
5223
5374
  await streamChat(assistant.querySelector(".content"));
5375
+ statusEl.classList.remove("error");
5224
5376
  statusEl.textContent = "";
5225
5377
  } catch (error) {
5226
- statusEl.textContent = error instanceof Error ? error.message : String(error);
5227
- statusEl.classList.add("error");
5378
+ const message = error instanceof Error ? error.message : String(error);
5379
+ statusEl.classList.remove("error");
5380
+ statusEl.textContent = "";
5381
+ const assistantError = renderAssistantError(assistant.querySelector(".content"), message);
5382
+ messages.push({ role: "assistant", content: assistantError });
5228
5383
  }
5229
5384
  });
5230
5385
 
@@ -5385,6 +5540,13 @@ function renderMarkdown(element, markdown) {
5385
5540
  }
5386
5541
  }
5387
5542
 
5543
+ function renderAssistantError(element, message) {
5544
+ const text = "Sidecar dev hit an error:\\n\\n" + message;
5545
+ element.classList.add("error");
5546
+ renderMarkdown(element, text);
5547
+ return text;
5548
+ }
5549
+
5388
5550
  function appendToolStart(tool) {
5389
5551
  const article = document.createElement("article");
5390
5552
  article.className = "tool-card";
@@ -5544,12 +5706,6 @@ function applyState(next) {
5544
5706
  syncSegmentedControl("[data-device]", state.device, "device");
5545
5707
  surfaceTitleEl.textContent = (state.host === "generic" ? "MCP" : state.host === "chatgpt" ? "ChatGPT" : "Claude") + " preview";
5546
5708
  surfaceMetaEl.textContent = state.device === "mobile" ? "Mobile" : "Desktop";
5547
- if (workspaceTargetEl) {
5548
- workspaceTargetEl.textContent = state.host === "generic" ? "MCP" : state.host === "chatgpt" ? "ChatGPT" : "Claude";
5549
- }
5550
- if (workspaceDeviceEl) {
5551
- workspaceDeviceEl.textContent = state.device === "mobile" ? "Mobile" : "Desktop";
5552
- }
5553
5709
  for (const source of frameContexts.keys()) {
5554
5710
  notify(source, "ui/notifications/host-context-changed", hostContext());
5555
5711
  }