@suifei/dsh-ai-team 0.3.26 → 0.3.27

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/CHANGELOG.md CHANGED
@@ -1,5 +1,12 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.3.27 — 2026-11-10
4
+
5
+ - 主对话「任务」模式拆成标题 + 验收标准;不再把 Human 原话直接当 resultDefinition;
6
+ - 开启 QA 时必须逐行填写 checklist,否则不能提交;
7
+ - 修复真实项目 #3/#4 的根因:重复创建、宽泛结果定义、QA 空清单;
8
+ - 重复 Task 的第二条会打开已有卡,不再静默新建。
9
+
3
10
  ## 0.3.26 — 2026-11-10
4
11
 
5
12
  - Task 创建增加重复保护:相同 title/resultDefinition/owner 的 active Task 会被拒绝并返回已有 Task;
package/client.js CHANGED
@@ -34,7 +34,12 @@ window.__ModuleLoader__.load({
34
34
  tabSituation: '态势',
35
35
  tabsAria: '项目视图',
36
36
  composer: '写一条消息…',
37
- taskPlaceholder: '一句话任务,可稍后补完判据',
37
+ taskPlaceholder: '任务标题:要做什么',
38
+ taskDefinitionPlaceholder: '验收标准(必填):怎样算完成、拿什么证据',
39
+ taskDefinitionAria: 'Task 验收标准',
40
+ qaChecklistPlaceholder: 'QA 清单,每行一条(开启 QA 时必填)',
41
+ qaChecklistAria: 'QA 验收清单',
42
+ taskDefinitionRequired: '请先写验收标准,再创建 Task。',
38
43
  discuss: '讨论',
39
44
  taskMode: '任务',
40
45
  send: '发送',
@@ -341,7 +346,12 @@ window.__ModuleLoader__.load({
341
346
  tabSituation: 'Situation',
342
347
  tabsAria: 'Project views',
343
348
  composer: 'Write a message…',
344
- taskPlaceholder: 'A one-line task; add the definition of done later',
349
+ taskPlaceholder: 'Task title: what to do',
350
+ taskDefinitionPlaceholder: 'Definition of done (required): how it is accepted, with what evidence',
351
+ taskDefinitionAria: 'Definition of done',
352
+ qaChecklistPlaceholder: 'QA checklist, one per line (required when QA is on)',
353
+ qaChecklistAria: 'QA checklist',
354
+ taskDefinitionRequired: 'Write the definition of done before creating a Task.',
345
355
  discuss: 'Discuss',
346
356
  taskMode: 'Task',
347
357
  send: 'Send',
@@ -978,6 +988,9 @@ window.__ModuleLoader__.load({
978
988
  .at-inboxactions { display: flex; align-items: center; gap: 6px; flex: 0 0 auto; }
979
989
  .at-qacheck { display: inline-flex; align-items: center; gap: 4px; color: var(--dsw-alias-label-tertiary); font-size: 11px; white-space: nowrap; }
980
990
  .at-qacheck input { accent-color: var(--dsw-alias-state-business-primary); }
991
+ .at-taskfields { display: flex; flex-direction: column; gap: 6px; padding: 0 10px 8px; }
992
+ .at-taskdef, .at-taskqa { width: 100%; box-sizing: border-box; resize: vertical; min-height: 42px; padding: 7px 8px; border: 1px solid var(--dsw-alias-border-l2); border-radius: var(--dsw-radius-sm); background: var(--dsw-alias-bg-layer-2); color: var(--dsw-alias-label-primary); font: inherit; font-size: 12px; line-height: 18px; }
993
+ .at-taskdef::placeholder, .at-taskqa::placeholder { color: var(--dsw-alias-label-caption); }
981
994
  .at-qabadge { display: inline-flex; align-items: center; margin-left: 5px; padding: 0 5px; border: 1px solid var(--dsw-alias-state-business-primary); border-radius: 999px; color: var(--dsw-alias-state-business-primary); font-size: 9px; line-height: 15px; vertical-align: 1px; }
982
995
  .at-talented { opacity: 0.82; }
983
996
  .at-btn-small { min-height: 24px; padding: 0 8px; font-size: 11px; }
@@ -1919,8 +1932,12 @@ window.__ModuleLoader__.load({
1919
1932
  h('button', { className: 'at-send', type: 'button', disabled: !reply.trim(), onClick: onReplySend }, t('send'))))) : null);
1920
1933
  }
1921
1934
 
1922
- function Composer({ t, mode, draft, disabled, qaRequired, onQaRequired, onMode, onDraft, onSend }) {
1923
- const send = () => { if (draft.trim() && !disabled) onSend(); };
1935
+ function Composer({ t, mode, draft, definition, qaChecklist, disabled, qaRequired, onQaRequired, onDefinition, onQaChecklist, onMode, onDraft, onSend }) {
1936
+ const send = () => {
1937
+ if (!draft.trim() || disabled) return;
1938
+ if (mode === 'task' && (!definition.trim() || (qaRequired && !qaChecklist.trim()))) return;
1939
+ onSend();
1940
+ };
1924
1941
  return h('div', { className: 'at-composer' },
1925
1942
  h('div', { className: 'at-composerinner' },
1926
1943
  h('div', { className: cx('at-box', 'at-composerbox', mode === 'task' && 'at-taskmode') },
@@ -1938,6 +1955,25 @@ window.__ModuleLoader__.load({
1938
1955
  }
1939
1956
  },
1940
1957
  }),
1958
+ mode === 'task' ? h('div', { className: 'at-taskfields' },
1959
+ h('textarea', {
1960
+ className: 'at-taskdef',
1961
+ rows: 2,
1962
+ value: definition,
1963
+ disabled,
1964
+ placeholder: t('taskDefinitionPlaceholder'),
1965
+ 'aria-label': t('taskDefinitionAria'),
1966
+ onChange: (event) => onDefinition(event.target.value),
1967
+ }),
1968
+ qaRequired ? h('textarea', {
1969
+ className: 'at-taskqa',
1970
+ rows: 2,
1971
+ value: qaChecklist,
1972
+ disabled,
1973
+ placeholder: t('qaChecklistPlaceholder'),
1974
+ 'aria-label': t('qaChecklistAria'),
1975
+ onChange: (event) => onQaChecklist(event.target.value),
1976
+ }) : null) : null,
1941
1977
  h('div', { className: 'at-barrow' },
1942
1978
  h('div', { className: 'at-mode', role: 'group', 'aria-label': t('modeAria') },
1943
1979
  h('button', { type: 'button', 'aria-pressed': mode === 'discuss', onClick: () => onMode('discuss') }, t('discuss')),
@@ -1946,7 +1982,7 @@ window.__ModuleLoader__.load({
1946
1982
  h('input', { type: 'checkbox', checked: qaRequired, onChange: (event) => onQaRequired(event.target.checked) }),
1947
1983
  h('span', null, t('qaRequired'))) : null,
1948
1984
  h('span', { className: 'at-hint' }, t('enterHint')),
1949
- h('button', { className: 'at-send', type: 'button', disabled: disabled || !draft.trim(), onClick: send }, mode === 'task' ? t('createTask') : t('send'))))));
1985
+ h('button', { className: 'at-send', type: 'button', disabled: disabled || !draft.trim() || (mode === 'task' && (!definition.trim() || (qaRequired && !qaChecklist.trim()))), onClick: send }, mode === 'task' ? t('createTask') : t('send'))))));
1950
1986
  }
1951
1987
 
1952
1988
  function QuadrantCard({ t, meta, quadrant, tasks, items, count, onItem, onViewAll }) {
@@ -2119,6 +2155,8 @@ window.__ModuleLoader__.load({
2119
2155
  const [threadOpen, setThreadOpen] = React.useState(false);
2120
2156
  const [mode, setMode] = React.useState('discuss');
2121
2157
  const [qaTask, setQaTask] = React.useState(false);
2158
+ const [taskDefinition, setTaskDefinition] = React.useState('');
2159
+ const [qaChecklistText, setQaChecklistText] = React.useState('');
2122
2160
  const [draft, setDraft] = React.useState('');
2123
2161
  const [note, setNote] = React.useState('');
2124
2162
  const [rightNote, setRightNote] = React.useState('');
@@ -2821,7 +2859,18 @@ window.__ModuleLoader__.load({
2821
2859
  if (!project?.workspacePath) { say(t('workspaceRequired')); return; }
2822
2860
  try {
2823
2861
  if (mode === 'task') {
2824
- await runCommand('task.create', { title: text, resultDefinition: text, qaRequired: qaTask });
2862
+ const definition = taskDefinition.trim();
2863
+ const checklist = qaChecklistText.split(/\r?\n/).map((item) => item.trim()).filter(Boolean);
2864
+ if (definition === '') { say(t('taskDefinitionRequired')); return; }
2865
+ if (qaTask && checklist.length === 0) { say(t('qaNeedsChecklist')); return; }
2866
+ await runCommand('task.create', {
2867
+ title: text,
2868
+ resultDefinition: definition,
2869
+ qaRequired: qaTask,
2870
+ ...(qaTask ? { qaChecklist: checklist } : {}),
2871
+ });
2872
+ setTaskDefinition('');
2873
+ setQaChecklistText('');
2825
2874
  } else {
2826
2875
  await runCommand('stream.post', { body: text });
2827
2876
  }
@@ -3171,7 +3220,11 @@ window.__ModuleLoader__.load({
3171
3220
  draft,
3172
3221
  disabled: !project || !project.workspacePath,
3173
3222
  qaRequired: qaTask,
3223
+ definition: taskDefinition,
3224
+ qaChecklist: qaChecklistText,
3174
3225
  onQaRequired: setQaTask,
3226
+ onDefinition: setTaskDefinition,
3227
+ onQaChecklist: setQaChecklistText,
3175
3228
  onMode: setMode,
3176
3229
  onDraft: setDraft,
3177
3230
  onSend: send,
package/index.js CHANGED
@@ -34,7 +34,7 @@ export const name = 'ai-team';
34
34
  /** The workbench only makes sense where the Web carrier exists. */
35
35
  export const inject = ['webServer', 'permissionPresets', 'sandboxPolicy'];
36
36
 
37
- const VERSION = '0.3.26';
37
+ const VERSION = '0.3.27';
38
38
  const PROJECT_ID = 'prj_main';
39
39
  const HUMAN_ID = 'mem_human';
40
40
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@suifei/dsh-ai-team",
3
- "version": "0.3.26",
3
+ "version": "0.3.27",
4
4
  "type": "module",
5
5
  "description": "文渊阁 (Wenyuan Pavilion) — AI Team mode for DeepSeek Harness: concurrent projects, owned tasks, threads, inbox and an append-only team ledger",
6
6
  "license": "MIT",