dsh-tacit 0.2.2 → 0.2.3
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/README.md +21 -0
- package/client/client.js +85 -19
- package/docs/README.md +3 -3
- package/docs/README.zh.md +4 -3
- package/lib/analyze.js +175 -19
- package/lib/index.js +13 -0
- package/lib/routes.js +1 -1
- package/lib/schema.js +17 -1
- package/lib/service.js +200 -50
- package/lib/store.js +1 -0
- package/package.json +11 -5
package/README.md
CHANGED
|
@@ -85,6 +85,27 @@ reports. Dollar figures are estimates at list price; a cost plugin such as
|
|
|
85
85
|
the honest list of limitations:
|
|
86
86
|
[Privacy, cost & limitations](https://github.com/hackernotfound/dsh-tacit/blob/main/docs/privacy-and-cost.md).
|
|
87
87
|
|
|
88
|
+
## Help shape Tacit
|
|
89
|
+
|
|
90
|
+
Tacit works and I use it every day — but so far it has learned from one
|
|
91
|
+
person's prompts. It gets better with more of them.
|
|
92
|
+
|
|
93
|
+
- **Try it and say what feels wrong.** A directive that misfires, a cost that
|
|
94
|
+
surprised you, a label that reads oddly:
|
|
95
|
+
[open an issue](https://github.com/hackernotfound/dsh-tacit/issues/new/choose).
|
|
96
|
+
Two minutes of your time beats a week of my guessing.
|
|
97
|
+
- **Pick up a task.** Issues tagged
|
|
98
|
+
[`good first issue`](https://github.com/hackernotfound/dsh-tacit/labels/good%20first%20issue)
|
|
99
|
+
are small and come with acceptance criteria;
|
|
100
|
+
[`help wanted`](https://github.com/hackernotfound/dsh-tacit/labels/help%20wanted)
|
|
101
|
+
ones are bigger and I will pair on the design.
|
|
102
|
+
- **Ask anything** in
|
|
103
|
+
[Discussions](https://github.com/hackernotfound/dsh-tacit/discussions).
|
|
104
|
+
|
|
105
|
+
PRs are welcome — the fork → branch → PR walkthrough is in
|
|
106
|
+
[CONTRIBUTING.md](https://github.com/hackernotfound/dsh-tacit/blob/main/CONTRIBUTING.md).
|
|
107
|
+
No API key is needed to run the tests.
|
|
108
|
+
|
|
88
109
|
## Documentation
|
|
89
110
|
|
|
90
111
|
| | |
|
package/client/client.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
// SPDX-License-Identifier: MIT
|
|
2
2
|
// Copyright (c) 2026 hackernotfound — https://github.com/hackernotfound/dsh-tacit
|
|
3
|
+
// GENERATED by scripts/build-client.mjs from client/src/ — edit the sources, not this file.
|
|
3
4
|
/**
|
|
4
5
|
* dsh-tacit — Client half (installed package bundle entry, zero-build).
|
|
5
6
|
*
|
|
@@ -57,6 +58,10 @@ if (typeof window === 'undefined' || window.__ModuleLoader__ === undefined || ty
|
|
|
57
58
|
'trigger.correction': '纠正',
|
|
58
59
|
'trigger.manual': '手动',
|
|
59
60
|
'trigger.bootstrap': '引导',
|
|
61
|
+
'trigger.good': '做对了',
|
|
62
|
+
'report.strengths': '这次做对了什么',
|
|
63
|
+
'report.lesson': '经验',
|
|
64
|
+
'settings.learnGood': '也从混乱之后的顺利提示词中学习',
|
|
60
65
|
'bootstrap.btn': '从我最近 20 轮中学习',
|
|
61
66
|
'bootstrap.running': '学习中… {done}/{total}',
|
|
62
67
|
'bootstrap.hint': '约 $0.02–0.05,一次性。已顺利完成的提示词会被跳过。',
|
|
@@ -74,6 +79,9 @@ if (typeof window === 'undefined' || window.__ModuleLoader__ === undefined || ty
|
|
|
74
79
|
'steer.active': '已生效',
|
|
75
80
|
'steer.retired': '已淘汰 · {reason}',
|
|
76
81
|
'steer.user': '你添加的',
|
|
82
|
+
'steer.workspace': '仅 {name}',
|
|
83
|
+
'steer.scope': '适用范围',
|
|
84
|
+
'steer.everywhere': '所有工作区',
|
|
77
85
|
'settings.auto': '自动分析混乱轮次',
|
|
78
86
|
'settings.budget': '每日自动分析上限',
|
|
79
87
|
settings: '设置',
|
|
@@ -164,6 +172,10 @@ if (typeof window === 'undefined' || window.__ModuleLoader__ === undefined || ty
|
|
|
164
172
|
'trigger.correction': 'correction',
|
|
165
173
|
'trigger.manual': 'manual',
|
|
166
174
|
'trigger.bootstrap': 'bootstrap',
|
|
175
|
+
'trigger.good': 'what worked',
|
|
176
|
+
'report.strengths': 'What this prompt got right',
|
|
177
|
+
'report.lesson': 'Lesson',
|
|
178
|
+
'settings.learnGood': 'Also learn from a clean prompt right after a messy turn',
|
|
167
179
|
'bootstrap.btn': 'Learn from my last 20 turns',
|
|
168
180
|
'bootstrap.running': 'Learning… {done}/{total}',
|
|
169
181
|
'bootstrap.hint': '≈ $0.02–0.05, one time. Skips prompts that already went fine on their own.',
|
|
@@ -181,6 +193,9 @@ if (typeof window === 'undefined' || window.__ModuleLoader__ === undefined || ty
|
|
|
181
193
|
'steer.active': 'active',
|
|
182
194
|
'steer.retired': 'retired · {reason}',
|
|
183
195
|
'steer.user': 'yours',
|
|
196
|
+
'steer.workspace': 'only {name}',
|
|
197
|
+
'steer.scope': 'Applies to',
|
|
198
|
+
'steer.everywhere': 'Everywhere',
|
|
184
199
|
'settings.auto': 'Auto-analyze messy turns',
|
|
185
200
|
'settings.budget': 'Daily cap on automatic analyses',
|
|
186
201
|
settings: 'Settings',
|
|
@@ -346,13 +361,14 @@ if (typeof window === 'undefined' || window.__ModuleLoader__ === undefined || ty
|
|
|
346
361
|
return version
|
|
347
362
|
}
|
|
348
363
|
|
|
349
|
-
// ── Root store (
|
|
364
|
+
// ── Root store (settings section + bootstrap + directives editor) ──────
|
|
350
365
|
|
|
351
366
|
const rootStore = {
|
|
352
367
|
config: null,
|
|
353
368
|
profile: null,
|
|
354
369
|
auto: null,
|
|
355
370
|
steering: null, // {enabled, text}
|
|
371
|
+
workspaces: [], // [{cwd, label}] from /state
|
|
356
372
|
trend: null, // measured early-vs-recent trend
|
|
357
373
|
bootstrap: null, // {running, done, total}
|
|
358
374
|
coached: [], // cross-session coached-prompt entries
|
|
@@ -388,6 +404,7 @@ if (typeof window === 'undefined' || window.__ModuleLoader__ === undefined || ty
|
|
|
388
404
|
rootStore.profile = state.profile !== null && typeof state.profile === 'object' ? state.profile : null
|
|
389
405
|
rootStore.auto = state.auto !== null && typeof state.auto === 'object' ? state.auto : null
|
|
390
406
|
rootStore.steering = state.steering !== null && typeof state.steering === 'object' ? state.steering : null
|
|
407
|
+
rootStore.workspaces = Array.isArray(state.workspaces) ? state.workspaces : []
|
|
391
408
|
rootStore.bootstrap = state.bootstrap !== null && typeof state.bootstrap === 'object' ? state.bootstrap : null
|
|
392
409
|
}
|
|
393
410
|
const coached = await api('/history', { limit: 50 })
|
|
@@ -415,6 +432,7 @@ if (typeof window === 'undefined' || window.__ModuleLoader__ === undefined || ty
|
|
|
415
432
|
rootStore.profile = state.profile !== null && typeof state.profile === 'object' ? state.profile : null
|
|
416
433
|
rootStore.auto = state.auto !== null && typeof state.auto === 'object' ? state.auto : null
|
|
417
434
|
rootStore.steering = state.steering !== null && typeof state.steering === 'object' ? state.steering : null
|
|
435
|
+
rootStore.workspaces = Array.isArray(state.workspaces) ? state.workspaces : []
|
|
418
436
|
rootStore.bootstrap = state.bootstrap !== null && typeof state.bootstrap === 'object' ? state.bootstrap : null
|
|
419
437
|
}
|
|
420
438
|
} catch {
|
|
@@ -944,14 +962,21 @@ if (typeof window === 'undefined' || window.__ModuleLoader__ === undefined || ty
|
|
|
944
962
|
}
|
|
945
963
|
return h('div', { className: 'tacit-report' },
|
|
946
964
|
h('div', { className: 'tacit-report-title' },
|
|
947
|
-
t('report.problems'),
|
|
965
|
+
report.trigger === 'good' ? t('report.strengths') : t('report.problems'),
|
|
948
966
|
' ',
|
|
949
|
-
h('span', { className: 'tacit-chip tacit-chip-trigger' }, t('trigger.' + report.trigger))),
|
|
950
|
-
report.
|
|
951
|
-
?
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
967
|
+
h('span', { className: 'tacit-chip tacit-chip-trigger' + (report.trigger === 'good' ? ' tacit-chip-ok' : '') }, t('trigger.' + report.trigger))),
|
|
968
|
+
report.trigger === 'good'
|
|
969
|
+
? (Array.isArray(report.strengths) && report.strengths.length > 0
|
|
970
|
+
? report.strengths.map((strength, index) => h('div', { key: index, className: 'tacit-problem' },
|
|
971
|
+
h('span', { className: 'tacit-chip tacit-chip-ok' }, String(strength.kind)),
|
|
972
|
+
' ',
|
|
973
|
+
h('span', { className: 'tacit-problem-what' }, String(strength.what))))
|
|
974
|
+
: h('div', { className: 'tacit-report-note' }, '—'))
|
|
975
|
+
: report.problems.length === 0
|
|
976
|
+
? h('div', { className: 'tacit-report-note' }, '—')
|
|
977
|
+
: report.problems.map((problem, index) => ProblemRow(kit, problem, index)),
|
|
978
|
+
report.trigger === 'good' ? null : h('div', { className: 'tacit-report-title' }, t('report.improved')),
|
|
979
|
+
report.trigger === 'good' ? null : improved.length > 0
|
|
955
980
|
? h('div', { className: 'tacit-report-improved' },
|
|
956
981
|
h('div', { className: 'tacit-report-actions' },
|
|
957
982
|
h('button', {
|
|
@@ -966,7 +991,7 @@ if (typeof window === 'undefined' || window.__ModuleLoader__ === undefined || ty
|
|
|
966
991
|
: h('div', { className: 'tacit-report-note' }, t('report.emptyImproved')),
|
|
967
992
|
typeof report.explanation === 'string' && report.explanation.length > 0
|
|
968
993
|
? h('div', null,
|
|
969
|
-
h('div', { className: 'tacit-report-title' }, t('report.explanation')),
|
|
994
|
+
h('div', { className: 'tacit-report-title' }, report.trigger === 'good' ? t('report.lesson') : t('report.explanation')),
|
|
970
995
|
h('div', { className: 'tacit-report-body' },
|
|
971
996
|
MarkdownText !== null
|
|
972
997
|
? h(MarkdownText, { text: report.explanation })
|
|
@@ -1063,6 +1088,7 @@ if (typeof window === 'undefined' || window.__ModuleLoader__ === undefined || ty
|
|
|
1063
1088
|
const [model, setModel] = useState(config !== null && typeof config.model === 'string' ? config.model : 'deepseek-v4-flash')
|
|
1064
1089
|
const [budgetText, setBudgetText] = useState(config !== null && typeof config.autoDailyBudget === 'number' ? String(config.autoDailyBudget) : '30')
|
|
1065
1090
|
const [auto, setAuto] = useState(config !== null && config.autoAnalyze !== false)
|
|
1091
|
+
const [learnGood, setLearnGood] = useState(config !== null && config.learnFromGood !== false)
|
|
1066
1092
|
const [live, setLive] = useState(config !== null && config.liveSuggestions !== false)
|
|
1067
1093
|
const [notice, setNotice] = useState(null)
|
|
1068
1094
|
|
|
@@ -1071,6 +1097,7 @@ if (typeof window === 'undefined' || window.__ModuleLoader__ === undefined || ty
|
|
|
1071
1097
|
if (typeof config.model === 'string') setModel(config.model)
|
|
1072
1098
|
if (typeof config.autoDailyBudget === 'number') setBudgetText(String(config.autoDailyBudget))
|
|
1073
1099
|
if (typeof config.autoAnalyze === 'boolean') setAuto(config.autoAnalyze)
|
|
1100
|
+
if (typeof config.learnFromGood === 'boolean') setLearnGood(config.learnFromGood)
|
|
1074
1101
|
if (typeof config.liveSuggestions === 'boolean') setLive(config.liveSuggestions)
|
|
1075
1102
|
}
|
|
1076
1103
|
}, [config])
|
|
@@ -1084,6 +1111,11 @@ if (typeof window === 'undefined' || window.__ModuleLoader__ === undefined || ty
|
|
|
1084
1111
|
setBudgetText(String(number))
|
|
1085
1112
|
updateConfig(store, { autoDailyBudget: number })
|
|
1086
1113
|
}
|
|
1114
|
+
const toggleLearnGood = () => {
|
|
1115
|
+
const next = !learnGood
|
|
1116
|
+
setLearnGood(next)
|
|
1117
|
+
updateConfig(store, { learnFromGood: next })
|
|
1118
|
+
}
|
|
1087
1119
|
const toggleAuto = () => {
|
|
1088
1120
|
const next = !auto
|
|
1089
1121
|
setAuto(next)
|
|
@@ -1116,6 +1148,9 @@ if (typeof window === 'undefined' || window.__ModuleLoader__ === undefined || ty
|
|
|
1116
1148
|
h('div', { className: 'tacit-settings-row' },
|
|
1117
1149
|
h('label', { className: 'tacit-settings-label' }, t('settings.auto')),
|
|
1118
1150
|
h('input', { type: 'checkbox', checked: auto, onChange: toggleAuto })),
|
|
1151
|
+
h('div', { className: 'tacit-settings-row' },
|
|
1152
|
+
h('label', { className: 'tacit-settings-label' }, t('settings.learnGood')),
|
|
1153
|
+
h('input', { type: 'checkbox', checked: learnGood, onChange: toggleLearnGood })),
|
|
1119
1154
|
h('div', { className: 'tacit-settings-row' },
|
|
1120
1155
|
h('label', { className: 'tacit-settings-label' }, t('settings.budget')),
|
|
1121
1156
|
h('input', {
|
|
@@ -1259,7 +1294,7 @@ if (typeof window === 'undefined' || window.__ModuleLoader__ === undefined || ty
|
|
|
1259
1294
|
}
|
|
1260
1295
|
}
|
|
1261
1296
|
|
|
1262
|
-
// ── Feedback strip (
|
|
1297
|
+
// ── Feedback strip (above the composer, Improve enabled only) ───────────
|
|
1263
1298
|
|
|
1264
1299
|
function FeedbackStrip(kit) {
|
|
1265
1300
|
const { t } = kit
|
|
@@ -1329,13 +1364,19 @@ if (typeof window === 'undefined' || window.__ModuleLoader__ === undefined || ty
|
|
|
1329
1364
|
}
|
|
1330
1365
|
}
|
|
1331
1366
|
|
|
1332
|
-
// ── Global panel (
|
|
1367
|
+
// ── Global panel (Settings → Tacit section) ────────────────────────────
|
|
1333
1368
|
|
|
1334
1369
|
function DirectivesEditor(kit) {
|
|
1335
1370
|
const { t } = kit
|
|
1336
1371
|
return function DirectivesEditorView(props) {
|
|
1337
1372
|
const { config, directives, steering } = props
|
|
1373
|
+
const workspaces = Array.isArray(props.workspaces) ? props.workspaces : []
|
|
1338
1374
|
const [draft, setDraft] = useState('')
|
|
1375
|
+
const [scope, setScope] = useState('')
|
|
1376
|
+
const labelOf = (cwd) => {
|
|
1377
|
+
const parts = String(cwd).split(/[\\/]+/).filter((part) => part.length > 0)
|
|
1378
|
+
return parts.length > 0 ? parts[parts.length - 1] : String(cwd)
|
|
1379
|
+
}
|
|
1339
1380
|
const [steerOn, setSteerOn] = useState(config !== null && config.steerAgent !== false)
|
|
1340
1381
|
const [enrichOn, setEnrichOn] = useState(config !== null && config.enrichPrompts === true)
|
|
1341
1382
|
useEffect(() => {
|
|
@@ -1356,7 +1397,7 @@ if (typeof window === 'undefined' || window.__ModuleLoader__ === undefined || ty
|
|
|
1356
1397
|
const text = draft.trim()
|
|
1357
1398
|
if (text.length === 0) return
|
|
1358
1399
|
setDraft('')
|
|
1359
|
-
editDirectives({ action: 'add', text: text.slice(0, 300) })
|
|
1400
|
+
editDirectives({ action: 'add', text: text.slice(0, 300), ...(scope.length > 0 ? { workspace: scope } : {}) })
|
|
1360
1401
|
}
|
|
1361
1402
|
return h('div', { className: 'tacit-panel-section', 'data-testid': 'tacit-steering' },
|
|
1362
1403
|
h('div', { className: 'tacit-report-title' }, t('steer.title')),
|
|
@@ -1380,6 +1421,9 @@ if (typeof window === 'undefined' || window.__ModuleLoader__ === undefined || ty
|
|
|
1380
1421
|
}),
|
|
1381
1422
|
h('span', { className: 'tacit-directive-text' }, String(entry.text)),
|
|
1382
1423
|
h('span', { className: 'tacit-chip' }, entry.source === 'user' ? t('steer.user') : t('steer.distilled')),
|
|
1424
|
+
typeof entry.workspace === 'string' && entry.workspace.length > 0
|
|
1425
|
+
? h('span', { className: 'tacit-chip tacit-chip-scope', title: entry.workspace }, t('steer.workspace', { name: labelOf(entry.workspace) }))
|
|
1426
|
+
: null,
|
|
1383
1427
|
entry.status === 'candidate'
|
|
1384
1428
|
? h('span', { className: 'tacit-chip tacit-chip-trial' }, t('steer.trial', {
|
|
1385
1429
|
n: String(entry.trial !== null && typeof entry.trial === 'object' && typeof entry.trial.turns === 'number' ? entry.trial.turns : 0),
|
|
@@ -1402,6 +1446,16 @@ if (typeof window === 'undefined' || window.__ModuleLoader__ === undefined || ty
|
|
|
1402
1446
|
if (event.key === 'Enter') onAdd()
|
|
1403
1447
|
},
|
|
1404
1448
|
}),
|
|
1449
|
+
workspaces.length > 0
|
|
1450
|
+
? h('select', {
|
|
1451
|
+
className: 'tacit-input tacit-select',
|
|
1452
|
+
'aria-label': t('steer.scope'),
|
|
1453
|
+
value: scope,
|
|
1454
|
+
onChange: (event) => setScope(event.target.value),
|
|
1455
|
+
},
|
|
1456
|
+
h('option', { value: '' }, t('steer.everywhere')),
|
|
1457
|
+
...workspaces.map((entry) => h('option', { key: entry.cwd, value: entry.cwd }, entry.label)))
|
|
1458
|
+
: null,
|
|
1405
1459
|
h('button', { type: 'button', className: 'tacit-btn tacit-btn-sm', disabled: draft.trim().length === 0, onClick: onAdd }, t('steer.add'))),
|
|
1406
1460
|
steering !== null && typeof steering === 'object' && typeof steering.text === 'string' && steering.text.length > 0
|
|
1407
1461
|
? h('details', { className: 'tacit-preview' },
|
|
@@ -1425,6 +1479,7 @@ if (typeof window === 'undefined' || window.__ModuleLoader__ === undefined || ty
|
|
|
1425
1479
|
const [model, setModel] = useState(config !== null && typeof config.model === 'string' ? config.model : 'deepseek-v4-flash')
|
|
1426
1480
|
const [budgetText, setBudgetText] = useState(config !== null && typeof config.autoDailyBudget === 'number' ? String(config.autoDailyBudget) : '30')
|
|
1427
1481
|
const [auto, setAuto] = useState(config !== null && config.autoAnalyze !== false)
|
|
1482
|
+
const [learnGood, setLearnGood] = useState(config !== null && config.learnFromGood !== false)
|
|
1428
1483
|
const [live, setLive] = useState(config !== null && config.liveSuggestions !== false)
|
|
1429
1484
|
|
|
1430
1485
|
useEffect(() => {
|
|
@@ -1432,6 +1487,7 @@ if (typeof window === 'undefined' || window.__ModuleLoader__ === undefined || ty
|
|
|
1432
1487
|
if (typeof config.model === 'string') setModel(config.model)
|
|
1433
1488
|
if (typeof config.autoDailyBudget === 'number') setBudgetText(String(config.autoDailyBudget))
|
|
1434
1489
|
if (typeof config.autoAnalyze === 'boolean') setAuto(config.autoAnalyze)
|
|
1490
|
+
if (typeof config.learnFromGood === 'boolean') setLearnGood(config.learnFromGood)
|
|
1435
1491
|
if (typeof config.liveSuggestions === 'boolean') setLive(config.liveSuggestions)
|
|
1436
1492
|
}
|
|
1437
1493
|
}, [config])
|
|
@@ -1445,6 +1501,11 @@ if (typeof window === 'undefined' || window.__ModuleLoader__ === undefined || ty
|
|
|
1445
1501
|
setBudgetText(String(number))
|
|
1446
1502
|
updateRootConfig({ autoDailyBudget: number })
|
|
1447
1503
|
}
|
|
1504
|
+
const toggleLearnGood = () => {
|
|
1505
|
+
const next = !learnGood
|
|
1506
|
+
setLearnGood(next)
|
|
1507
|
+
updateRootConfig({ learnFromGood: next })
|
|
1508
|
+
}
|
|
1448
1509
|
const toggleAuto = () => {
|
|
1449
1510
|
const next = !auto
|
|
1450
1511
|
setAuto(next)
|
|
@@ -1484,6 +1545,9 @@ if (typeof window === 'undefined' || window.__ModuleLoader__ === undefined || ty
|
|
|
1484
1545
|
h('div', { className: 'tacit-settings-row' },
|
|
1485
1546
|
h('label', { className: 'tacit-settings-label' }, t('settings.auto')),
|
|
1486
1547
|
h('input', { type: 'checkbox', checked: auto, onChange: toggleAuto })),
|
|
1548
|
+
h('div', { className: 'tacit-settings-row' },
|
|
1549
|
+
h('label', { className: 'tacit-settings-label' }, t('settings.learnGood')),
|
|
1550
|
+
h('input', { type: 'checkbox', checked: learnGood, onChange: toggleLearnGood })),
|
|
1487
1551
|
h('div', { className: 'tacit-settings-row' },
|
|
1488
1552
|
h('label', { className: 'tacit-settings-label' }, t('settings.budget')),
|
|
1489
1553
|
h('input', {
|
|
@@ -1502,7 +1566,8 @@ if (typeof window === 'undefined' || window.__ModuleLoader__ === undefined || ty
|
|
|
1502
1566
|
error !== null && typeof error === 'object'
|
|
1503
1567
|
? h('div', { className: 'tacit-error' }, t('err.' + String(error.code), { detail: String(error.detail || '') }))
|
|
1504
1568
|
: null,
|
|
1505
|
-
h(DirectivesEditorView, {
|
|
1569
|
+
h(DirectivesEditorView, {
|
|
1570
|
+
workspaces: rootStore.workspaces, config, directives, steering: rootStore.steering }),
|
|
1506
1571
|
h('div', { className: 'tacit-panel-section' },
|
|
1507
1572
|
h('div', { className: 'tacit-report-title' }, t('panel.styleRules')),
|
|
1508
1573
|
styleRules.length === 0
|
|
@@ -1594,13 +1659,13 @@ if (typeof window === 'undefined' || window.__ModuleLoader__ === undefined || ty
|
|
|
1594
1659
|
+ '.tacit-modal-col-title{font-size:11px;font-weight:600;color:var(--dsw-alias-label-secondary);margin-bottom:6px}'
|
|
1595
1660
|
+ '.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}'
|
|
1596
1661
|
+ '.tacit-modal-actions{display:flex;gap:8px;justify-content:flex-end}'
|
|
1597
|
-
+ '.tacit-feedback{display:flex;justify-content:center;align-items:center;margin:
|
|
1662
|
+
+ '.tacit-feedback{display:flex;justify-content:center;align-items:center;margin:0 2px 8px;font-size:12px;color:var(--dsw-alias-label-primary);background:var(--dsw-alias-bg-layer-1);border:1px solid var(--dsw-alias-border-l1);border-radius:8px;padding:6px 10px;gap:8px;transition:opacity .35s ease}.tacit-feedback-fading{opacity:0}'
|
|
1598
1663
|
+ '.tacit-feedback-row{display:flex;align-items:center;gap:8px;flex-wrap:wrap}.tacit-feedback-title{color:var(--dsw-alias-label-secondary)}'
|
|
1599
1664
|
+ '.tacit-feedback-vote{font:inherit;font-size:14px;line-height:1;cursor:pointer;background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l1);border-radius:999px;padding:3px 8px}.tacit-feedback-vote:hover{border-color:var(--dsw-alias-brand-primary)}.tacit-feedback-vote-active{border-color:var(--dsw-alias-state-warn-primary);background:color-mix(in srgb, var(--dsw-alias-state-warn-primary) 12%, transparent)}'
|
|
1600
1665
|
+ '.tacit-feedback-reason{display:flex;align-items:center;gap:6px;flex-wrap:wrap}.tacit-feedback-input{width:260px;max-width:60vw}'
|
|
1601
1666
|
+ '.tacit-feedback-noted{color:var(--dsw-alias-state-success-primary);font-weight:600}'
|
|
1602
1667
|
+ '.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}'
|
|
1603
|
-
+ '.tacit-chip-trial{color:var(--dsw-alias-brand-primary)}.tacit-chip-ok{color:var(--dsw-alias-state-success-primary)}'
|
|
1668
|
+
+ '.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}'
|
|
1604
1669
|
+ '.tacit-directive{display:flex;align-items:center;gap:8px}.tacit-directive-text{flex:1;min-width:0}.tacit-directive-off .tacit-directive-text{opacity:.5;text-decoration:line-through}.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}'
|
|
1605
1670
|
+ '.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}'
|
|
1606
1671
|
|
|
@@ -1650,11 +1715,12 @@ if (typeof window === 'undefined' || window.__ModuleLoader__ === undefined || ty
|
|
|
1650
1715
|
inject: (sessionId) => ({ tacitStore: storeFor(sessionId) }),
|
|
1651
1716
|
}, (props) => h(PreviewOverlayView, props)))
|
|
1652
1717
|
|
|
1653
|
-
// The post-apply 👍/👎 strip lives in the
|
|
1654
|
-
// (
|
|
1718
|
+
// The post-apply 👍/👎 strip lives in the full-width row ABOVE the composer
|
|
1719
|
+
// card (input.dock). Not composer.dock: the harness hides that one until a
|
|
1720
|
+
// conversation has content, which is exactly when a first draft is improved.
|
|
1655
1721
|
const FeedbackStripView = FeedbackStrip(kit)
|
|
1656
|
-
ctx.slots.inject('conversation.
|
|
1657
|
-
name: 'conversation.
|
|
1722
|
+
ctx.slots.inject('conversation.input.dock', () => ctx.slots.register({
|
|
1723
|
+
name: 'conversation.input.dock',
|
|
1658
1724
|
id: 'tacit-feedback',
|
|
1659
1725
|
order: 10,
|
|
1660
1726
|
locale: NS,
|
package/docs/README.md
CHANGED
|
@@ -9,13 +9,13 @@ Pick the question you have:
|
|
|
9
9
|
|
|
10
10
|
| I want to… | Read |
|
|
11
11
|
| --- | --- |
|
|
12
|
-
| Install it and see it working in five minutes | [Getting started](getting-started.md) |
|
|
12
|
+
| Install it and see it working in five minutes | [Getting started](getting-started.md) ([中文](getting-started.zh.md)) |
|
|
13
13
|
| Understand what it does, step by step, and what the words mean | [How it works](how-it-works.md) |
|
|
14
14
|
| Know what leaves my machine, what it costs, and what it can't do yet | [Privacy, cost & limitations](privacy-and-cost.md) |
|
|
15
15
|
| Change a setting | [Configuration](configuration.md) |
|
|
16
|
-
| Read or change the code | [Architecture](architecture.md) · [Contributing](../CONTRIBUTING.md) |
|
|
16
|
+
| Read or change the code | [Architecture](architecture.md) · [Contributing](../CONTRIBUTING.md) ([中文](CONTRIBUTING.zh.md)) |
|
|
17
17
|
| See what changed between versions | [Changelog](../CHANGELOG.md) |
|
|
18
18
|
|
|
19
19
|
Reading order for a newcomer: Getting started → How it works → Privacy & cost.
|
|
20
20
|
|
|
21
|
-
中文:[README.zh.md](README.zh.md)
|
|
21
|
+
中文:[README.zh.md](README.zh.md) · [快速开始](getting-started.zh.md) · [贡献指南](CONTRIBUTING.zh.md)(其余文档为英文)。
|
package/docs/README.zh.md
CHANGED
|
@@ -68,15 +68,16 @@ Tacit 从不接触你的 API Key(所有调用都经过 harness 自己的模型
|
|
|
68
68
|
完整的数据流与成本表、以及坦白的限制清单(英文):
|
|
69
69
|
[Privacy, cost & limitations](https://github.com/hackernotfound/dsh-tacit/blob/main/docs/privacy-and-cost.md)。
|
|
70
70
|
|
|
71
|
-
##
|
|
71
|
+
## 文档(除标注外均为英文)
|
|
72
72
|
|
|
73
73
|
| | |
|
|
74
74
|
| --- | --- |
|
|
75
|
-
| [
|
|
75
|
+
| [快速开始](https://github.com/hackernotfound/dsh-tacit/blob/main/docs/getting-started.zh.md)([English](https://github.com/hackernotfound/dsh-tacit/blob/main/docs/getting-started.md)) | 安装、确认已启用、快速起步、界面各处在哪、排障 |
|
|
76
76
|
| [How it works](https://github.com/hackernotfound/dsh-tacit/blob/main/docs/how-it-works.md) | 逐步流程,带图和术语表 |
|
|
77
77
|
| [Privacy, cost & limitations](https://github.com/hackernotfound/dsh-tacit/blob/main/docs/privacy-and-cost.md) | 什么留在本地、什么会发出去、每次调用的花费、目前做不到的事 |
|
|
78
78
|
| [Configuration](https://github.com/hackernotfound/dsh-tacit/blob/main/docs/configuration.md) | 所有设置项、默认值和取值范围 |
|
|
79
79
|
| [Architecture](https://github.com/hackernotfound/dsh-tacit/blob/main/docs/architecture.md) | 面向贡献者:模块、钩子、路由、存储 |
|
|
80
|
-
| [
|
|
80
|
+
| [贡献指南](https://github.com/hackernotfound/dsh-tacit/blob/main/docs/CONTRIBUTING.zh.md)([English](https://github.com/hackernotfound/dsh-tacit/blob/main/CONTRIBUTING.md)) | fork → 分支 → PR 的流程、测试、基本规则;欢迎提 issue 和 PR |
|
|
81
|
+
| [Changelog](https://github.com/hackernotfound/dsh-tacit/blob/main/CHANGELOG.md) | 各版本的变更 |
|
|
81
82
|
|
|
82
83
|
MIT © hackernotfound
|