dsh-tacit 0.5.0 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/client/client.js +333 -201
- package/package.json +1 -1
package/client/client.js
CHANGED
|
@@ -108,12 +108,15 @@ if (typeof window === 'undefined' || window.__ModuleLoader__ === undefined || ty
|
|
|
108
108
|
'steer.receiptEvaluated': '评定于',
|
|
109
109
|
'steer.receiptVersion': '版本',
|
|
110
110
|
'steer.receiptTrial': '试用窗口',
|
|
111
|
-
'steer.
|
|
111
|
+
'steer.receiptTurns': '{n} 轮',
|
|
112
|
+
'steer.receiptTrialNote': '始于 {started} · 基线:杂乱 {messy}、纠正 {corrected}',
|
|
113
|
+
'steer.receiptCalls': '{n} 次调用',
|
|
114
|
+
'steer.enabled': '启用',
|
|
115
|
+
'steer.options': '选项',
|
|
112
116
|
'steer.receiptTriggers': '触发类别',
|
|
113
117
|
'steer.receiptEvidence': '证据',
|
|
114
118
|
'steer.receiptEvidenceValue': '{turns} 轮,来自 {conversations} 个会话',
|
|
115
119
|
'steer.receiptCost': '提炼花费',
|
|
116
|
-
'steer.receiptCostValue': '{usd} · {calls} 次调用',
|
|
117
120
|
'steer.moveTo': '移到工作区',
|
|
118
121
|
'steer.notSeen': '自 {date} 起未见',
|
|
119
122
|
'settings.auto': '自动分析混乱轮次',
|
|
@@ -394,12 +397,15 @@ if (typeof window === 'undefined' || window.__ModuleLoader__ === undefined || ty
|
|
|
394
397
|
'steer.receiptEvaluated': 'Evaluated',
|
|
395
398
|
'steer.receiptVersion': 'Version',
|
|
396
399
|
'steer.receiptTrial': 'Trial window',
|
|
397
|
-
'steer.
|
|
400
|
+
'steer.receiptTurns': '{n} turns',
|
|
401
|
+
'steer.receiptTrialNote': 'from {started} · baseline messy {messy}, corrections {corrected}',
|
|
402
|
+
'steer.receiptCalls': '{n} calls',
|
|
403
|
+
'steer.enabled': 'Enabled',
|
|
404
|
+
'steer.options': 'Options',
|
|
398
405
|
'steer.receiptTriggers': 'Trigger categories',
|
|
399
406
|
'steer.receiptEvidence': 'Evidence',
|
|
400
407
|
'steer.receiptEvidenceValue': '{turns} turns across {conversations} conversations',
|
|
401
408
|
'steer.receiptCost': 'Distillation cost',
|
|
402
|
-
'steer.receiptCostValue': '{usd} · {calls} calls',
|
|
403
409
|
'steer.moveTo': 'Move to workspace',
|
|
404
410
|
'steer.notSeen': 'not seen since {date}',
|
|
405
411
|
'settings.auto': 'Auto-analyze messy turns',
|
|
@@ -1878,7 +1884,13 @@ if (typeof window === 'undefined' || window.__ModuleLoader__ === undefined || ty
|
|
|
1878
1884
|
return h('div', { className: 'tacit-progress' },
|
|
1879
1885
|
h('div', { className: 'tacit-progress-head' },
|
|
1880
1886
|
h('span', { className: 'tacit-progress-title' }, t('status.learned', { count: String(analyzed) })),
|
|
1881
|
-
|
|
1887
|
+
// The same badge idiom the directive cards use: a dot plus a label,
|
|
1888
|
+
// tinted by state. Off is said in the line below, not twice.
|
|
1889
|
+
autoOn
|
|
1890
|
+
? h('span', { className: 'tacit-badge tacit-badge-active' },
|
|
1891
|
+
h('span', { className: 'tacit-badge-dot', 'aria-hidden': 'true' }),
|
|
1892
|
+
t('status.autoOn', { today: String(today), budget: String(budget) }))
|
|
1893
|
+
: null),
|
|
1882
1894
|
h('div', { className: 'tacit-progress-text' }, autoOn ? t('status.autoHint') : t('status.autoOff')),
|
|
1883
1895
|
hasTrend
|
|
1884
1896
|
? h('div', { className: 'tacit-trend', title: t('status.trendDocs') },
|
|
@@ -1977,8 +1989,10 @@ if (typeof window === 'undefined' || window.__ModuleLoader__ === undefined || ty
|
|
|
1977
1989
|
const status = turn.finished === true
|
|
1978
1990
|
? null
|
|
1979
1991
|
: (isNewest === true
|
|
1980
|
-
? h('span', { className: 'tacit-
|
|
1981
|
-
|
|
1992
|
+
? h('span', { className: 'tacit-badge tacit-badge-active' },
|
|
1993
|
+
h('span', { className: 'tacit-badge-dot', 'aria-hidden': 'true' }),
|
|
1994
|
+
t('turn.running'))
|
|
1995
|
+
: h('span', { className: 'tacit-badge tacit-badge-muted' }, t('turn.interrupted')))
|
|
1982
1996
|
|
|
1983
1997
|
return h('div', { className: 'tacit-row' + (report !== null ? ' tacit-row-analyzed' : '') },
|
|
1984
1998
|
h('div', { className: 'tacit-row-head' },
|
|
@@ -1996,35 +2010,47 @@ if (typeof window === 'undefined' || window.__ModuleLoader__ === undefined || ty
|
|
|
1996
2010
|
h('span', { className: 'tacit-row-time' }, fmtTime(turn.startedAt)),
|
|
1997
2011
|
report !== null ? h('span', { className: 'tacit-chip tacit-chip-trigger' }, t('trigger.' + report.trigger)) : null,
|
|
1998
2012
|
status),
|
|
1999
|
-
|
|
2000
|
-
|
|
2001
|
-
|
|
2002
|
-
h('span', { className: 'tacit-chip' }, t('turn.tokens', { n: fmt(tokens) })),
|
|
2003
|
-
typeof turn.retries === 'number' && turn.retries > 0
|
|
2004
|
-
? h('span', { className: 'tacit-chip tacit-chip-warn' }, t('turn.retries', { n: String(turn.retries) }))
|
|
2005
|
-
: null,
|
|
2013
|
+
// Two controls only, and the row's own action is the solid one:
|
|
2014
|
+
// opening the report is a disclosure, so it stays quiet.
|
|
2015
|
+
h('div', { className: 'tacit-row-actions' },
|
|
2006
2016
|
report !== null
|
|
2007
|
-
? h('button', {
|
|
2008
|
-
|
|
2017
|
+
? h('button', {
|
|
2018
|
+
type: 'button',
|
|
2019
|
+
className: 'tacit-btn tacit-btn-sm tacit-btn-quiet',
|
|
2020
|
+
'aria-expanded': reportOpen,
|
|
2021
|
+
onClick: () => toggleReport(store, turn.turn),
|
|
2022
|
+
}, t('turn.report'),
|
|
2023
|
+
h('span', { className: 'tacit-chevron' + (reportOpen ? ' tacit-chevron-open' : ''), 'aria-hidden': 'true' }, '›'))
|
|
2009
2024
|
: null,
|
|
2010
2025
|
h('button', {
|
|
2011
2026
|
type: 'button',
|
|
2012
|
-
className: 'tacit-btn tacit-btn-sm
|
|
2027
|
+
className: 'tacit-btn tacit-btn-sm',
|
|
2013
2028
|
disabled: analyzing,
|
|
2014
2029
|
onClick: () => analyzeTurn(store, turn.turn),
|
|
2015
2030
|
}, analyzing ? t('turn.analyzing') : (report !== null ? t('turn.reanalyze') : t('turn.analyze'))))),
|
|
2016
2031
|
prompt.length > 0
|
|
2017
2032
|
? h('div', { className: 'tacit-row-prompt' },
|
|
2018
|
-
|
|
2019
|
-
|
|
2020
|
-
className: 'tacit-row-prompt-text',
|
|
2021
|
-
onClick: () => setExpanded((open) => !open),
|
|
2022
|
-
}, expanded ? prompt : promptPreview),
|
|
2033
|
+
// A long prompt is one control: the text itself toggles, and the
|
|
2034
|
+
// trailing word says so. A short one is plain text.
|
|
2023
2035
|
prompt.length > 120
|
|
2024
|
-
? h('button', {
|
|
2025
|
-
|
|
2026
|
-
|
|
2036
|
+
? h('button', {
|
|
2037
|
+
type: 'button',
|
|
2038
|
+
className: 'tacit-row-prompt-text',
|
|
2039
|
+
'aria-expanded': expanded,
|
|
2040
|
+
onClick: () => setExpanded((open) => !open),
|
|
2041
|
+
}, expanded ? prompt : promptPreview,
|
|
2042
|
+
h('span', { className: 'tacit-row-more' }, expanded ? t('turn.collapse') : t('turn.expand')))
|
|
2043
|
+
: h('div', { className: 'tacit-row-prompt-text tacit-row-prompt-static' }, prompt))
|
|
2027
2044
|
: null,
|
|
2045
|
+
// The measurements are context, not headline: one quiet dot-separated
|
|
2046
|
+
// line under the prompt rather than four bordered chips in the header.
|
|
2047
|
+
h('div', { className: 'tacit-row-meta' },
|
|
2048
|
+
h('span', null, t('turn.tools', { n: String(tools) })),
|
|
2049
|
+
h('span', null, t('turn.steps', { n: String(typeof turn.steps === 'number' ? turn.steps : 0) })),
|
|
2050
|
+
h('span', null, t('turn.tokens', { n: fmt(tokens) })),
|
|
2051
|
+
typeof turn.retries === 'number' && turn.retries > 0
|
|
2052
|
+
? h('span', { className: 'tacit-row-meta-warn' }, t('turn.retries', { n: String(turn.retries) }))
|
|
2053
|
+
: null),
|
|
2028
2054
|
typeof turn.enrichment === 'string' && turn.enrichment.length > 0
|
|
2029
2055
|
? h('div', { className: 'tacit-row-enrichment' },
|
|
2030
2056
|
h('span', { className: 'tacit-report-title' }, t('turn.enrichment')),
|
|
@@ -2088,35 +2114,33 @@ if (typeof window === 'undefined' || window.__ModuleLoader__ === undefined || ty
|
|
|
2088
2114
|
|
|
2089
2115
|
return h('div', { className: 'tacit-settings' },
|
|
2090
2116
|
h('div', { className: 'tacit-settings-title' }, t('settings.title')),
|
|
2091
|
-
|
|
2092
|
-
|
|
2093
|
-
|
|
2094
|
-
|
|
2095
|
-
|
|
2096
|
-
|
|
2097
|
-
|
|
2098
|
-
|
|
2099
|
-
|
|
2100
|
-
h('div', { className: 'tacit-settings-row' },
|
|
2101
|
-
h('label', { className: 'tacit-settings-label' }, t('settings.auto')),
|
|
2102
|
-
h('input', { type: 'checkbox', checked: auto, onChange: toggleAuto })),
|
|
2103
|
-
h('div', { className: 'tacit-settings-row' },
|
|
2104
|
-
h('label', { className: 'tacit-settings-label' }, t('settings.learnGood')),
|
|
2105
|
-
h('input', { type: 'checkbox', checked: learnGood, onChange: toggleLearnGood })),
|
|
2106
|
-
h('div', { className: 'tacit-settings-row' },
|
|
2107
|
-
h('label', { className: 'tacit-settings-label' }, t('settings.budget')),
|
|
2117
|
+
FieldRow(t('settings.model'), h('select', {
|
|
2118
|
+
id: 'tacit-tab-model',
|
|
2119
|
+
className: 'tacit-select',
|
|
2120
|
+
value: model,
|
|
2121
|
+
onChange: (event) => applyModel(event.target.value),
|
|
2122
|
+
},
|
|
2123
|
+
h('option', { value: 'deepseek-v4-flash' }, 'deepseek-v4-flash'),
|
|
2124
|
+
h('option', { value: 'deepseek-v4-pro' }, 'deepseek-v4-pro')), 'tacit-tab-model'),
|
|
2125
|
+
FieldRow(t('settings.budget'), [
|
|
2108
2126
|
h('input', {
|
|
2127
|
+
key: 'input',
|
|
2128
|
+
id: 'tacit-tab-budget',
|
|
2109
2129
|
className: 'tacit-input',
|
|
2110
2130
|
type: 'number',
|
|
2111
2131
|
min: 0,
|
|
2112
2132
|
value: budgetText,
|
|
2113
2133
|
onChange: (event) => setBudgetText(event.target.value),
|
|
2114
2134
|
}),
|
|
2115
|
-
h('button', { type: 'button', className: 'tacit-btn tacit-btn-sm', onClick: applyBudget }, t('settings.apply'))
|
|
2116
|
-
|
|
2117
|
-
|
|
2118
|
-
|
|
2119
|
-
h('div', { className: 'tacit-
|
|
2135
|
+
h('button', { key: 'apply', type: 'button', className: 'tacit-btn tacit-btn-sm', onClick: applyBudget }, t('settings.apply')),
|
|
2136
|
+
], 'tacit-tab-budget'),
|
|
2137
|
+
// The three switches read as one group of clickable sentences, the way
|
|
2138
|
+
// the Agent guidance options do.
|
|
2139
|
+
h('div', { className: 'tacit-options' },
|
|
2140
|
+
OptionRow(t('settings.auto'), auto, toggleAuto),
|
|
2141
|
+
OptionRow(t('settings.learnGood'), learnGood, toggleLearnGood),
|
|
2142
|
+
OptionRow(t('settings.live'), live, toggleLive)),
|
|
2143
|
+
h('div', { className: 'tacit-inline' },
|
|
2120
2144
|
h('button', { type: 'button', className: 'tacit-btn tacit-btn-sm', onClick: onClear }, t('settings.clear')),
|
|
2121
2145
|
notice !== null ? h('span', { className: 'tacit-settings-notice' }, notice) : null))
|
|
2122
2146
|
}
|
|
@@ -2148,7 +2172,7 @@ if (typeof window === 'undefined' || window.__ModuleLoader__ === undefined || ty
|
|
|
2148
2172
|
h('div', { className: 'tacit-head-title' }, t('tab')),
|
|
2149
2173
|
h('button', {
|
|
2150
2174
|
type: 'button',
|
|
2151
|
-
className: 'tacit-btn',
|
|
2175
|
+
className: 'tacit-btn tacit-btn-sm tacit-btn-quiet',
|
|
2152
2176
|
onClick: () => setSettingsOpen((open) => !open),
|
|
2153
2177
|
}, settingsOpen ? t('settings.close') : t('settings'))),
|
|
2154
2178
|
StatusCard(kit, { config, profile, auto: store.auto }),
|
|
@@ -2168,11 +2192,10 @@ if (typeof window === 'undefined' || window.__ModuleLoader__ === undefined || ty
|
|
|
2168
2192
|
? h('div', { className: 'tacit-empty' }, t('empty'))
|
|
2169
2193
|
: h('div', null,
|
|
2170
2194
|
h('div', { className: 'tacit-toolbar' },
|
|
2171
|
-
h('span', { className: 'tacit-panel-hint tacit-toolbar-hint' }, t('manual.hint')),
|
|
2172
2195
|
BootstrapButton(kit, { bootstrap: store.bootstrap, onClick: () => bootstrapSession(store) }),
|
|
2173
2196
|
h('button', {
|
|
2174
2197
|
type: 'button',
|
|
2175
|
-
className: 'tacit-btn tacit-btn-sm',
|
|
2198
|
+
className: 'tacit-btn tacit-btn-sm' + (store.selecting ? '' : ' tacit-btn-quiet'),
|
|
2176
2199
|
onClick: () => toggleSelecting(store),
|
|
2177
2200
|
}, store.selecting ? t('coach.selectDone') : t('coach.select')),
|
|
2178
2201
|
store.selecting
|
|
@@ -2183,6 +2206,7 @@ if (typeof window === 'undefined' || window.__ModuleLoader__ === undefined || ty
|
|
|
2183
2206
|
onClick: () => coachSelected(store),
|
|
2184
2207
|
}, store.batchRunning ? t('coach.batchRunning') : t('coach.selected', { n: String(selectedCount) }))
|
|
2185
2208
|
: null),
|
|
2209
|
+
h('div', { className: 'tacit-toolbar-note' }, t('manual.hint')),
|
|
2186
2210
|
turns.map((turn, index) => h(TurnRow, { key: String(turn.turn), kit, store, turn, isNewest: index === 0 }))))
|
|
2187
2211
|
}
|
|
2188
2212
|
}
|
|
@@ -2242,21 +2266,23 @@ if (typeof window === 'undefined' || window.__ModuleLoader__ === undefined || ty
|
|
|
2242
2266
|
: preview.error !== null
|
|
2243
2267
|
? h('div', { className: 'tacit-error' },
|
|
2244
2268
|
t('err.' + String(preview.error.code), { detail: String(preview.error.detail || '') }))
|
|
2245
|
-
|
|
2269
|
+
// What changed is the one sentence that decides Apply, so it
|
|
2270
|
+
// reads before the two columns rather than under them.
|
|
2271
|
+
: h('div', { className: 'tacit-modal-body' },
|
|
2272
|
+
preview.data !== null && typeof preview.data === 'object' && typeof preview.data.rationale === 'string' && preview.data.rationale.length > 0
|
|
2273
|
+
? h('div', { className: 'tacit-modal-rationale' },
|
|
2274
|
+
h('div', { className: 'tacit-modal-col-title' }, t('preview.rationale')),
|
|
2275
|
+
h('div', { className: 'tacit-modal-rationale-text' }, preview.data.rationale))
|
|
2276
|
+
: null,
|
|
2246
2277
|
unchanged
|
|
2247
2278
|
? h('div', { className: 'tacit-modal-unchanged' }, t('preview.unchanged'))
|
|
2248
2279
|
: h('div', { className: 'tacit-modal-cols' },
|
|
2249
2280
|
h('div', { className: 'tacit-modal-col' },
|
|
2250
2281
|
h('div', { className: 'tacit-modal-col-title' }, t('preview.original')),
|
|
2251
2282
|
h('pre', { className: 'tacit-pre' }, preview.original)),
|
|
2252
|
-
h('div', { className: 'tacit-modal-col' },
|
|
2283
|
+
h('div', { className: 'tacit-modal-col tacit-modal-col-improved' },
|
|
2253
2284
|
h('div', { className: 'tacit-modal-col-title' }, t('preview.improved')),
|
|
2254
2285
|
h('pre', { className: 'tacit-pre' }, improvedText))),
|
|
2255
|
-
preview.data !== null && typeof preview.data === 'object' && typeof preview.data.rationale === 'string' && preview.data.rationale.length > 0
|
|
2256
|
-
? h('div', { className: 'tacit-modal-rationale' },
|
|
2257
|
-
h('div', { className: 'tacit-modal-col-title' }, t('preview.rationale')),
|
|
2258
|
-
h('div', { className: 'tacit-modal-rationale-text' }, preview.data.rationale))
|
|
2259
|
-
: null,
|
|
2260
2286
|
h('div', { className: 'tacit-modal-actions' },
|
|
2261
2287
|
unchanged
|
|
2262
2288
|
? null
|
|
@@ -2337,6 +2363,37 @@ if (typeof window === 'undefined' || window.__ModuleLoader__ === undefined || ty
|
|
|
2337
2363
|
|
|
2338
2364
|
// ── Collapsible section card (Settings → Tacit) ────────────────────────
|
|
2339
2365
|
|
|
2366
|
+
/**
|
|
2367
|
+
* One settings row: a label that takes the slack and wraps, and its
|
|
2368
|
+
* control(s) right-aligned. `htmlFor` names the control when it has an id;
|
|
2369
|
+
* checkbox settings use `OptionRow` instead, which is a label all through.
|
|
2370
|
+
*/
|
|
2371
|
+
function FieldRow(label, control, htmlFor) {
|
|
2372
|
+
const controls = Array.isArray(control) ? control : [control]
|
|
2373
|
+
return h('div', { className: 'tacit-field' },
|
|
2374
|
+
h('label', {
|
|
2375
|
+
className: 'tacit-field-label',
|
|
2376
|
+
...(typeof htmlFor === 'string' && htmlFor.length > 0 ? { htmlFor } : {}),
|
|
2377
|
+
}, label),
|
|
2378
|
+
h('div', { className: 'tacit-field-control' }, ...controls))
|
|
2379
|
+
}
|
|
2380
|
+
|
|
2381
|
+
/**
|
|
2382
|
+
* One checkbox setting as a clickable `<label>`, so the hit target is the
|
|
2383
|
+
* whole sentence rather than a 14px box.
|
|
2384
|
+
*/
|
|
2385
|
+
function OptionRow(label, checked, onChange, extra) {
|
|
2386
|
+
return h('label', { className: 'tacit-option' },
|
|
2387
|
+
h('input', {
|
|
2388
|
+
type: 'checkbox',
|
|
2389
|
+
className: 'tacit-check',
|
|
2390
|
+
checked,
|
|
2391
|
+
onChange,
|
|
2392
|
+
...(extra !== null && typeof extra === 'object' ? extra : {}),
|
|
2393
|
+
}),
|
|
2394
|
+
h('span', null, label))
|
|
2395
|
+
}
|
|
2396
|
+
|
|
2340
2397
|
/**
|
|
2341
2398
|
* One accessible collapsible card.
|
|
2342
2399
|
*
|
|
@@ -2366,10 +2423,15 @@ if (typeof window === 'undefined' || window.__ModuleLoader__ === undefined || ty
|
|
|
2366
2423
|
typeof summary === 'string' && summary.length > 0
|
|
2367
2424
|
? h('span', { className: 'tacit-card-summary' }, summary)
|
|
2368
2425
|
: null,
|
|
2369
|
-
count
|
|
2426
|
+
// A zero count is silence, not a figure worth a chip.
|
|
2427
|
+
typeof count === 'number' && count > 0
|
|
2370
2428
|
? h('span', { className: 'tacit-card-count' }, String(count))
|
|
2371
2429
|
: null,
|
|
2372
|
-
h('span', {
|
|
2430
|
+
h('span', {
|
|
2431
|
+
className: 'tacit-chevron tacit-card-chevron' + (isOpen ? ' tacit-chevron-open' : ''),
|
|
2432
|
+
'aria-label': label,
|
|
2433
|
+
title: label,
|
|
2434
|
+
}, '›')),
|
|
2373
2435
|
h('div', { className: 'tacit-card-body', id: bodyId, hidden: !isOpen }, ...kids))
|
|
2374
2436
|
}
|
|
2375
2437
|
|
|
@@ -2444,7 +2506,7 @@ if (typeof window === 'undefined' || window.__ModuleLoader__ === undefined || ty
|
|
|
2444
2506
|
},
|
|
2445
2507
|
},
|
|
2446
2508
|
h('div', {
|
|
2447
|
-
className: 'tacit-modal-card',
|
|
2509
|
+
className: 'tacit-modal-card tacit-modal-card-sm',
|
|
2448
2510
|
role: 'dialog',
|
|
2449
2511
|
'aria-modal': 'true',
|
|
2450
2512
|
'aria-labelledby': 'tacit-confirm-title',
|
|
@@ -2476,31 +2538,54 @@ if (typeof window === 'undefined' || window.__ModuleLoader__ === undefined || ty
|
|
|
2476
2538
|
if (typeof navigator === 'undefined' || navigator === null || !navigator.clipboard || typeof navigator.clipboard.writeText !== 'function') return
|
|
2477
2539
|
navigator.clipboard.writeText(JSON.stringify(receipt, null, 2)).catch(() => {})
|
|
2478
2540
|
}
|
|
2479
|
-
const
|
|
2480
|
-
/**
|
|
2541
|
+
const metaRow = (label, value) => [h('dt', { key: label + '-t' }, label), h('dd', { key: label + '-d' }, value)]
|
|
2542
|
+
/** A null `note` marks an absent value ("never", "no ledger run"), shown quiet rather than as a headline figure. */
|
|
2543
|
+
const tile = (key, label, value, note) => h('div', { key, className: 'tacit-tile tacit-receipt-tile' },
|
|
2544
|
+
h('span', { className: 'tacit-tile-label' }, label),
|
|
2545
|
+
h('span', { className: 'tacit-tile-value' + (note === null ? ' tacit-tile-muted' : '') }, value),
|
|
2546
|
+
note === null ? null : h('span', { className: 'tacit-receipt-tile-note' }, note))
|
|
2547
|
+
const step = (key, label, ms) => h('li', { key, className: 'tacit-timeline-step' + (Number(ms) > 0 ? '' : ' tacit-timeline-never') },
|
|
2548
|
+
h('span', { className: 'tacit-timeline-label' }, label),
|
|
2549
|
+
h('span', { className: 'tacit-timeline-value' }, fmtDay(ms)))
|
|
2550
|
+
/**
|
|
2551
|
+
* What the receipt route returned for this directive, layered: three
|
|
2552
|
+
* tiles, a lifecycle timeline, the trigger chips, then the identity grid;
|
|
2553
|
+
* never any prompt text.
|
|
2554
|
+
*/
|
|
2481
2555
|
function Receipt(receipt) {
|
|
2482
2556
|
if (receipt === null || typeof receipt === 'object' === false) return h('div', { className: 'tacit-panel-hint' }, t('steer.receiptLoading'))
|
|
2483
2557
|
const triggers = Object.entries(receipt.triggers !== null && typeof receipt.triggers === 'object' ? receipt.triggers : {})
|
|
2484
|
-
.map(([name, count]) => triggerName(name) + ' ' + String(count)).join(' · ')
|
|
2485
2558
|
const evidence = receipt.evidence !== null && typeof receipt.evidence === 'object' ? receipt.evidence : { turns: 0, conversations: 0 }
|
|
2486
2559
|
const cost = receipt.cost !== null && typeof receipt.cost === 'object' ? receipt.cost : { usd: null, calls: 0 }
|
|
2487
2560
|
const trial = receipt.trial !== null && typeof receipt.trial === 'object' ? receipt.trial : null
|
|
2488
|
-
return h('div',
|
|
2489
|
-
h('
|
|
2490
|
-
|
|
2491
|
-
|
|
2492
|
-
|
|
2493
|
-
|
|
2494
|
-
|
|
2495
|
-
|
|
2496
|
-
|
|
2497
|
-
|
|
2498
|
-
|
|
2499
|
-
|
|
2500
|
-
|
|
2501
|
-
|
|
2502
|
-
|
|
2503
|
-
h('
|
|
2561
|
+
return h('div', { className: 'tacit-receipt' },
|
|
2562
|
+
h('div', { className: 'tacit-tiles tacit-receipt-tiles' },
|
|
2563
|
+
tile('evidence', t('steer.receiptEvidence'), String(evidence.turns),
|
|
2564
|
+
t('steer.receiptEvidenceValue', { turns: String(evidence.turns), conversations: String(evidence.conversations) })),
|
|
2565
|
+
tile('trial', t('steer.receiptTrial'),
|
|
2566
|
+
trial === null ? t('steer.receiptNever') : t('steer.receiptTurns', { n: String(trial.turns) }),
|
|
2567
|
+
trial === null ? null : t('steer.receiptTrialNote', {
|
|
2568
|
+
started: fmtDay(trial.startedAt), messy: pct(trial.baselineMessyRate), corrected: pct(trial.baselineCorrectionRate) })),
|
|
2569
|
+
tile('cost', t('steer.receiptCost'),
|
|
2570
|
+
cost.usd === null ? t('steer.receiptNoRun') : fmtUsd(cost.usd),
|
|
2571
|
+
cost.usd === null ? null : t('steer.receiptCalls', { n: String(cost.calls) }))),
|
|
2572
|
+
h('ol', { className: 'tacit-timeline' },
|
|
2573
|
+
step('created', t('steer.receiptCreated'), receipt.createdAt),
|
|
2574
|
+
step('updated', t('steer.receiptUpdated'), receipt.updatedAt),
|
|
2575
|
+
step('evaluated', t('steer.receiptEvaluated'), receipt.evaluatedAt)),
|
|
2576
|
+
h('div', { className: 'tacit-receipt-row' },
|
|
2577
|
+
h('span', { className: 'tacit-receipt-label' }, t('steer.receiptTriggers')),
|
|
2578
|
+
triggers.length === 0
|
|
2579
|
+
? h('span', { className: 'tacit-chip tacit-chip-muted' }, t('steer.receiptNever'))
|
|
2580
|
+
: triggers.map(([name, count]) => h('span', { key: name, className: 'tacit-chip' }, triggerName(name) + ' ' + String(count)))),
|
|
2581
|
+
h('dl', { className: 'tacit-receipt-meta' },
|
|
2582
|
+
...metaRow(t('steer.receiptId'), String(receipt.id)),
|
|
2583
|
+
...metaRow(t('steer.receiptVersion'), String(receipt.version)),
|
|
2584
|
+
...metaRow(t('steer.receiptScope'), typeof receipt.scope === 'string' && receipt.scope.length > 0 ? receipt.scope : t('steer.everywhere')),
|
|
2585
|
+
...metaRow(t('steer.receiptSource'), receipt.source === 'user' ? t('steer.user') : t('steer.distilled')),
|
|
2586
|
+
...metaRow(t('steer.receiptStatus'), String(receipt.status))),
|
|
2587
|
+
h('div', { className: 'tacit-receipt-actions' },
|
|
2588
|
+
h('button', { type: 'button', className: 'tacit-btn tacit-btn-sm', onClick: () => copyReceipt(receipt) }, t('steer.receiptCopy'))))
|
|
2504
2589
|
}
|
|
2505
2590
|
return function DirectivesEditorView(props) {
|
|
2506
2591
|
const { config, steering } = props
|
|
@@ -2553,23 +2638,42 @@ if (typeof window === 'undefined' || window.__ModuleLoader__ === undefined || ty
|
|
|
2553
2638
|
setDraft('')
|
|
2554
2639
|
editDirectives({ action: 'add', text: text.slice(0, 300), ...(scope.length > 0 ? { workspace: scope } : {}) })
|
|
2555
2640
|
}
|
|
2556
|
-
|
|
2557
|
-
|
|
2558
|
-
|
|
2559
|
-
|
|
2560
|
-
|
|
2561
|
-
|
|
2562
|
-
|
|
2563
|
-
|
|
2564
|
-
|
|
2565
|
-
|
|
2566
|
-
|
|
2567
|
-
|
|
2568
|
-
|
|
2569
|
-
|
|
2570
|
-
|
|
2571
|
-
|
|
2572
|
-
|
|
2641
|
+
/** The lifecycle badge: one colour per status, the label the chips used to carry. */
|
|
2642
|
+
const statusOf = (entry) => {
|
|
2643
|
+
if (entry.status === 'queued') return { kind: 'queued', label: t('steer.queued') }
|
|
2644
|
+
if (entry.status === 'candidate') {
|
|
2645
|
+
return {
|
|
2646
|
+
kind: 'trial',
|
|
2647
|
+
label: t('steer.trial', {
|
|
2648
|
+
n: String(entry.trial !== null && typeof entry.trial === 'object' && typeof entry.trial.turns === 'number' ? entry.trial.turns : 0),
|
|
2649
|
+
total: String(config !== null && typeof config.directiveTrialTurns === 'number' ? config.directiveTrialTurns : 10),
|
|
2650
|
+
}),
|
|
2651
|
+
}
|
|
2652
|
+
}
|
|
2653
|
+
if (entry.status === 'retired') return { kind: 'retired', label: t('steer.retired', { reason: String(entry.retiredReason || '') }) }
|
|
2654
|
+
return { kind: 'active', label: t('steer.active') }
|
|
2655
|
+
}
|
|
2656
|
+
const directiveCard = (entry) => {
|
|
2657
|
+
const status = statusOf(entry)
|
|
2658
|
+
const scoped = typeof entry.workspace === 'string' && entry.workspace.length > 0
|
|
2659
|
+
return h('div', { key: entry.id, className: 'tacit-dir tacit-dir-' + status.kind + (entry.enabled === false ? ' tacit-dir-off' : '') },
|
|
2660
|
+
h('div', { className: 'tacit-dir-head' },
|
|
2661
|
+
h('span', { className: 'tacit-badge tacit-badge-' + status.kind },
|
|
2662
|
+
h('span', { className: 'tacit-badge-dot', 'aria-hidden': 'true' }),
|
|
2663
|
+
status.label),
|
|
2664
|
+
h('span', { className: 'tacit-chip' }, entry.source === 'user' ? t('steer.user') : t('steer.distilled')),
|
|
2665
|
+
scoped
|
|
2666
|
+
? h('span', { className: 'tacit-chip tacit-chip-scope', title: entry.workspace }, t('steer.workspace', { name: labelOf(entry.workspace) }))
|
|
2667
|
+
: null,
|
|
2668
|
+
scoped && !liveScope(entry.workspace)
|
|
2669
|
+
? h('span', { className: 'tacit-chip tacit-chip-muted', title: entry.workspace }, t('steer.notSeen', { date: notSeenSince(entry) }))
|
|
2670
|
+
: null,
|
|
2671
|
+
reviewOn && entry.status === 'queued' && !(entry.approvedAt > 0)
|
|
2672
|
+
? h('button', { type: 'button', className: 'tacit-btn tacit-btn-sm tacit-btn-primary tacit-dir-start', onClick: () => editDirectives({ action: 'start-trial', id: entry.id }) }, t('steer.startTrial'))
|
|
2673
|
+
: null),
|
|
2674
|
+
h('div', { className: 'tacit-dir-text' }, String(entry.text)),
|
|
2675
|
+
h('div', { className: 'tacit-dir-actions' },
|
|
2676
|
+
h('label', { className: 'tacit-dir-enabled' },
|
|
2573
2677
|
h('input', {
|
|
2574
2678
|
type: 'checkbox',
|
|
2575
2679
|
className: 'tacit-check',
|
|
@@ -2577,46 +2681,33 @@ if (typeof window === 'undefined' || window.__ModuleLoader__ === undefined || ty
|
|
|
2577
2681
|
checked: entry.enabled !== false,
|
|
2578
2682
|
onChange: () => editDirectives({ action: 'toggle', id: entry.id, enabled: entry.enabled === false }),
|
|
2579
2683
|
}),
|
|
2580
|
-
|
|
2581
|
-
|
|
2582
|
-
|
|
2583
|
-
|
|
2584
|
-
|
|
2585
|
-
|
|
2586
|
-
? h('span', { className: 'tacit-chip tacit-chip-muted', title: entry.workspace }, t('steer.notSeen', { date: notSeenSince(entry) }))
|
|
2587
|
-
: null,
|
|
2588
|
-
entry.status === 'queued'
|
|
2589
|
-
? h('span', { className: 'tacit-chip tacit-chip-muted' }, t('steer.queued'))
|
|
2590
|
-
: entry.status === 'candidate'
|
|
2591
|
-
? h('span', { className: 'tacit-chip tacit-chip-trial' }, t('steer.trial', {
|
|
2592
|
-
n: String(entry.trial !== null && typeof entry.trial === 'object' && typeof entry.trial.turns === 'number' ? entry.trial.turns : 0),
|
|
2593
|
-
total: String(config !== null && typeof config.directiveTrialTurns === 'number' ? config.directiveTrialTurns : 10),
|
|
2594
|
-
}))
|
|
2595
|
-
: entry.status === 'retired'
|
|
2596
|
-
? h('span', { className: 'tacit-chip tacit-chip-warn' }, t('steer.retired', { reason: String(entry.retiredReason || '') }))
|
|
2597
|
-
: h('span', { className: 'tacit-chip tacit-chip-ok' }, t('steer.active')),
|
|
2598
|
-
reviewOn && entry.status === 'queued' && !(entry.approvedAt > 0)
|
|
2599
|
-
? h('button', { type: 'button', className: 'tacit-btn tacit-btn-sm', onClick: () => editDirectives({ action: 'start-trial', id: entry.id }) }, t('steer.startTrial'))
|
|
2600
|
-
: null,
|
|
2601
|
-
h('select', {
|
|
2602
|
-
className: 'tacit-input tacit-select tacit-select-sm',
|
|
2603
|
-
'aria-label': t('steer.moveTo'),
|
|
2604
|
-
onChange: (event) => {
|
|
2605
|
-
if (event.target.value !== '-') editDirectives({ action: 'rescope', id: entry.id, workspace: event.target.value })
|
|
2606
|
-
},
|
|
2607
|
-
}, ...scopeOptions(typeof entry.workspace === 'string' ? entry.workspace : '')),
|
|
2608
|
-
h('button', { type: 'button', className: 'tacit-btn tacit-btn-sm', onClick: () => editDirectives({ action: 'remove', id: entry.id }) }, t('steer.remove'))),
|
|
2609
|
-
h('details', {
|
|
2610
|
-
className: 'tacit-preview',
|
|
2611
|
-
'data-testid': 'tacit-receipt',
|
|
2612
|
-
'data-directive-id': entry.id,
|
|
2613
|
-
onToggle: (event) => {
|
|
2614
|
-
if (event.target.open) fetchReceipt(entry.id)
|
|
2615
|
-
},
|
|
2684
|
+
t('steer.enabled')),
|
|
2685
|
+
h('select', {
|
|
2686
|
+
className: 'tacit-input tacit-select tacit-select-sm',
|
|
2687
|
+
'aria-label': t('steer.moveTo'),
|
|
2688
|
+
onChange: (event) => {
|
|
2689
|
+
if (event.target.value !== '-') editDirectives({ action: 'rescope', id: entry.id, workspace: event.target.value })
|
|
2616
2690
|
},
|
|
2617
|
-
|
|
2618
|
-
|
|
2619
|
-
|
|
2691
|
+
}, ...scopeOptions(typeof entry.workspace === 'string' ? entry.workspace : '')),
|
|
2692
|
+
h('button', { type: 'button', className: 'tacit-btn tacit-btn-sm tacit-btn-quiet tacit-dir-remove', onClick: () => editDirectives({ action: 'remove', id: entry.id }) }, t('steer.remove'))),
|
|
2693
|
+
h('details', {
|
|
2694
|
+
className: 'tacit-dir-receipt',
|
|
2695
|
+
'data-testid': 'tacit-receipt',
|
|
2696
|
+
'data-directive-id': entry.id,
|
|
2697
|
+
onToggle: (event) => {
|
|
2698
|
+
if (event.target.open) fetchReceipt(entry.id)
|
|
2699
|
+
},
|
|
2700
|
+
},
|
|
2701
|
+
h('summary', null, t('steer.receipt')),
|
|
2702
|
+
Receipt(receipts[entry.id] ?? null)))
|
|
2703
|
+
}
|
|
2704
|
+
return h('div', { className: 'tacit-panel-section', 'data-testid': 'tacit-steering' },
|
|
2705
|
+
h('div', { className: 'tacit-report-title' }, t('steer.title')),
|
|
2706
|
+
h('div', { className: 'tacit-panel-hint' }, t('steer.desc')),
|
|
2707
|
+
directives.length === 0
|
|
2708
|
+
? h('div', { className: 'tacit-empty' }, t('steer.empty'))
|
|
2709
|
+
: h('div', { className: 'tacit-dir-list' }, directives.map(directiveCard)),
|
|
2710
|
+
h('div', { className: 'tacit-dir-add' },
|
|
2620
2711
|
h('input', {
|
|
2621
2712
|
className: 'tacit-input tacit-directive-input',
|
|
2622
2713
|
type: 'text',
|
|
@@ -2639,7 +2730,12 @@ if (typeof window === 'undefined' || window.__ModuleLoader__ === undefined || ty
|
|
|
2639
2730
|
h('option', { value: '' }, t('steer.everywhere')),
|
|
2640
2731
|
...workspaces.map((entry) => h('option', { key: entry.cwd, value: entry.cwd }, entry.label)))
|
|
2641
2732
|
: null,
|
|
2642
|
-
h('button', { type: 'button', className: 'tacit-btn tacit-btn-sm', disabled: draft.trim().length === 0, onClick: onAdd }, t('steer.add'))),
|
|
2733
|
+
h('button', { type: 'button', className: 'tacit-btn tacit-btn-sm tacit-btn-primary', disabled: draft.trim().length === 0, onClick: onAdd }, t('steer.add'))),
|
|
2734
|
+
h('div', { className: 'tacit-options' },
|
|
2735
|
+
h('div', { className: 'tacit-report-title' }, t('steer.options')),
|
|
2736
|
+
OptionRow(t('steer.toggle'), steerOn, toggleSteer),
|
|
2737
|
+
OptionRow(t('steer.enrich'), enrichOn, toggleEnrich),
|
|
2738
|
+
OptionRow(t('steer.review'), reviewOn, toggleReview)),
|
|
2643
2739
|
steering !== null && typeof steering === 'object' && typeof steering.text === 'string' && steering.text.length > 0
|
|
2644
2740
|
? h('details', { className: 'tacit-preview' },
|
|
2645
2741
|
h('summary', null, t('steer.preview')),
|
|
@@ -2789,19 +2885,15 @@ if (typeof window === 'undefined' || window.__ModuleLoader__ === undefined || ty
|
|
|
2789
2885
|
h('div', { className: 'tacit-settings-notice', role: 'status' }, notice === null ? '' : notice.text),
|
|
2790
2886
|
card('overview', [
|
|
2791
2887
|
StatusCard(kit, { config, profile, auto: rootStore.auto, trend: rootStore.trend }),
|
|
2792
|
-
|
|
2793
|
-
? h('div', { className: 'tacit-settings-row' },
|
|
2794
|
-
h('span', { className: 'tacit-chip' }, t('overview.model', { model: config.model })))
|
|
2795
|
-
: null,
|
|
2796
|
-
h('div', { className: 'tacit-settings-row' },
|
|
2888
|
+
h('div', { className: 'tacit-inline' },
|
|
2797
2889
|
BootstrapButton(kit, {
|
|
2798
2890
|
bootstrap: rootStore.bootstrap,
|
|
2799
2891
|
// Only a loaded preview may disable the button: before one
|
|
2800
2892
|
// lands, "0 eligible" is an absence of data, not a fact.
|
|
2801
2893
|
disabled: preview !== null && preview.eligible === 0,
|
|
2802
2894
|
onClick: () => bootstrapAll(t),
|
|
2803
|
-
}),
|
|
2804
|
-
|
|
2895
|
+
})),
|
|
2896
|
+
h('p', { className: 'tacit-panel-hint' }, t('bootstrap.hint')),
|
|
2805
2897
|
// What the run would actually cost, priced from the ledger once it
|
|
2806
2898
|
// holds enough analyses; until the preview lands, the documented
|
|
2807
2899
|
// figure stands in.
|
|
@@ -2840,41 +2932,40 @@ if (typeof window === 'undefined' || window.__ModuleLoader__ === undefined || ty
|
|
|
2840
2932
|
}),
|
|
2841
2933
|
], { summary: pricingSummary(kit, usagePricing) }),
|
|
2842
2934
|
card('learning', [
|
|
2843
|
-
|
|
2844
|
-
|
|
2845
|
-
|
|
2846
|
-
|
|
2847
|
-
|
|
2848
|
-
|
|
2849
|
-
|
|
2850
|
-
|
|
2851
|
-
|
|
2852
|
-
h('div', { className: 'tacit-settings-row' },
|
|
2853
|
-
h('label', { className: 'tacit-settings-label' }, t('settings.auto')),
|
|
2854
|
-
h('input', { type: 'checkbox', checked: auto, onChange: toggleAuto })),
|
|
2855
|
-
h('div', { className: 'tacit-settings-row' },
|
|
2856
|
-
h('label', { className: 'tacit-settings-label' }, t('settings.learnGood')),
|
|
2857
|
-
h('input', { type: 'checkbox', checked: learnGood, onChange: toggleLearnGood })),
|
|
2858
|
-
h('div', { className: 'tacit-settings-row' },
|
|
2859
|
-
h('label', { className: 'tacit-settings-label' }, t('settings.budget')),
|
|
2935
|
+
FieldRow(t('settings.model'), h('select', {
|
|
2936
|
+
id: 'tacit-learning-model',
|
|
2937
|
+
className: 'tacit-select',
|
|
2938
|
+
value: model,
|
|
2939
|
+
onChange: (event) => applyModel(event.target.value),
|
|
2940
|
+
},
|
|
2941
|
+
h('option', { value: 'deepseek-v4-flash' }, 'deepseek-v4-flash'),
|
|
2942
|
+
h('option', { value: 'deepseek-v4-pro' }, 'deepseek-v4-pro')), 'tacit-learning-model'),
|
|
2943
|
+
FieldRow(t('settings.budget'), [
|
|
2860
2944
|
h('input', {
|
|
2945
|
+
key: 'input',
|
|
2946
|
+
id: 'tacit-learning-budget',
|
|
2861
2947
|
className: 'tacit-input',
|
|
2862
2948
|
type: 'number',
|
|
2863
2949
|
min: 0,
|
|
2864
2950
|
value: budgetText,
|
|
2865
2951
|
onChange: (event) => setBudgetText(event.target.value),
|
|
2866
2952
|
}),
|
|
2867
|
-
h('button', { type: 'button', className: 'tacit-btn tacit-btn-sm', onClick: applyBudget }, t('settings.apply'))
|
|
2868
|
-
|
|
2953
|
+
h('button', { key: 'apply', type: 'button', className: 'tacit-btn tacit-btn-sm', onClick: applyBudget }, t('settings.apply')),
|
|
2954
|
+
], 'tacit-learning-budget'),
|
|
2955
|
+
h('div', { className: 'tacit-options' },
|
|
2956
|
+
OptionRow(t('settings.auto'), auto, toggleAuto),
|
|
2957
|
+
OptionRow(t('settings.learnGood'), learnGood, toggleLearnGood)),
|
|
2958
|
+
// The model in force reads from the collapsed head, where it is set.
|
|
2959
|
+
], config !== null && typeof config.model === 'string' && config.model.length > 0
|
|
2960
|
+
? { summary: t('overview.model', { model: config.model }) }
|
|
2961
|
+
: undefined),
|
|
2869
2962
|
card('guidance', [
|
|
2870
2963
|
h(DirectivesEditorView, {
|
|
2871
2964
|
workspaces: rootStore.workspaces, config, directives, steering: rootStore.steering,
|
|
2872
2965
|
seenAt: rootStore.profile !== null && typeof rootStore.profile === 'object' ? rootStore.profile.workspaceSeenAt : null }),
|
|
2873
|
-
]),
|
|
2966
|
+
], { count: directives.filter((entry) => entry.status !== 'removed').length }),
|
|
2874
2967
|
card('improve', [
|
|
2875
|
-
|
|
2876
|
-
h('label', { className: 'tacit-settings-label' }, t('settings.live')),
|
|
2877
|
-
h('input', { type: 'checkbox', checked: live, onChange: toggleLive })),
|
|
2968
|
+
OptionRow(t('settings.live'), live, toggleLive),
|
|
2878
2969
|
h('div', { className: 'tacit-panel-section' },
|
|
2879
2970
|
h('div', { className: 'tacit-report-title' }, t('panel.styleRules')),
|
|
2880
2971
|
styleRules.length === 0
|
|
@@ -2904,18 +2995,16 @@ if (typeof window === 'undefined' || window.__ModuleLoader__ === undefined || ty
|
|
|
2904
2995
|
], { count: coached.length }),
|
|
2905
2996
|
card('privacy', [
|
|
2906
2997
|
h('p', { className: 'tacit-panel-hint' }, t('privacy.stored')),
|
|
2907
|
-
|
|
2908
|
-
|
|
2909
|
-
|
|
2910
|
-
|
|
2911
|
-
|
|
2912
|
-
|
|
2913
|
-
|
|
2914
|
-
|
|
2915
|
-
...retentionDays.map((days) => h('option', { key: days, value: String(days) }, String(days))))),
|
|
2916
|
-
h('div', { className: 'tacit-settings-row' },
|
|
2917
|
-
h('label', { className: 'tacit-settings-label', htmlFor: 'tacit-warn-daily' }, t('privacy.warnDaily')),
|
|
2998
|
+
FieldRow(t('privacy.retention'), h('select', {
|
|
2999
|
+
id: 'tacit-retention',
|
|
3000
|
+
className: 'tacit-select',
|
|
3001
|
+
value: String(retention),
|
|
3002
|
+
onChange: (event) => updateRootConfig({ costHistoryDays: Number(event.target.value) }),
|
|
3003
|
+
},
|
|
3004
|
+
...retentionDays.map((days) => h('option', { key: days, value: String(days) }, String(days)))), 'tacit-retention'),
|
|
3005
|
+
FieldRow(t('privacy.warnDaily'), [
|
|
2918
3006
|
h('input', {
|
|
3007
|
+
key: 'input',
|
|
2919
3008
|
id: 'tacit-warn-daily',
|
|
2920
3009
|
className: 'tacit-input',
|
|
2921
3010
|
type: 'number',
|
|
@@ -2925,16 +3014,18 @@ if (typeof window === 'undefined' || window.__ModuleLoader__ === undefined || ty
|
|
|
2925
3014
|
onChange: (event) => setDailyText(event.target.value),
|
|
2926
3015
|
}),
|
|
2927
3016
|
h('button', {
|
|
3017
|
+
key: 'apply',
|
|
2928
3018
|
type: 'button',
|
|
2929
3019
|
className: 'tacit-btn tacit-btn-sm',
|
|
2930
3020
|
// Two identically labelled buttons in one card: the accessible
|
|
2931
3021
|
// name has to say which threshold each one applies.
|
|
2932
3022
|
'aria-label': t('privacy.applyTo', { action: t('privacy.apply'), field: t('privacy.warnDaily') }),
|
|
2933
3023
|
onClick: () => applyWarn('costWarnDailyUsd', dailyText, setDailyText),
|
|
2934
|
-
}, t('privacy.apply'))
|
|
2935
|
-
|
|
2936
|
-
|
|
3024
|
+
}, t('privacy.apply')),
|
|
3025
|
+
], 'tacit-warn-daily'),
|
|
3026
|
+
FieldRow(t('privacy.warnMonthly'), [
|
|
2937
3027
|
h('input', {
|
|
3028
|
+
key: 'input',
|
|
2938
3029
|
id: 'tacit-warn-monthly',
|
|
2939
3030
|
className: 'tacit-input',
|
|
2940
3031
|
type: 'number',
|
|
@@ -2944,18 +3035,20 @@ if (typeof window === 'undefined' || window.__ModuleLoader__ === undefined || ty
|
|
|
2944
3035
|
onChange: (event) => setMonthlyText(event.target.value),
|
|
2945
3036
|
}),
|
|
2946
3037
|
h('button', {
|
|
3038
|
+
key: 'apply',
|
|
2947
3039
|
type: 'button',
|
|
2948
3040
|
className: 'tacit-btn tacit-btn-sm',
|
|
2949
3041
|
// Two identically labelled buttons in one card: the accessible
|
|
2950
3042
|
// name has to say which threshold each one applies.
|
|
2951
3043
|
'aria-label': t('privacy.applyTo', { action: t('privacy.apply'), field: t('privacy.warnMonthly') }),
|
|
2952
3044
|
onClick: () => applyWarn('costWarnMonthlyUsd', monthlyText, setMonthlyText),
|
|
2953
|
-
}, t('privacy.apply'))
|
|
3045
|
+
}, t('privacy.apply')),
|
|
3046
|
+
], 'tacit-warn-monthly'),
|
|
2954
3047
|
h('p', { className: 'tacit-panel-hint' }, t('privacy.warnHint')),
|
|
2955
3048
|
// Both clears are irreversible, so both go through the dialog.
|
|
2956
|
-
h('div', { className: 'tacit-
|
|
2957
|
-
h('button', { type: 'button', className: 'tacit-btn tacit-btn-sm', onClick: () => openConfirm('reports') }, t('settings.clear')),
|
|
2958
|
-
h('button', { type: 'button', className: 'tacit-btn tacit-btn-sm', onClick: () => openConfirm('usage') }, t('privacy.clearUsage'))),
|
|
3049
|
+
h('div', { className: 'tacit-inline' },
|
|
3050
|
+
h('button', { type: 'button', className: 'tacit-btn tacit-btn-sm tacit-btn-quiet', onClick: () => openConfirm('reports') }, t('settings.clear')),
|
|
3051
|
+
h('button', { type: 'button', className: 'tacit-btn tacit-btn-sm tacit-btn-quiet', onClick: () => openConfirm('usage') }, t('privacy.clearUsage'))),
|
|
2959
3052
|
]),
|
|
2960
3053
|
// Always rendered (null while closed) so its one effect keeps this
|
|
2961
3054
|
// component's hook count stable.
|
|
@@ -3476,17 +3569,19 @@ if (typeof window === 'undefined' || window.__ModuleLoader__ === undefined || ty
|
|
|
3476
3569
|
|
|
3477
3570
|
const css = '.tacit-root{box-sizing:border-box;height:100%;color:var(--dsw-alias-label-primary);padding:16px 20px 32px;font-size:13px;overflow-y:auto}'
|
|
3478
3571
|
+ '.tacit-head{display:flex;align-items:baseline;gap:8px;margin-bottom:10px}.tacit-head-title{font-size:14px;font-weight:600;margin-right:auto}'
|
|
3479
|
-
+ '.tacit-progress{background:var(--dsw-alias-bg-layer-1);border:1px solid var(--dsw-alias-border-l1);border-radius:8px;padding:8px 12px;margin-bottom:12px;color:var(--dsw-alias-label-secondary);font-size:12px;line-height:1.5}.tacit-progress-title{font-weight:600;color:var(--dsw-alias-label-primary)}'
|
|
3480
|
-
+ '.tacit-empty{color:var(--dsw-alias-label-secondary);text-align:center;
|
|
3572
|
+
+ '.tacit-progress{background:var(--dsw-alias-bg-layer-1);border:1px solid var(--dsw-alias-border-l1);border-radius:8px;padding:8px 12px;margin-bottom:12px;color:var(--dsw-alias-label-secondary);font-size:12px;line-height:1.5}.tacit-progress-title{font-size:13px;font-weight:600;color:var(--dsw-alias-label-primary);margin-right:auto}'
|
|
3573
|
+
+ '.tacit-empty{color:var(--dsw-alias-label-secondary);text-align:center;font-size:12px;line-height:1.6;max-width:46ch;margin-inline:auto;padding:18px 12px;border:1px dashed var(--dsw-alias-border-l1);border-radius:8px;background:color-mix(in srgb, var(--dsw-alias-bg-layer-2) 50%, transparent)}'
|
|
3481
3574
|
+ '.tacit-error{color:var(--dsw-alias-state-error-primary);background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l1);border-radius:8px;padding:8px 12px;margin-bottom:12px;overflow-wrap:anywhere;font-size:12px}'
|
|
3482
3575
|
+ '.tacit-btn{font:inherit;font-size:12px;color:var(--dsw-alias-label-primary);background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l1);border-radius:6px;cursor:pointer;padding:4px 10px}.tacit-btn:hover{border-color:var(--dsw-alias-label-primary)}.tacit-btn:disabled{opacity:.55;cursor:default}'
|
|
3483
3576
|
+ '.tacit-btn-primary{background:var(--dsw-alias-button-primary-fill);color:var(--dsw-alias-label-primary-foreground);border-color:transparent}.tacit-btn-primary:hover{border-color:transparent;filter:brightness(1.1)}'
|
|
3484
3577
|
+ '.tacit-btn-sm{padding:2px 8px;font-size:11px}'
|
|
3485
3578
|
+ '.tacit-btn-danger{color:var(--dsw-alias-state-error-primary);border-color:color-mix(in srgb, var(--dsw-alias-state-error-primary) 45%, transparent)}.tacit-btn-danger:hover{border-color:var(--dsw-alias-state-error-primary);background:color-mix(in srgb, var(--dsw-alias-state-error-primary) 12%, transparent)}'
|
|
3486
3579
|
+ '.tacit-row{background:var(--dsw-alias-bg-layer-1);border:1px solid var(--dsw-alias-border-l1);border-radius:10px;padding:10px 12px;margin-bottom:10px}'
|
|
3487
|
-
+ '.tacit-row-head{display:flex;flex-wrap:wrap;align-items:
|
|
3488
|
-
+ '.tacit-
|
|
3489
|
-
|
|
3580
|
+
+ '.tacit-row-head{display:flex;flex-wrap:wrap;align-items:center;gap:6px 10px}.tacit-row-heading{display:flex;flex-wrap:wrap;align-items:center;gap:4px 8px;font-weight:600;min-width:0}.tacit-row-turn{font-size:13px;font-variant-numeric:tabular-nums}.tacit-row-time{color:var(--dsw-alias-label-secondary);font-size:11px;font-weight:400}.tacit-row-actions{display:flex;align-items:center;gap:6px;margin-left:auto}'
|
|
3581
|
+
+ '.tacit-chip{background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l1);color:var(--dsw-alias-label-secondary);border-radius:4px;padding:1px 7px;font-size:11px}.tacit-chip-warn{color:var(--dsw-alias-state-warn-primary)}'
|
|
3582
|
+
// Turn facts read as one dot-separated line, not four bordered chips.
|
|
3583
|
+
+ '.tacit-row-meta{display:flex;flex-wrap:wrap;align-items:center;margin-top:8px;font-size:11px;line-height:1.5;color:var(--dsw-alias-label-secondary);font-variant-numeric:tabular-nums}.tacit-row-meta>span+span::before{content:"·";margin:0 7px;opacity:.6}.tacit-row-meta-warn{color:var(--dsw-alias-state-warn-primary)}'
|
|
3584
|
+
+ '.tacit-row-prompt{display:flex;align-items:flex-start;gap:8px;margin-top:8px}.tacit-row-prompt-text{font:inherit;font-size:12px;color:var(--dsw-alias-label-primary);background:none;border:0;cursor:pointer;text-align:left;padding:0;white-space:pre-wrap;word-break:break-word;flex:1;line-height:1.55}.tacit-row-prompt-static{cursor:auto}.tacit-row-more{margin-left:8px;font-size:11px;color:var(--dsw-alias-brand-primary);white-space:nowrap}'
|
|
3490
3585
|
+ '.tacit-report{border-top:1px dashed var(--dsw-alias-border-l1);margin-top:10px;padding-top:10px;display:flex;flex-direction:column;gap:6px}'
|
|
3491
3586
|
+ '.tacit-report-title{font-size:11px;font-weight:600;color:var(--dsw-alias-label-secondary)}'
|
|
3492
3587
|
+ '.tacit-report-note{color:var(--dsw-alias-label-secondary);font-size:12px}'
|
|
@@ -3502,7 +3597,11 @@ if (typeof window === 'undefined' || window.__ModuleLoader__ === undefined || ty
|
|
|
3502
3597
|
+ '.tacit-problem-what{font-size:12px;color:var(--dsw-alias-label-primary);line-height:1.5}.tacit-problem-why{font-size:11px;color:var(--dsw-alias-label-secondary);line-height:1.5}'
|
|
3503
3598
|
+ '.tacit-pre{margin:0;white-space:pre-wrap;word-break:break-word;font-family:inherit;font-size:12px;line-height:1.6;color:var(--dsw-alias-label-primary)}'
|
|
3504
3599
|
+ '.tacit-settings{background:var(--dsw-alias-bg-layer-1);border:1px solid var(--dsw-alias-border-l1);border-radius:10px;padding:10px 12px;margin-bottom:12px;display:flex;flex-direction:column;gap:8px}'
|
|
3505
|
-
+ '.tacit-settings-title{font-size:12px;font-weight:600}
|
|
3600
|
+
+ '.tacit-settings-title{font-size:12px;font-weight:600}'
|
|
3601
|
+
// One settings row everywhere: the label takes the slack and wraps, the
|
|
3602
|
+
// control stays right-aligned, and nothing needs a 150px minimum.
|
|
3603
|
+
+ '.tacit-field{display:flex;flex-wrap:wrap;align-items:center;gap:6px 12px}.tacit-field-label{flex:1 1 150px;min-width:0;font-size:12px;line-height:1.45;color:var(--dsw-alias-label-secondary)}.tacit-field-control{display:flex;flex-wrap:wrap;align-items:center;gap:6px;margin-left:auto}'
|
|
3604
|
+
+ '.tacit-inline,.tacit-settings-row{display:flex;flex-wrap:wrap;align-items:center;gap:8px}'
|
|
3506
3605
|
+ '.tacit-settings-notice{font-size:11px;color:var(--dsw-alias-state-success-primary)}'
|
|
3507
3606
|
// The idle live region has to stay mounted to announce, but as an empty
|
|
3508
3607
|
// flex item it still claims one of the panel's 10px gaps; -5px a side
|
|
@@ -3511,22 +3610,22 @@ if (typeof window === 'undefined' || window.__ModuleLoader__ === undefined || ty
|
|
|
3511
3610
|
+ '.tacit-select,.tacit-input{font:inherit;font-size:12px;color:var(--dsw-alias-label-primary);background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l1);border-radius:6px;padding:3px 8px}.tacit-input{width:90px}'
|
|
3512
3611
|
+ '.tacit-improve-btn{font:inherit;font-size:13px;font-weight:500;line-height:20px;color:var(--dsw-alias-label-secondary);background:transparent;border:0;border-radius:24px;cursor:pointer;height:28px;padding:0 8px;white-space:nowrap;display:inline-flex;align-items:center;gap:4px}.tacit-improve-btn:hover{color:var(--dsw-alias-label-primary);background:var(--dsw-alias-interactive-bg-hover)}'
|
|
3513
3612
|
+ '.tacit-check{width:14px;height:14px;accent-color:var(--dsw-alias-brand-primary);flex:none;margin:2px 4px 0 0}'
|
|
3514
|
-
+ '.tacit-toolbar{display:flex;align-items:center;gap:8px;margin-bottom:
|
|
3515
|
-
+ '.tacit-progress-head{display:flex;align-items:
|
|
3613
|
+
+ '.tacit-toolbar{display:flex;align-items:center;gap:8px;margin-bottom:6px;flex-wrap:wrap}.tacit-toolbar-note{font-size:11px;line-height:1.5;color:var(--dsw-alias-label-secondary);margin-bottom:10px}.tacit-btn-quiet{color:var(--dsw-alias-label-secondary);background:transparent;border-color:transparent}.tacit-btn-quiet:hover{color:var(--dsw-alias-label-primary);border-color:transparent;background:var(--dsw-alias-interactive-bg-hover)}.tacit-chip-muted{opacity:.7}.tacit-row-analyzed{border-left:3px solid var(--dsw-alias-brand-primary)}'
|
|
3614
|
+
+ '.tacit-progress-head{display:flex;flex-wrap:wrap;align-items:center;gap:6px 8px;margin-bottom:6px}'
|
|
3516
3615
|
+ '.tacit-progress-text{font-size:12px;color:var(--dsw-alias-label-secondary);line-height:1.5}'
|
|
3517
|
-
+ '.tacit-panel{display:flex;flex-direction:column;gap:10px}.tacit-panel-section{display:flex;flex-direction:column;gap:6px}.tacit-panel-hint{font-size:11px;color:var(--dsw-alias-label-secondary);line-height:1.5}'
|
|
3616
|
+
+ '.tacit-panel{display:flex;flex-direction:column;gap:10px}.tacit-panel-section{display:flex;flex-direction:column;gap:6px}.tacit-panel-hint{margin:0;font-size:11px;color:var(--dsw-alias-label-secondary);line-height:1.5}'
|
|
3518
3617
|
+ '.tacit-coached-list{display:flex;flex-direction:column;gap:6px}.tacit-coached-row{background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l1);border-radius:8px;padding:6px 10px;display:flex;flex-direction:column;gap:3px}'
|
|
3519
3618
|
+ '.tacit-coached-meta{display:flex;align-items:baseline;gap:8px}.tacit-coached-turn{font-weight:600;font-size:12px}.tacit-coached-time{color:var(--dsw-alias-label-secondary);font-size:11px}'
|
|
3520
3619
|
+ '.tacit-coached-excerpt{font-size:12px;color:var(--dsw-alias-label-primary);white-space:pre-wrap;word-break:break-word;line-height:1.5}.tacit-coached-improved{font-size:11px;color:var(--dsw-alias-label-secondary);line-height:1.5;white-space:pre-wrap;word-break:break-word}'
|
|
3521
3620
|
+ ''
|
|
3522
3621
|
+ '.tacit-modal-backdrop{z-index:200;background:#00000073;display:flex;justify-content:center;align-items:center;position:fixed;inset:0}'
|
|
3523
|
-
+ '.tacit-modal-card{box-sizing:border-box;background:var(--dsw-alias-bg-layer-1);border:1px solid var(--dsw-alias-border-l1);width:min(760px,100vw - 48px);max-height:min(84vh,800px);box-shadow:var(--dsw-shadow-lv3,0 12px 32px #0006);color:var(--dsw-alias-label-primary);border-radius:12px;padding:16px 18px 18px;font-size:13px;display:flex;flex-direction:column;gap:10px;overflow-y:auto}'
|
|
3622
|
+
+ '.tacit-modal-card{box-sizing:border-box;background:var(--dsw-alias-bg-layer-1);border:1px solid var(--dsw-alias-border-l1);width:min(760px,100vw - 48px);max-height:min(84vh,800px);box-shadow:var(--dsw-shadow-lv3,0 12px 32px #0006);color:var(--dsw-alias-label-primary);border-radius:12px;padding:16px 18px 18px;font-size:13px;display:flex;flex-direction:column;gap:10px;overflow-y:auto}.tacit-modal-card-sm{width:min(440px,100vw - 48px)}'
|
|
3524
3623
|
+ '.tacit-modal-head{display:flex;align-items:baseline;gap:8px}.tacit-modal-title{font-size:14px;font-weight:600;margin:0 auto 0 0}.tacit-modal-close{color:var(--dsw-alias-label-secondary);cursor:pointer;background:none;border:0;border-radius:6px;padding:2px 8px;font-family:inherit;font-size:18px;line-height:1}.tacit-modal-close:hover{color:var(--dsw-alias-label-primary);background:var(--dsw-alias-bg-layer-2)}'
|
|
3525
3624
|
+ '.tacit-modal-pending{color:var(--dsw-alias-label-secondary);padding:16px 0;text-align:center}'
|
|
3526
3625
|
+ '.tacit-modal-unchanged{color:var(--dsw-alias-label-primary);padding:16px 0;text-align:center}'
|
|
3527
|
-
+ '.tacit-modal-cols{display:grid;grid-template-columns:1fr 1fr;gap:10px}.tacit-modal-col{border:1px solid var(--dsw-alias-border-l1);border-radius:8px;background:var(--dsw-alias-bg-layer-2);padding:8px 10px;min-width:0;max-height:300px;overflow-y:auto}'
|
|
3626
|
+
+ '.tacit-modal-body{display:flex;flex-direction:column;gap:10px}.tacit-modal-cols{display:grid;grid-template-columns:1fr 1fr;gap:10px}.tacit-modal-col{border:1px solid var(--dsw-alias-border-l1);border-radius:8px;background:var(--dsw-alias-bg-layer-2);padding:8px 10px;min-width:0;max-height:300px;overflow-y:auto}'
|
|
3528
3627
|
+ '.tacit-modal-col-title{font-size:11px;font-weight:600;color:var(--dsw-alias-label-secondary);margin-bottom:6px}'
|
|
3529
|
-
+ '.tacit-modal-rationale-text{font-size:12px;color:var(--dsw-alias-label-primary);line-height:1.6}.tacit-modal-savings{color:var(--dsw-alias-state-success-primary);font-size:12px;font-weight:600}'
|
|
3628
|
+
+ '.tacit-modal-col-improved{border-color:color-mix(in srgb, var(--dsw-alias-brand-primary) 40%, transparent)}.tacit-modal-rationale{display:flex;flex-direction:column;gap:4px}.tacit-modal-rationale-text{font-size:12px;color:var(--dsw-alias-label-primary);line-height:1.6}.tacit-modal-savings{color:var(--dsw-alias-state-success-primary);font-size:12px;font-weight:600}'
|
|
3530
3629
|
+ '.tacit-modal-actions{display:flex;gap:8px;justify-content:flex-end}'
|
|
3531
3630
|
+ '.tacit-confirm-body{margin:0;font-size:12px;line-height:1.6;color:var(--dsw-alias-label-primary)}'
|
|
3532
3631
|
+ '.tacit-confirm-actions{display:flex;gap:8px;justify-content:flex-end;margin-top:4px}'
|
|
@@ -3537,15 +3636,16 @@ if (typeof window === 'undefined' || window.__ModuleLoader__ === undefined || ty
|
|
|
3537
3636
|
+ '.tacit-feedback-noted{color:var(--dsw-alias-state-success-primary);font-weight:600}'
|
|
3538
3637
|
+ '.tacit-trend{display:flex;flex-wrap:wrap;align-items:center;gap:6px;margin-top:6px}.tacit-chip-trigger,.tacit-coached-trigger{text-transform:uppercase;letter-spacing:.04em;font-size:10px}.tacit-coached-trigger{margin-left:auto}.tacit-row-enrichment{margin-top:8px;border-left:3px solid var(--dsw-alias-brand-primary);padding:4px 10px;background:var(--dsw-alias-bg-layer-2);border-radius:6px}'
|
|
3539
3638
|
+ '.tacit-chip-trial{color:var(--dsw-alias-brand-primary)}.tacit-chip-ok{color:var(--dsw-alias-state-success-primary)}.tacit-chip-scope{color:var(--dsw-alias-brand-primary)}.tacit-select{max-width:11rem}'
|
|
3540
|
-
+ '.tacit-directive
|
|
3639
|
+
+ '.tacit-directive-input{width:min(420px,100%);flex:1}.tacit-preview summary{cursor:pointer;font-size:11px;color:var(--dsw-alias-label-secondary)}.tacit-preview pre{margin-top:6px;background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l1);border-radius:6px;padding:8px 10px}'
|
|
3541
3640
|
+ '.tacit-rules-list{display:flex;flex-direction:column;gap:6px}.tacit-rule{background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l1);border-left:3px solid var(--dsw-alias-brand-primary);border-radius:6px;padding:6px 10px;font-size:12px;line-height:1.55;color:var(--dsw-alias-label-primary);white-space:pre-wrap;word-break:break-word}'
|
|
3542
3641
|
+ '.tacit-card{border:1px solid var(--dsw-alias-border-l1);border-radius:8px;background:var(--dsw-alias-bg-layer-1)}'
|
|
3543
|
-
+ '.tacit-card-head{width:100%;display:flex;align-items:center;gap:8px;text-align:left;padding:10px 12px;background:none;border:0;cursor:pointer;font:inherit;color:inherit}'
|
|
3642
|
+
+ '.tacit-card-head{width:100%;display:flex;align-items:center;gap:8px;text-align:left;padding:10px 12px;background:none;border:0;border-radius:7px;cursor:pointer;font:inherit;color:inherit}.tacit-card-head:hover{background:var(--dsw-alias-interactive-bg-hover)}'
|
|
3544
3643
|
+ '.tacit-card-head:focus-visible{outline:2px solid var(--dsw-alias-brand-primary)}'
|
|
3545
3644
|
+ '.tacit-card-title{font-size:13px;font-weight:600}.tacit-card-summary{font-size:11px;color:var(--dsw-alias-label-secondary);min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}'
|
|
3546
3645
|
+ '.tacit-card-count{background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l1);color:var(--dsw-alias-label-secondary);border-radius:4px;padding:1px 7px;font-size:11px;font-variant-numeric:tabular-nums}'
|
|
3547
|
-
|
|
3548
|
-
+ '.tacit-
|
|
3646
|
+
// One disclosure glyph everywhere: a › that rotates down when open.
|
|
3647
|
+
+ '.tacit-chevron{display:inline-block;font-size:12px;line-height:1;color:inherit;transition:transform .15s ease}.tacit-chevron-open{transform:rotate(90deg)}.tacit-card-chevron{margin-left:auto;color:var(--dsw-alias-label-secondary)}'
|
|
3648
|
+
+ '.tacit-card-body{display:flex;flex-direction:column;gap:10px;padding:10px 12px 12px;border-top:1px solid color-mix(in srgb, var(--dsw-alias-border-l1) 60%, transparent)}.tacit-card-body[hidden]{display:none}'
|
|
3549
3649
|
+ '.tacit-usage{display:flex;flex-direction:column;gap:10px}'
|
|
3550
3650
|
+ '.tacit-tiles{display:flex;flex-wrap:wrap;gap:8px}'
|
|
3551
3651
|
+ '.tacit-tile{flex:1 1 140px;display:flex;flex-direction:column;gap:2px;background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l1);border-radius:8px;padding:8px 10px;min-width:0}'
|
|
@@ -3580,7 +3680,39 @@ if (typeof window === 'undefined' || window.__ModuleLoader__ === undefined || ty
|
|
|
3580
3680
|
+ '.tacit-pricing-table>.tacit-pricing-row:first-child{border-top:0}.tacit-pricing-head{color:var(--dsw-alias-label-secondary);font-weight:600;background:var(--dsw-alias-bg-layer-2)}'
|
|
3581
3681
|
+ '.tacit-pricing-cell{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.tacit-pricing-model{font-weight:600}'
|
|
3582
3682
|
+ '.tacit-pricing-error{font-size:11px;color:var(--dsw-alias-state-warn-primary);line-height:1.5}'
|
|
3583
|
-
|
|
3683
|
+
// Directive cards: a status-coloured rail and pill badge, the text on
|
|
3684
|
+
// its own line, and a wrapping actions row, so nothing fights for width.
|
|
3685
|
+
+ '.tacit-dir-list{display:flex;flex-direction:column;gap:8px}'
|
|
3686
|
+
+ '.tacit-dir{--tacit-status:var(--dsw-alias-label-secondary);background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l1);border-left:3px solid var(--tacit-status);border-radius:8px;padding:8px 10px 8px 12px;display:flex;flex-direction:column;gap:6px;min-width:0}'
|
|
3687
|
+
+ '.tacit-dir-active{--tacit-status:var(--dsw-alias-state-success-primary)}.tacit-dir-trial{--tacit-status:var(--dsw-alias-brand-primary)}.tacit-dir-retired{--tacit-status:var(--dsw-alias-state-warn-primary)}'
|
|
3688
|
+
+ '.tacit-dir-head{display:flex;flex-wrap:wrap;align-items:center;gap:4px 6px}.tacit-dir-start{margin-left:auto}'
|
|
3689
|
+
+ '.tacit-badge{--tacit-badge:var(--tacit-status, var(--dsw-alias-label-secondary));display:inline-flex;align-items:center;gap:5px;border-radius:999px;padding:1px 8px 1px 6px;font-size:11px;font-weight:600;line-height:1.5;color:var(--tacit-badge);background:color-mix(in srgb, var(--tacit-badge) 14%, transparent)}'
|
|
3690
|
+
+ '.tacit-badge-active{--tacit-status:var(--dsw-alias-state-success-primary)}.tacit-badge-trial{--tacit-status:var(--dsw-alias-brand-primary)}.tacit-badge-retired{--tacit-status:var(--dsw-alias-state-warn-primary)}.tacit-badge-muted{--tacit-status:var(--dsw-alias-label-secondary)}'
|
|
3691
|
+
+ '.tacit-badge-dot{width:6px;height:6px;border-radius:50%;background:var(--tacit-badge);flex:none}'
|
|
3692
|
+
+ '.tacit-dir-text{font-size:13px;line-height:1.55;color:var(--dsw-alias-label-primary);white-space:pre-wrap;word-break:break-word}.tacit-dir-off .tacit-dir-text{opacity:.5;text-decoration:line-through}'
|
|
3693
|
+
+ '.tacit-dir-actions{display:flex;flex-wrap:wrap;align-items:center;gap:6px 10px;font-size:11px;color:var(--dsw-alias-label-secondary)}'
|
|
3694
|
+
+ '.tacit-dir-enabled{display:inline-flex;align-items:center;gap:5px;cursor:pointer}.tacit-dir-enabled .tacit-check{margin:0}.tacit-dir-remove{margin-left:auto}'
|
|
3695
|
+
+ '.tacit-select-sm{font-size:11px;padding:2px 6px;width:auto}'
|
|
3696
|
+
+ '.tacit-dir-receipt summary{cursor:pointer;font-size:11px;color:var(--dsw-alias-label-secondary)}.tacit-dir-receipt summary:hover{color:var(--dsw-alias-label-primary)}'
|
|
3697
|
+
+ '.tacit-dir-add{display:flex;flex-wrap:wrap;align-items:center;gap:6px}'
|
|
3698
|
+
+ '.tacit-options{display:flex;flex-direction:column;gap:6px;background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l1);border-radius:8px;padding:8px 10px}'
|
|
3699
|
+
+ '.tacit-option{display:flex;align-items:flex-start;gap:8px;font-size:12px;line-height:1.5;cursor:pointer}.tacit-option .tacit-check{margin-top:2px}'
|
|
3700
|
+
// Hairlines between rows keep the group one soft box, not a list of boxes.
|
|
3701
|
+
+ '.tacit-options>*+*{border-top:1px solid color-mix(in srgb, var(--dsw-alias-border-l1) 60%, transparent);padding-top:6px}.tacit-options .tacit-select,.tacit-options .tacit-input{background:var(--dsw-alias-bg-layer-1)}'
|
|
3702
|
+
// The receipt: tiles, a lifecycle timeline, trigger chips, then the
|
|
3703
|
+
// identity grid.
|
|
3704
|
+
+ '.tacit-receipt{margin-top:8px;padding-top:10px;border-top:1px dashed var(--dsw-alias-border-l1);display:flex;flex-direction:column;gap:10px}'
|
|
3705
|
+
+ '.tacit-receipt-tiles .tacit-tile{flex-basis:120px;background:var(--dsw-alias-bg-layer-1)}.tacit-receipt-tile-note{font-size:10px;color:var(--dsw-alias-label-secondary);line-height:1.4}.tacit-tile-muted{font-size:12px;font-weight:500;color:var(--dsw-alias-label-secondary)}'
|
|
3706
|
+
+ '.tacit-timeline{list-style:none;margin:0;padding:0;display:flex}'
|
|
3707
|
+
+ '.tacit-timeline-step{flex:1;position:relative;min-width:0;padding:14px 6px 0 0;font-size:11px}'
|
|
3708
|
+
+ '.tacit-timeline-step::before{content:"";position:absolute;left:0;top:0;width:9px;height:9px;border-radius:50%;box-sizing:border-box;background:var(--dsw-alias-brand-primary)}'
|
|
3709
|
+
+ '.tacit-timeline-step::after{content:"";position:absolute;left:12px;right:2px;top:4px;height:1px;background:var(--dsw-alias-border-l1)}.tacit-timeline-step:last-child::after{display:none}'
|
|
3710
|
+
+ '.tacit-timeline-never::before{background:var(--dsw-alias-bg-layer-2);border:1.5px solid var(--dsw-alias-border-l1)}.tacit-timeline-never .tacit-timeline-value{color:var(--dsw-alias-label-secondary);font-weight:400}'
|
|
3711
|
+
+ '.tacit-timeline-label{display:block;color:var(--dsw-alias-label-secondary)}.tacit-timeline-value{display:block;font-weight:600;font-variant-numeric:tabular-nums}'
|
|
3712
|
+
+ '.tacit-receipt-row{display:flex;flex-wrap:wrap;align-items:center;gap:4px 6px}.tacit-receipt-label{font-size:11px;color:var(--dsw-alias-label-secondary);margin-right:2px}'
|
|
3713
|
+
+ '.tacit-receipt-meta{margin:0;display:grid;grid-template-columns:max-content minmax(0,1fr);gap:3px 12px;font-size:11px}.tacit-receipt-meta dt{color:var(--dsw-alias-label-secondary)}.tacit-receipt-meta dd{margin:0;overflow-wrap:anywhere;font-variant-numeric:tabular-nums}'
|
|
3714
|
+
+ '.tacit-receipt-actions{display:flex;justify-content:flex-end}'
|
|
3715
|
+
+ '@media (max-width:640px){.tacit-field-label{flex-basis:100%}.tacit-field-control{margin-left:0}.tacit-modal-cols{grid-template-columns:1fr}.tacit-usage-row{display:flex;flex-direction:column}.tacit-usage-cell{white-space:normal}.tacit-pricing-row{display:flex;flex-direction:column}.tacit-pricing-cell{white-space:normal}.tacit-tile{flex-basis:45%}.tacit-breakdown-row{grid-template-columns:minmax(0,1fr) 4rem 5rem}}'
|
|
3584
3716
|
|
|
3585
3717
|
function injectCss() {
|
|
3586
3718
|
const tagId = 'dsh-tacit/styles.css'
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-tacit",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"description": "Tacit learns what you leave unsaid in your prompts — from messy turns and your own corrections, with zero clicks — and tells the agent how to compensate, on every turn, via a system-prompt section you can read and edit.",
|
|
5
5
|
"author": "hackernotfound",
|
|
6
6
|
"license": "MIT",
|