@goodandready/dsh-goal 0.2.0 → 0.2.1
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/lib/client.js +56 -108
- package/lib/command-handler.js +11 -2
- package/lib/goal-engine.js +24 -3
- package/lib/index.js +2 -2
- package/package.json +1 -1
package/lib/client.js
CHANGED
|
@@ -18,16 +18,16 @@ window.__ModuleLoader__.load({
|
|
|
18
18
|
|
|
19
19
|
// --- 10 ИНЖЕНЕРНЫХ ШАБЛОНОВ БЫСТРОГО ЗАПУСКА ЦЕЛИ ---
|
|
20
20
|
const QUICK_LAUNCH_TEMPLATES = [
|
|
21
|
-
{ id: 'fix', icon: '🐛', label: { en: 'Fix Bug',
|
|
22
|
-
{ id: 'refactor', icon: '⚡', label: { en: 'Refactor (YAGNI)',
|
|
23
|
-
{ id: 'tests', icon: '📝', label: { en: 'Tests & Coverage',
|
|
24
|
-
{ id: 'review', icon: '🔍', label: { en: 'Code Review',
|
|
25
|
-
{ id: 'feature', icon: '🚀', label: { en: 'New Feature',
|
|
26
|
-
{ id: 'security', icon: '🛡️', label: { en: 'Security Audit',
|
|
27
|
-
{ id: 'docs', icon: '📚', label: { en: 'Docs & Contract',
|
|
28
|
-
{ id: 'upgrade', icon: '📦', label: { en: 'Upgrade Deps',
|
|
29
|
-
{ id: 'cleanup', icon: '🧹', label: { en: 'Dead Code',
|
|
30
|
-
{ id: 'perf', icon: '⚙️', label: { en: 'Performance',
|
|
21
|
+
{ id: 'fix', icon: '🐛', label: { en: 'Fix Bug', zh: '修复缺陷' }, prefix: { en: 'Investigate bug, pinpoint root cause, apply fix, and verify with tests: ', zh: '调查并定位缺陷根源,实施修复并通过测试验证:' } },
|
|
22
|
+
{ id: 'refactor', icon: '⚡', label: { en: 'Refactor (YAGNI)', zh: '重构精简' }, prefix: { en: 'Refactor module applying YAGNI principle, delete redundant abstractions, and verify: ', zh: '遵循 YAGNI 原则重构模块,删除冗余抽象并验证:' } },
|
|
23
|
+
{ id: 'tests', icon: '📝', label: { en: 'Tests & Coverage', zh: '补充测试' }, prefix: { en: 'Write comprehensive unit tests covering edge cases for: ', zh: '为以下模块编写覆盖边界情况的完整单元测试:' } },
|
|
24
|
+
{ id: 'review', icon: '🔍', label: { en: 'Code Review', zh: '代码审计' }, prefix: { en: 'Review codebase for subtle bugs, memory leaks, and over-engineering in: ', zh: '对代码库进行深入审查,排查潜在缺陷与过度设计:' } },
|
|
25
|
+
{ id: 'feature', icon: '🚀', label: { en: 'New Feature', zh: '新功能开发' }, prefix: { en: 'Implement new feature according to specification and add tests for: ', zh: '根据规格说明实现新功能并补充测试:' } },
|
|
26
|
+
{ id: 'security', icon: '🛡️', label: { en: 'Security Audit', zh: '安全加固' }, prefix: { en: 'Audit security boundaries, sanitize inputs, and prevent injection in: ', zh: '审计安全边界,增加输入过滤与防注入保护:' } },
|
|
27
|
+
{ id: 'docs', icon: '📚', label: { en: 'Docs & Contract', zh: '文档规范' }, prefix: { en: 'Update technical documentation, README, and DESIGN.md conforming to standard for: ', zh: '按标准更新技术文档、README 与 DESIGN.md:' } },
|
|
28
|
+
{ id: 'upgrade', icon: '📦', label: { en: 'Upgrade Deps', zh: '依赖升级' }, prefix: { en: 'Upgrade dependencies, resolve breaking API changes, and verify build for: ', zh: '安全升级依赖库,解决接口兼容性并确保构建通过:' } },
|
|
29
|
+
{ id: 'cleanup', icon: '🧹', label: { en: 'Dead Code', zh: '清理死代码' }, prefix: { en: 'Find and safely remove dead code, unused exports, and stale fixtures in: ', zh: '查找并安全移除死代码、未使用的导出与失效测试用例:' } },
|
|
30
|
+
{ id: 'perf', icon: '⚙️', label: { en: 'Performance', zh: '性能优化' }, prefix: { en: 'Profile performance bottlenecks, eliminate unnecessary blocking calls in: ', zh: '分析性能瓶颈,消除阻塞调用并优化响应速度:' } },
|
|
31
31
|
];
|
|
32
32
|
|
|
33
33
|
// --- SVG ИКОНКИ ---
|
|
@@ -871,7 +871,7 @@ window.__ModuleLoader__.load({
|
|
|
871
871
|
: '—';
|
|
872
872
|
const tokensTooltip = totalTokens > 0
|
|
873
873
|
? `Prompt: ${promptTokens.toLocaleString('en-US')} | Completion: ${compTokens.toLocaleString('en-US')} | Total: ${totalTokens.toLocaleString('en-US')}`
|
|
874
|
-
: '
|
|
874
|
+
: 'Tokens not recorded yet';
|
|
875
875
|
|
|
876
876
|
const handleCopyReport = () => {
|
|
877
877
|
const md = generateMarkdownReport(state);
|
|
@@ -932,7 +932,7 @@ window.__ModuleLoader__.load({
|
|
|
932
932
|
type: 'text',
|
|
933
933
|
className: 'dsh-goal-card-input',
|
|
934
934
|
style: { flex: 1, fontSize: 12 },
|
|
935
|
-
placeholder: t('nudgePlaceholder') || '💡
|
|
935
|
+
placeholder: t('nudgePlaceholder') || '💡 Clarify task or steer agent...',
|
|
936
936
|
value: nudgeText,
|
|
937
937
|
onChange: (e) => setNudgeText(e.target.value),
|
|
938
938
|
onKeyDown: (e) => {
|
|
@@ -959,7 +959,7 @@ window.__ModuleLoader__.load({
|
|
|
959
959
|
}
|
|
960
960
|
},
|
|
961
961
|
},
|
|
962
|
-
nudgeSent ? (t('nudgeSent') || '✅
|
|
962
|
+
nudgeSent ? (t('nudgeSent') || '✅ Steering sent!') : (t('sendNudge') || 'Steer'),
|
|
963
963
|
),
|
|
964
964
|
)
|
|
965
965
|
: null,
|
|
@@ -971,7 +971,7 @@ window.__ModuleLoader__.load({
|
|
|
971
971
|
'span',
|
|
972
972
|
{
|
|
973
973
|
className: 'dsh-goal-git-badge',
|
|
974
|
-
title: t('copyGitDiff') || '
|
|
974
|
+
title: t('copyGitDiff') || 'Click to copy git diff command',
|
|
975
975
|
onClick: () => {
|
|
976
976
|
if (typeof navigator !== 'undefined' && navigator.clipboard?.writeText) {
|
|
977
977
|
navigator.clipboard.writeText(`git diff ${state.gitStartCommit}`).then(() => {
|
|
@@ -981,7 +981,7 @@ window.__ModuleLoader__.load({
|
|
|
981
981
|
}
|
|
982
982
|
},
|
|
983
983
|
},
|
|
984
|
-
gitCopied ? '✅
|
|
984
|
+
gitCopied ? '✅ Diff copied!' : `📌 Git: ${state.gitStartCommit}`,
|
|
985
985
|
),
|
|
986
986
|
)
|
|
987
987
|
: null,
|
|
@@ -1062,9 +1062,9 @@ window.__ModuleLoader__.load({
|
|
|
1062
1062
|
{
|
|
1063
1063
|
className: `dsh-goal-btn dsh-goal-btn-copy${copied ? ' copied' : ''}`,
|
|
1064
1064
|
onClick: handleCopyReport,
|
|
1065
|
-
title: t('copyReport') || '
|
|
1065
|
+
title: t('copyReport') || 'Copy Report in Markdown',
|
|
1066
1066
|
},
|
|
1067
|
-
copied ? (t('reportCopied') || '✅
|
|
1067
|
+
copied ? (t('reportCopied') || '✅ Copied!') : (t('copyReport') || '📋 Copy Report in Markdown'),
|
|
1068
1068
|
),
|
|
1069
1069
|
React.createElement(
|
|
1070
1070
|
'button',
|
|
@@ -1079,9 +1079,9 @@ window.__ModuleLoader__.load({
|
|
|
1079
1079
|
});
|
|
1080
1080
|
}
|
|
1081
1081
|
},
|
|
1082
|
-
title: '
|
|
1082
|
+
title: 'Copy Report for GitHub / Gitea PR Comment',
|
|
1083
1083
|
},
|
|
1084
|
-
prCopied ? (t('prCommentCopied') || '✅ PR
|
|
1084
|
+
prCopied ? (t('prCommentCopied') || '✅ PR Report Copied!') : (t('copyPRComment') || '🐙 Copy for GitHub PR'),
|
|
1085
1085
|
),
|
|
1086
1086
|
)
|
|
1087
1087
|
: null,
|
|
@@ -1095,7 +1095,7 @@ window.__ModuleLoader__.load({
|
|
|
1095
1095
|
onClose();
|
|
1096
1096
|
},
|
|
1097
1097
|
},
|
|
1098
|
-
t('closeBanner') || '
|
|
1098
|
+
t('closeBanner') || 'Close goal banner',
|
|
1099
1099
|
)
|
|
1100
1100
|
: null,
|
|
1101
1101
|
React.createElement(
|
|
@@ -1104,7 +1104,7 @@ window.__ModuleLoader__.load({
|
|
|
1104
1104
|
className: 'dsh-goal-btn dsh-goal-btn-primary',
|
|
1105
1105
|
onClick: onClose,
|
|
1106
1106
|
},
|
|
1107
|
-
t('close') || '
|
|
1107
|
+
t('close') || 'Close',
|
|
1108
1108
|
),
|
|
1109
1109
|
),
|
|
1110
1110
|
),
|
|
@@ -1145,11 +1145,11 @@ window.__ModuleLoader__.load({
|
|
|
1145
1145
|
'div',
|
|
1146
1146
|
{ className: 'dsh-goal-modal-title' },
|
|
1147
1147
|
React.createElement(IconTarget, { size: 18 }),
|
|
1148
|
-
t('quickLaunchTitle') || '
|
|
1148
|
+
t('quickLaunchTitle') || 'Quick Launch Goal',
|
|
1149
1149
|
),
|
|
1150
1150
|
React.createElement(
|
|
1151
1151
|
'button',
|
|
1152
|
-
{ className: 'dsh-goal-btn icon-only close', onClick: onClose, title: t('close') || '
|
|
1152
|
+
{ className: 'dsh-goal-btn icon-only close', onClick: onClose, title: t('close') || 'Close' },
|
|
1153
1153
|
'✕',
|
|
1154
1154
|
),
|
|
1155
1155
|
),
|
|
@@ -1162,13 +1162,13 @@ window.__ModuleLoader__.load({
|
|
|
1162
1162
|
React.createElement(
|
|
1163
1163
|
'div',
|
|
1164
1164
|
{ style: { fontSize: 13, color: 'var(--dsw-alias-label-secondary)', marginBottom: 8 } },
|
|
1165
|
-
t('quickLaunchDesc') || '
|
|
1165
|
+
t('quickLaunchDesc') || 'Define the objective for the agent in autonomous mode:',
|
|
1166
1166
|
),
|
|
1167
1167
|
React.createElement(
|
|
1168
1168
|
'div',
|
|
1169
1169
|
{ className: 'dsh-goal-template-chips' },
|
|
1170
1170
|
QUICK_LAUNCH_TEMPLATES.map((tmpl) => {
|
|
1171
|
-
const lang = t('localeCode') || '
|
|
1171
|
+
const lang = t('localeCode') || 'en';
|
|
1172
1172
|
const label = tmpl.label[lang] || tmpl.label.en;
|
|
1173
1173
|
const prefix = tmpl.prefix[lang] || tmpl.prefix.en;
|
|
1174
1174
|
return React.createElement(
|
|
@@ -1192,7 +1192,7 @@ window.__ModuleLoader__.load({
|
|
|
1192
1192
|
type: 'text',
|
|
1193
1193
|
className: 'dsh-goal-card-input',
|
|
1194
1194
|
style: { width: '100%', boxSizing: 'border-box', fontSize: 13, padding: '8px 10px' },
|
|
1195
|
-
placeholder: t('quickLaunchPlaceholder') || '
|
|
1195
|
+
placeholder: t('quickLaunchPlaceholder') || 'e.g. Implement report export and cover with unit tests...',
|
|
1196
1196
|
value: title,
|
|
1197
1197
|
onChange: (e) => setTitle(e.target.value),
|
|
1198
1198
|
onKeyDown: (e) => {
|
|
@@ -1209,7 +1209,7 @@ window.__ModuleLoader__.load({
|
|
|
1209
1209
|
React.createElement(
|
|
1210
1210
|
'button',
|
|
1211
1211
|
{ type: 'button', className: 'dsh-goal-btn', onClick: onClose },
|
|
1212
|
-
t('close') || '
|
|
1212
|
+
t('close') || 'Cancel',
|
|
1213
1213
|
),
|
|
1214
1214
|
React.createElement(
|
|
1215
1215
|
'button',
|
|
@@ -1218,7 +1218,7 @@ window.__ModuleLoader__.load({
|
|
|
1218
1218
|
className: 'dsh-goal-btn dsh-goal-btn-primary',
|
|
1219
1219
|
disabled: !title.trim(),
|
|
1220
1220
|
},
|
|
1221
|
-
t('startGoal') || '
|
|
1221
|
+
t('startGoal') || 'Start Goal',
|
|
1222
1222
|
),
|
|
1223
1223
|
),
|
|
1224
1224
|
),
|
|
@@ -1327,7 +1327,7 @@ window.__ModuleLoader__.load({
|
|
|
1327
1327
|
try {
|
|
1328
1328
|
const isOk = nextState.state === 'COMPLETED';
|
|
1329
1329
|
new Notification(
|
|
1330
|
-
isOk ? '🎯
|
|
1330
|
+
isOk ? '🎯 Goal Completed' : '⚠️ Goal Failed',
|
|
1331
1331
|
{
|
|
1332
1332
|
body: `${nextState.title} (${nextState.formattedElapsed || ''})`,
|
|
1333
1333
|
icon: '/favicon.ico',
|
|
@@ -1509,11 +1509,11 @@ window.__ModuleLoader__.load({
|
|
|
1509
1509
|
'button',
|
|
1510
1510
|
{
|
|
1511
1511
|
className: 'dsh-goal-quicklaunch-btn',
|
|
1512
|
-
title: t('quickLaunch') || '
|
|
1512
|
+
title: t('quickLaunch') || 'Start Goal (Goal Mode)',
|
|
1513
1513
|
onClick: () => setIsQuickLaunchOpen(true),
|
|
1514
1514
|
},
|
|
1515
1515
|
React.createElement(IconTarget, { size: 14 }),
|
|
1516
|
-
React.createElement('span', null, t('quickLaunch') || '
|
|
1516
|
+
React.createElement('span', null, t('quickLaunch') || 'Start Goal'),
|
|
1517
1517
|
),
|
|
1518
1518
|
),
|
|
1519
1519
|
isQuickLaunchOpen
|
|
@@ -1840,8 +1840,8 @@ window.__ModuleLoader__.load({
|
|
|
1840
1840
|
React.createElement(
|
|
1841
1841
|
'div',
|
|
1842
1842
|
{ style: { flex: 1 } },
|
|
1843
|
-
React.createElement('div', { className: 'dsh-goal-card-title' }, t('pluginTitle') || '
|
|
1844
|
-
React.createElement('div', { className: 'dsh-goal-card-sub' }, t('pluginDesc') || '
|
|
1843
|
+
React.createElement('div', { className: 'dsh-goal-card-title' }, t('pluginTitle') || 'Goal Mode & Autonomous Loop'),
|
|
1844
|
+
React.createElement('div', { className: 'dsh-goal-card-sub' }, t('pluginDesc') || 'Goal banner above composer dock, milestone decomposition, and auto-drive'),
|
|
1845
1845
|
),
|
|
1846
1846
|
React.createElement(Chevron, { className: `dsh-goal-chev ${isOpen ? 'dsh-goal-chev-open' : ''}` }),
|
|
1847
1847
|
),
|
|
@@ -1850,9 +1850,9 @@ window.__ModuleLoader__.load({
|
|
|
1850
1850
|
'div',
|
|
1851
1851
|
{ className: 'dsh-goal-card-body' },
|
|
1852
1852
|
status === 'loading'
|
|
1853
|
-
? React.createElement('p', { className: 'dsh-goal-field-hint', style: { padding: '12px 0' } }, t('loading') || '
|
|
1853
|
+
? React.createElement('p', { className: 'dsh-goal-field-hint', style: { padding: '12px 0' } }, t('loading') || 'Loading settings…')
|
|
1854
1854
|
: status !== 'ready'
|
|
1855
|
-
? React.createElement('p', { className: 'dsh-goal-foot-note', style: { padding: '12px 0' } }, t('unavailable') || '
|
|
1855
|
+
? React.createElement('p', { className: 'dsh-goal-foot-note', style: { padding: '12px 0' } }, t('unavailable') || 'Settings unavailable')
|
|
1856
1856
|
: React.createElement(
|
|
1857
1857
|
React.Fragment,
|
|
1858
1858
|
null,
|
|
@@ -1862,12 +1862,12 @@ window.__ModuleLoader__.load({
|
|
|
1862
1862
|
React.createElement(
|
|
1863
1863
|
'div',
|
|
1864
1864
|
{ className: 'dsh-goal-field-label-row' },
|
|
1865
|
-
React.createElement('label', { htmlFor: 'dsh-goal-max-iter' }, t('maxIterLabel') || '
|
|
1865
|
+
React.createElement('label', { htmlFor: 'dsh-goal-max-iter' }, t('maxIterLabel') || 'Max iterations (Safety Limit):'),
|
|
1866
1866
|
React.createElement(
|
|
1867
1867
|
'div',
|
|
1868
1868
|
{ className: 'dsh-goal-field-meta' },
|
|
1869
1869
|
maxIterStatus.isOverridden
|
|
1870
|
-
? React.createElement('span', { className: 'dsh-goal-override-tag' }, t('overridden') || '
|
|
1870
|
+
? React.createElement('span', { className: 'dsh-goal-override-tag' }, t('overridden') || 'overridden')
|
|
1871
1871
|
: null,
|
|
1872
1872
|
maxIterStatus.isOverridden
|
|
1873
1873
|
? React.createElement(
|
|
@@ -1875,11 +1875,11 @@ window.__ModuleLoader__.load({
|
|
|
1875
1875
|
{
|
|
1876
1876
|
type: 'button',
|
|
1877
1877
|
className: 'dsh-goal-btn-inline-reset',
|
|
1878
|
-
title: t('resetField') || '
|
|
1878
|
+
title: t('resetField') || 'Reset to default',
|
|
1879
1879
|
onClick: () => resetFieldToDefault('maxIterations'),
|
|
1880
1880
|
},
|
|
1881
1881
|
React.createElement(IconRotateCcw, { size: 12 }),
|
|
1882
|
-
t('resetField') || '
|
|
1882
|
+
t('resetField') || 'Default',
|
|
1883
1883
|
)
|
|
1884
1884
|
: null,
|
|
1885
1885
|
),
|
|
@@ -1908,7 +1908,7 @@ window.__ModuleLoader__.load({
|
|
|
1908
1908
|
disabled,
|
|
1909
1909
|
onChange: (e) => edit('autoDrive', e.target.checked),
|
|
1910
1910
|
}),
|
|
1911
|
-
t('autoDriveLabel') || '
|
|
1911
|
+
t('autoDriveLabel') || 'Auto-drive: keep the loop running automatically',
|
|
1912
1912
|
),
|
|
1913
1913
|
autoDriveStatus.isOverridden
|
|
1914
1914
|
? React.createElement(
|
|
@@ -1916,7 +1916,7 @@ window.__ModuleLoader__.load({
|
|
|
1916
1916
|
{
|
|
1917
1917
|
type: 'button',
|
|
1918
1918
|
className: 'dsh-goal-btn-inline-reset',
|
|
1919
|
-
title: t('resetField') || '
|
|
1919
|
+
title: t('resetField') || 'Reset to default',
|
|
1920
1920
|
onClick: () => resetFieldToDefault('autoDrive'),
|
|
1921
1921
|
},
|
|
1922
1922
|
React.createElement(IconRotateCcw, { size: 12 }),
|
|
@@ -1935,7 +1935,7 @@ window.__ModuleLoader__.load({
|
|
|
1935
1935
|
disabled,
|
|
1936
1936
|
onChange: (e) => edit('enableSound', e.target.checked),
|
|
1937
1937
|
}),
|
|
1938
|
-
t('soundLabel') || '
|
|
1938
|
+
t('soundLabel') || 'Sound when a goal completes',
|
|
1939
1939
|
),
|
|
1940
1940
|
enableSoundStatus.isOverridden
|
|
1941
1941
|
? React.createElement(
|
|
@@ -1943,7 +1943,7 @@ window.__ModuleLoader__.load({
|
|
|
1943
1943
|
{
|
|
1944
1944
|
type: 'button',
|
|
1945
1945
|
className: 'dsh-goal-btn-inline-reset',
|
|
1946
|
-
title: t('resetField') || '
|
|
1946
|
+
title: t('resetField') || 'Reset to default',
|
|
1947
1947
|
onClick: () => resetFieldToDefault('enableSound'),
|
|
1948
1948
|
},
|
|
1949
1949
|
React.createElement(IconRotateCcw, { size: 12 }),
|
|
@@ -1962,7 +1962,7 @@ window.__ModuleLoader__.load({
|
|
|
1962
1962
|
disabled,
|
|
1963
1963
|
onChange: (e) => edit('showQuickLaunchButton', e.target.checked),
|
|
1964
1964
|
}),
|
|
1965
|
-
t('quickLaunchLabel') || '
|
|
1965
|
+
t('quickLaunchLabel') || 'Quick launch goal button above composer dock',
|
|
1966
1966
|
),
|
|
1967
1967
|
quickLaunchStatus.isOverridden
|
|
1968
1968
|
? React.createElement(
|
|
@@ -1970,7 +1970,7 @@ window.__ModuleLoader__.load({
|
|
|
1970
1970
|
{
|
|
1971
1971
|
type: 'button',
|
|
1972
1972
|
className: 'dsh-goal-btn-inline-reset',
|
|
1973
|
-
title: t('resetField') || '
|
|
1973
|
+
title: t('resetField') || 'Reset to default',
|
|
1974
1974
|
onClick: () => resetFieldToDefault('showQuickLaunchButton'),
|
|
1975
1975
|
},
|
|
1976
1976
|
React.createElement(IconRotateCcw, { size: 12 }),
|
|
@@ -1983,12 +1983,12 @@ window.__ModuleLoader__.load({
|
|
|
1983
1983
|
React.createElement(
|
|
1984
1984
|
'div',
|
|
1985
1985
|
{ className: 'dsh-goal-field-label-row' },
|
|
1986
|
-
React.createElement('label', { htmlFor: 'dsh-goal-tool-fail' }, t('toolFailLabel') || '
|
|
1986
|
+
React.createElement('label', { htmlFor: 'dsh-goal-tool-fail' }, t('toolFailLabel') || 'Tool-Failure Breaker Limit:'),
|
|
1987
1987
|
React.createElement(
|
|
1988
1988
|
'div',
|
|
1989
1989
|
{ className: 'dsh-goal-field-meta' },
|
|
1990
1990
|
toolFailStatus.isOverridden
|
|
1991
|
-
? React.createElement('span', { className: 'dsh-goal-override-tag' }, t('overridden') || '
|
|
1991
|
+
? React.createElement('span', { className: 'dsh-goal-override-tag' }, t('overridden') || 'overridden')
|
|
1992
1992
|
: null,
|
|
1993
1993
|
toolFailStatus.isOverridden
|
|
1994
1994
|
? React.createElement(
|
|
@@ -1996,11 +1996,11 @@ window.__ModuleLoader__.load({
|
|
|
1996
1996
|
{
|
|
1997
1997
|
type: 'button',
|
|
1998
1998
|
className: 'dsh-goal-btn-inline-reset',
|
|
1999
|
-
title: t('resetField') || '
|
|
1999
|
+
title: t('resetField') || 'Reset to default',
|
|
2000
2000
|
onClick: () => edit('consecutiveToolFailureLimit', snap?.base?.consecutiveToolFailureLimit ?? DEFAULT_SETTINGS.consecutiveToolFailureLimit),
|
|
2001
2001
|
},
|
|
2002
2002
|
React.createElement(IconRotateCcw, { size: 12 }),
|
|
2003
|
-
t('resetField') || '
|
|
2003
|
+
t('resetField') || 'Default',
|
|
2004
2004
|
)
|
|
2005
2005
|
: null,
|
|
2006
2006
|
),
|
|
@@ -2018,7 +2018,7 @@ window.__ModuleLoader__.load({
|
|
|
2018
2018
|
React.createElement(
|
|
2019
2019
|
'p',
|
|
2020
2020
|
{ className: 'dsh-goal-field-hint' },
|
|
2021
|
-
t('toolFailHint') || '
|
|
2021
|
+
t('toolFailHint') || 'Auto-pause goal if N consecutive turns hit tool execution errors (0 to disable)',
|
|
2022
2022
|
),
|
|
2023
2023
|
),
|
|
2024
2024
|
React.createElement(
|
|
@@ -2038,7 +2038,7 @@ window.__ModuleLoader__.load({
|
|
|
2038
2038
|
}
|
|
2039
2039
|
},
|
|
2040
2040
|
}),
|
|
2041
|
-
t('notifLabel') || '
|
|
2041
|
+
t('notifLabel') || 'Native browser desktop notifications on completion',
|
|
2042
2042
|
),
|
|
2043
2043
|
notifStatus.isOverridden
|
|
2044
2044
|
? React.createElement(
|
|
@@ -2046,7 +2046,7 @@ window.__ModuleLoader__.load({
|
|
|
2046
2046
|
{
|
|
2047
2047
|
type: 'button',
|
|
2048
2048
|
className: 'dsh-goal-btn-inline-reset',
|
|
2049
|
-
title: t('resetField') || '
|
|
2049
|
+
title: t('resetField') || 'Reset to default',
|
|
2050
2050
|
onClick: () => resetFieldToDefault('enableBrowserNotifications'),
|
|
2051
2051
|
},
|
|
2052
2052
|
React.createElement(IconRotateCcw, { size: 12 }),
|
|
@@ -2057,7 +2057,7 @@ window.__ModuleLoader__.load({
|
|
|
2057
2057
|
'div',
|
|
2058
2058
|
{ className: 'dsh-goal-foot' },
|
|
2059
2059
|
failed
|
|
2060
|
-
? React.createElement('span', { className: 'dsh-goal-foot-note' }, t('saveFailed') || '
|
|
2060
|
+
? React.createElement('span', { className: 'dsh-goal-foot-note' }, t('saveFailed') || 'Not saved — fix the values and try again')
|
|
2061
2061
|
: null,
|
|
2062
2062
|
React.createElement(
|
|
2063
2063
|
'button',
|
|
@@ -2069,12 +2069,12 @@ window.__ModuleLoader__.load({
|
|
|
2069
2069
|
setDraft(null);
|
|
2070
2070
|
},
|
|
2071
2071
|
},
|
|
2072
|
-
t('discard') || '
|
|
2072
|
+
t('discard') || 'Discard changes',
|
|
2073
2073
|
),
|
|
2074
2074
|
React.createElement(
|
|
2075
2075
|
'button',
|
|
2076
2076
|
{ className: 'dsh-goal-save', disabled: !dirty || disabled || invalid, onClick: save },
|
|
2077
|
-
saving ? t('saving') || '
|
|
2077
|
+
saving ? (t('saving') || 'Saving…') : (t('save') || 'Save'),
|
|
2078
2078
|
),
|
|
2079
2079
|
),
|
|
2080
2080
|
),
|
|
@@ -2189,59 +2189,7 @@ window.__ModuleLoader__.load({
|
|
|
2189
2189
|
toolFailHint: '连续 N 轮遭遇工具调用错误时自动暂停(0 表示禁用)',
|
|
2190
2190
|
notifLabel: '目标完成时发送浏览器桌面原生通知',
|
|
2191
2191
|
},
|
|
2192
|
-
|
|
2193
|
-
goalLabel: 'Текущая цель',
|
|
2194
|
-
goalCompleted: 'Цель выполнена',
|
|
2195
|
-
clearGoal: 'Очистить цель',
|
|
2196
|
-
closeBanner: 'Закрыть плашку цели',
|
|
2197
|
-
pause: 'Приостановить',
|
|
2198
|
-
paused: 'На паузе',
|
|
2199
|
-
resume: 'Возобновить',
|
|
2200
|
-
details: 'Развернуть детали цели',
|
|
2201
|
-
modalTitle: 'План и статус цели',
|
|
2202
|
-
modalTitleCompleted: 'Цель выполнена: план и результаты',
|
|
2203
|
-
time: 'Время работы',
|
|
2204
|
-
eta: 'Оценка (ETA)',
|
|
2205
|
-
tokens: 'Токены',
|
|
2206
|
-
iterations: 'Итерации',
|
|
2207
|
-
progress: 'Прогресс',
|
|
2208
|
-
done: 'Готово',
|
|
2209
|
-
milestones: 'План работ:',
|
|
2210
|
-
noMilestones: 'Агент формирует план работ...',
|
|
2211
|
-
close: 'Закрыть',
|
|
2212
|
-
pluginTitle: 'Цели и автономный режим (Goal Mode)',
|
|
2213
|
-
pluginDesc: 'Панель цели над полем ввода, декомпозиция вех и авто-драйв',
|
|
2214
|
-
maxIterLabel: 'Максимум итераций (Safety Limit):',
|
|
2215
|
-
autoDriveLabel: 'Авто-драйв: продолжать цикл автоматически',
|
|
2216
|
-
soundLabel: 'Звук по завершении цели',
|
|
2217
|
-
quickLaunchLabel: 'Кнопка быстрого запуска цели над полем ввода',
|
|
2218
|
-
quickLaunch: 'Запустить цель',
|
|
2219
|
-
quickLaunchTitle: 'Быстрый запуск цели',
|
|
2220
|
-
quickLaunchDesc: 'Сформулируйте задачу для агента в автономном режиме:',
|
|
2221
|
-
quickLaunchPlaceholder: 'Например: Реализовать экспорт отчетов и покрыть тестами...',
|
|
2222
|
-
startGoal: 'Запустить цель',
|
|
2223
|
-
copyReport: '📋 Скопировать отчёт в Markdown',
|
|
2224
|
-
reportCopied: '✅ Скопировано!',
|
|
2225
|
-
save: 'Сохранить',
|
|
2226
|
-
saving: 'Сохранение…',
|
|
2227
|
-
discard: 'Отменить правки',
|
|
2228
|
-
resetField: 'По умолчанию',
|
|
2229
|
-
overridden: 'изменено',
|
|
2230
|
-
saveFailed: 'Не сохранено — исправьте и повторите',
|
|
2231
|
-
loading: 'Загрузка настроек…',
|
|
2232
|
-
unavailable: 'Настройки недоступны',
|
|
2233
|
-
localeCode: 'ru',
|
|
2234
|
-
copyPRComment: '🐙 Копировать для GitHub PR',
|
|
2235
|
-
prCommentCopied: '✅ PR-отчёт скопирован!',
|
|
2236
|
-
nudgePlaceholder: '💡 Уточнить задачу или направить агента...',
|
|
2237
|
-
sendNudge: 'Направить',
|
|
2238
|
-
nudgeSent: '✅ Подсказка отправлена!',
|
|
2239
|
-
copyGitDiff: 'Кликните, чтобы скопировать команду git diff',
|
|
2240
|
-
toolFailLabel: 'Лимит ошибок инструментов (Tool-Failure Breaker):',
|
|
2241
|
-
toolFailHint: 'Приостанавливать цель при N ошибках инструментов подряд (0 — отключить)',
|
|
2242
|
-
notifLabel: 'Браузерные уведомления на рабочем столе при завершении',
|
|
2243
|
-
},
|
|
2244
|
-
};
|
|
2192
|
+
};
|
|
2245
2193
|
|
|
2246
2194
|
module.exports.inject = ['slots', 'locale', 'settingsScope'];
|
|
2247
2195
|
module.exports.apply = function apply(ctx) {
|
package/lib/command-handler.js
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { randomUUID } from 'node:crypto';
|
|
2
2
|
import { GoalState, detectLanguage } from './goal-engine.js';
|
|
3
3
|
|
|
4
|
-
export const USAGE_RU = 'Использование: /goal [<цель>|clear|pause|resume]';
|
|
5
4
|
export const USAGE_EN = 'Usage: /goal [<goal>|clear|pause|resume]';
|
|
6
|
-
export const
|
|
5
|
+
export const USAGE_ZH = '用法: /goal [<目标描述>|clear|pause|resume]';
|
|
6
|
+
export const USAGE_RU = 'Использование: /goal [<цель>|clear|pause|resume]';
|
|
7
|
+
export const USAGE = USAGE_EN;
|
|
7
8
|
|
|
8
9
|
/**
|
|
9
10
|
* Парсинг строки ввода для команды /goal
|
|
@@ -46,6 +47,14 @@ export function createGoalUserMessage(text) {
|
|
|
46
47
|
*/
|
|
47
48
|
export function formatGoalStartPrompt(goalText, explicitLang) {
|
|
48
49
|
const lang = explicitLang || detectLanguage(goalText);
|
|
50
|
+
if (lang === 'zh') {
|
|
51
|
+
return `🎯 目标模式已激活 (Goal Mode): "${goalText}"\n\n` +
|
|
52
|
+
`自主执行契约:\n` +
|
|
53
|
+
`1. 第一步必选动作:在开展任何工作或回复之前,你的第一个动作必须是调用 goal_set_milestones 工具,提交包含 3-7 个具体连续步骤的工作计划。用户将在界面中实时查看此计划。\n` +
|
|
54
|
+
`2. 第二步:计划确立后开始执行任务。在开始每个步骤前,通过 goal_update_progress(milestone_id, "in_progress") 标记其为进行中。\n` +
|
|
55
|
+
`3. 第三步:完成某一步骤后,通过 goal_update_progress(milestone_id, "completed", "阶段简要成果") 标记为已完成。\n` +
|
|
56
|
+
`4. 第四步:当所有里程碑全部完成后,调用 goal_finish(summary) 工具并附带详尽的最终成果总结。`;
|
|
57
|
+
}
|
|
49
58
|
if (lang === 'ru') {
|
|
50
59
|
return `🎯 Активирован режим цели (Goal Mode): "${goalText}"\n\n` +
|
|
51
60
|
`СТРОГИЙ КОНТРАКТ АВТОНОМНОГО РЕЖИМА:\n` +
|
package/lib/goal-engine.js
CHANGED
|
@@ -948,9 +948,30 @@ export class GoalEngine {
|
|
|
948
948
|
if (goal.pendingNudge) {
|
|
949
949
|
const userFeedback = goal.pendingNudge;
|
|
950
950
|
goal.pendingNudge = null;
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
951
|
+
if (lang === 'zh') {
|
|
952
|
+
nudgeText = `\n\n🚨 用户紧急补充说明 / 调整方向:\n"${userFeedback}"\n你必须根据此说明调整近期的具体执行步骤!\n`;
|
|
953
|
+
} else if (lang === 'ru') {
|
|
954
|
+
nudgeText = `\n\n🚨 СРОЧНОЕ УТОЧНЕНИЕ / НАПРАВЛЕНИЕ ОТ ПОЛЬЗОВАТЕЛЯ:\n"${userFeedback}"\nОбязательно скорректируй свои ближайшие действия с учётом этого замечания!\n`;
|
|
955
|
+
} else {
|
|
956
|
+
nudgeText = `\n\n🚨 URGENT USER CLARIFICATION / STEERING:\n"${userFeedback}"\nYou must adjust your immediate actions according to this guidance!\n`;
|
|
957
|
+
}
|
|
958
|
+
}
|
|
959
|
+
|
|
960
|
+
if (lang === 'zh') {
|
|
961
|
+
const milestonesText = hasMilestones
|
|
962
|
+
? snapshot.milestones.map((m, i) => ` ${i + 1}. [${m.status.toUpperCase()}] ${m.title}${m.notes ? ` (${m.notes})` : ''}`).join('\n')
|
|
963
|
+
: ' (工作计划尚未建立 — 请立即调用 goal_set_milestones 设定初始里程碑!)';
|
|
964
|
+
|
|
965
|
+
return nudgeText + `\n\n[DSH GOAL MODE ACTIVE]
|
|
966
|
+
目标: "${snapshot.title}"
|
|
967
|
+
运行时间: ${snapshot.formattedElapsed}${etaText} | 迭代轮次: ${snapshot.iterationsCount}/${snapshot.maxIterations}
|
|
968
|
+
工作计划:
|
|
969
|
+
${milestonesText}
|
|
970
|
+
|
|
971
|
+
Goal Mode 执行契约 (必须严格遵循):
|
|
972
|
+
1. ${hasMilestones ? '按部就班推进当前进行中的里程碑。' : '第一步核心指令: 立即调用 goal_set_milestones 制定 3-7 个具体里程碑。在完成此工具调用前严禁执行其他操作!'}
|
|
973
|
+
2. 推进里程碑时,必须通过 goal_update_progress 工具更新状态(开始前标为 in_progress,完成后标为 completed 并附简要说明)。
|
|
974
|
+
3. 当所有里程碑全部完成后,调用 goal_finish 工具提交详细成果总结。`;
|
|
954
975
|
}
|
|
955
976
|
|
|
956
977
|
if (lang === 'ru') {
|
package/lib/index.js
CHANGED
|
@@ -291,8 +291,8 @@ export function apply(ctx, config = {}) {
|
|
|
291
291
|
|
|
292
292
|
const unregister = cctx.commands.register({
|
|
293
293
|
name: 'goal',
|
|
294
|
-
description: '
|
|
295
|
-
input: { hint: '[
|
|
294
|
+
description: 'Manage Goal Mode: activate, milestones, pause, resume, and clear',
|
|
295
|
+
input: { hint: '[<objective>|clear|pause|resume]' },
|
|
296
296
|
handler: async (invocation) => {
|
|
297
297
|
const sid = sessionIdOf(invocation, 'default');
|
|
298
298
|
if (invocation?.agent) {
|
package/package.json
CHANGED