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

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