dsh-plugin-teamflow 0.1.8 → 0.1.9
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 +27 -1
- package/README.en.md +14 -3
- package/README.md +6 -3
- package/lib/client.js +922 -259
- package/lib/descriptors.mjs +9 -0
- package/lib/host.mjs +2724 -563
- package/lib/store.mjs +55 -6
- package/package.json +3 -3
package/lib/store.mjs
CHANGED
|
@@ -110,6 +110,7 @@ function serializeJournal(journal) {
|
|
|
110
110
|
workspacePath: journal.workspacePath || null,
|
|
111
111
|
ownerSession: journal.ownerSession || null,
|
|
112
112
|
product: journal.product || null,
|
|
113
|
+
locale: journal.locale || null,
|
|
113
114
|
sanity: journal.sanity || null,
|
|
114
115
|
blueprint: journal.blueprint || null,
|
|
115
116
|
reqId: journal.reqId || null,
|
|
@@ -118,6 +119,9 @@ function serializeJournal(journal) {
|
|
|
118
119
|
taskMap: journal.taskMap || {},
|
|
119
120
|
agentsStarted: journal.agentsStarted || 0,
|
|
120
121
|
humanIntervention: journal.humanIntervention === true,
|
|
122
|
+
/** E 方案(2026-09-15):本轮验收是「已知问题」只读模式(QA 打回超限后补跑)——report 据此给
|
|
123
|
+
* 「结论被强制为需人工裁定、不要据此合回」的显式提示(持久化:重启/resume 后仍可判)。 */
|
|
124
|
+
knownIssuesAcceptance: journal.knownIssuesAcceptance === true,
|
|
121
125
|
cancelled: journal.cancelled === true,
|
|
122
126
|
interrupted: journal.interrupted === true,
|
|
123
127
|
interruptedAt: journal.interruptedAt || null,
|
|
@@ -145,6 +149,27 @@ function serializeJournal(journal) {
|
|
|
145
149
|
t: l.t,
|
|
146
150
|
level: l.level,
|
|
147
151
|
message: clip(l.message, 500)
|
|
152
|
+
})),
|
|
153
|
+
qaRounds: (journal.qaRounds || []).slice(-12).map((r) => ({
|
|
154
|
+
round: r.round,
|
|
155
|
+
seq: r.seq,
|
|
156
|
+
blocking: r.blocking,
|
|
157
|
+
p3: r.p3,
|
|
158
|
+
defects: Array.isArray(r.defects) ? r.defects.slice(0, 20).map((d) => ({
|
|
159
|
+
id: clip(d.id, 40),
|
|
160
|
+
sev: d.sev,
|
|
161
|
+
module: clip(d.module, 60),
|
|
162
|
+
fp: clip(d.fp, 200)
|
|
163
|
+
})) : [],
|
|
164
|
+
withCheck: r.withCheck,
|
|
165
|
+
withCriterion: r.withCriterion,
|
|
166
|
+
qaCalls: r.qaCalls,
|
|
167
|
+
fixCalls: r.fixCalls,
|
|
168
|
+
gate: r.gate,
|
|
169
|
+
newFps: r.newFps,
|
|
170
|
+
repeats: r.repeats,
|
|
171
|
+
resolved: r.resolved,
|
|
172
|
+
outcome: r.outcome
|
|
148
173
|
}))
|
|
149
174
|
};
|
|
150
175
|
}
|
|
@@ -161,17 +186,41 @@ function writeText(file, text) {
|
|
|
161
186
|
return false;
|
|
162
187
|
}
|
|
163
188
|
}
|
|
164
|
-
/**
|
|
165
|
-
|
|
189
|
+
/** 工作区内暂存目录段(与 host/constants.TF_LOG_DIR 同址;store 是独立 entry、刻意不引 host 代码,一致性由 test/runlogs.test.js 守门)。 */
|
|
190
|
+
const STAGING_SEGMENTS = ["logs", "teamflow"];
|
|
191
|
+
/** 归档用的工作区槽位:优先 journal.workspace,缺失/兜底时按 workspacePath 派生(与 backlog 同键)。 */
|
|
192
|
+
function logWorkspaceKey(journal) {
|
|
193
|
+
const w = journal && typeof journal.workspace === "string" ? journal.workspace.trim() : "";
|
|
194
|
+
if (w && w !== "default") return w;
|
|
195
|
+
const p = journal ? journal.workspacePath : null;
|
|
196
|
+
return p ? slugPath(p) : null;
|
|
197
|
+
}
|
|
198
|
+
/** 归档根(工作区级):`$DSH_HOME/teamflow/<workspace>/logs/`(每个 run 一个子目录)。 */
|
|
199
|
+
function logsArchiveRoot(journal) {
|
|
200
|
+
const key = logWorkspaceKey(journal);
|
|
201
|
+
return key ? join(teamflowRoot(), key, "logs") : null;
|
|
202
|
+
}
|
|
203
|
+
/** 归档落点(run 级目录):`$DSH_HOME/teamflow/<workspace>/logs/<runId>/`(与 journal/backlog 同槽位)。 */
|
|
204
|
+
function runLogArchiveDir(journal) {
|
|
205
|
+
const root = logsArchiveRoot(journal);
|
|
206
|
+
return root ? join(root, journal.id) : null;
|
|
207
|
+
}
|
|
208
|
+
/** 工作区内暂存落点(子代理写、run 结束归档后删除):`<workspacePath>/logs/teamflow/<runId>/`。 */
|
|
209
|
+
function runLogStagingDir(journal) {
|
|
166
210
|
if (!journal.workspacePath) return null;
|
|
167
|
-
return join(journal.workspacePath,
|
|
211
|
+
return join(journal.workspacePath, ...STAGING_SEGMENTS, journal.id);
|
|
212
|
+
}
|
|
213
|
+
/** host 事件日志落点:`<归档 run 目录>/run.log`(run 期间即写终态位置,无需搬运)。 */
|
|
214
|
+
function runLogFile(journal) {
|
|
215
|
+
const dir = runLogArchiveDir(journal);
|
|
216
|
+
return dir ? join(dir, "run.log") : null;
|
|
168
217
|
}
|
|
169
|
-
/** 把运行事件日志聚合写到
|
|
218
|
+
/** 把运行事件日志聚合写到 `$DSH_HOME/teamflow/<workspace>/logs/<runId>/run.log`(logs 离开用户项目)。 */
|
|
170
219
|
function persistRunLog(journal) {
|
|
171
220
|
const file = runLogFile(journal);
|
|
172
221
|
if (!file) return false;
|
|
173
222
|
const lines = [
|
|
174
|
-
`# TeamFlow 运行日志(${journal.name})`,
|
|
223
|
+
journal.locale === "en" ? `# TeamFlow run log (${journal.name})` : `# TeamFlow 运行日志(${journal.name})`,
|
|
175
224
|
`runId=${journal.id}`,
|
|
176
225
|
`workspace=${journal.workspacePath || ""}`,
|
|
177
226
|
`product=${journal.product || ""}`,
|
|
@@ -255,4 +304,4 @@ function loadJournals() {
|
|
|
255
304
|
return out;
|
|
256
305
|
}
|
|
257
306
|
//#endregion
|
|
258
|
-
export { STAGE_OUTPUT_CLIP, dshHome, fileFor, journalFile, loadJournals, persistJournal, persistRunLog, productDir, readJson, readJsonAny, runLogFile, runsDir, serializeJournal, slugPath, teamflowRoot, workspaceDir, writeJson, writeText };
|
|
307
|
+
export { STAGE_OUTPUT_CLIP, dshHome, fileFor, journalFile, loadJournals, logsArchiveRoot, persistJournal, persistRunLog, productDir, readJson, readJsonAny, runLogArchiveDir, runLogFile, runLogStagingDir, runsDir, serializeJournal, slugPath, teamflowRoot, workspaceDir, writeJson, writeText };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-plugin-teamflow",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.9",
|
|
4
4
|
"description": "TeamFlow 团队研发流水线(TypeScript):需求→PRD→设计→架构→技术方案→并行开发→QA→验收;backlog 持久化 + 断点续跑 + 完成汇报 + 防假交付;Web 团队工作台(conversation.view tab + 拖拽看板)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./lib/host.mjs",
|
|
@@ -41,8 +41,8 @@
|
|
|
41
41
|
"watch": "tsdown --watch",
|
|
42
42
|
"deploy": "node deploy.mjs",
|
|
43
43
|
"typecheck": "tsc --noEmit",
|
|
44
|
-
"test": "node test/smoke.js && node test/verdict.test.js && node test/stages.test.js && node test/journal.test.js && node test/diagnostic.test.js && node test/evidence.test.js && node test/metering.test.js && node test/gitignore.test.js && node test/product-scope.test.js && node test/prompt-contract.test.js && node test/conformance.test.js",
|
|
45
|
-
"prepublishOnly": "npx tsdown && npx tsdown -c tsdown.host.config.ts && node test/smoke.js && node test/verdict.test.js && node test/stages.test.js && node test/journal.test.js && node test/diagnostic.test.js && node test/evidence.test.js && node test/metering.test.js && node test/gitignore.test.js && node test/product-scope.test.js && node test/prompt-contract.test.js && node test/conformance.test.js"
|
|
44
|
+
"test": "node test/smoke.js && node test/locale.test.js && node test/verdict.test.js && node test/stages.test.js && node test/journal.test.js && node test/runlogs.test.js && node test/diagnostic.test.js && node test/evidence.test.js && node test/metering.test.js && node test/gitignore.test.js && node test/commit-path.test.js && node test/product-scope.test.js && node test/prompt-contract.test.js && node test/conformance.test.js",
|
|
45
|
+
"prepublishOnly": "npx tsdown && npx tsdown -c tsdown.host.config.ts && node test/smoke.js && node test/locale.test.js && node test/verdict.test.js && node test/stages.test.js && node test/journal.test.js && node test/runlogs.test.js && node test/diagnostic.test.js && node test/evidence.test.js && node test/metering.test.js && node test/gitignore.test.js && node test/commit-path.test.js && node test/product-scope.test.js && node test/prompt-contract.test.js && node test/conformance.test.js"
|
|
46
46
|
},
|
|
47
47
|
"files": [
|
|
48
48
|
"lib",
|