@openturtle/cli 0.3.5 → 0.3.7
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 +4 -4
- package/dist/commands/resources.js +31 -2
- package/dist/core/api-client.js +3 -0
- package/dist/index.js +42 -1
- package/dist/local-knowledge/index.js +7 -1
- package/package.json +1 -1
- package/skill/openturtle-cli/SKILL.md +2 -1
package/README.md
CHANGED
|
@@ -56,7 +56,7 @@ ot knowledge search "部署"
|
|
|
56
56
|
ot knowledge local search "部署"
|
|
57
57
|
ot meetings list --project <project-id>
|
|
58
58
|
ot work summary --project <project-id>
|
|
59
|
-
ot worklogs record --summary "完成联调" --type progress
|
|
59
|
+
ot worklogs record --summary "完成联调" --type progress --todo <todo-id>
|
|
60
60
|
ot report draft --today
|
|
61
61
|
```
|
|
62
62
|
|
|
@@ -79,7 +79,7 @@ ot todos progress <todo-id> --message "完成接口联调,等待验收"
|
|
|
79
79
|
### 记录一条工作日志
|
|
80
80
|
|
|
81
81
|
```bash
|
|
82
|
-
ot worklogs record --summary "完成 Qoder CLI 接入验证" --type progress
|
|
82
|
+
ot worklogs record --summary "完成 Qoder CLI 接入验证" --type progress --todo <todo-id>
|
|
83
83
|
```
|
|
84
84
|
|
|
85
85
|
### 聚合搜索知识
|
|
@@ -446,7 +446,7 @@ ot meetings updates ignore <meeting-id> <update-id> --dry-run
|
|
|
446
446
|
|
|
447
447
|
```bash
|
|
448
448
|
ot worklogs list --today
|
|
449
|
-
ot worklogs record --summary "完成 Qoder CLI 接入验证" --type progress
|
|
449
|
+
ot worklogs record --summary "完成 Qoder CLI 接入验证" --type progress --todo <todo-id>
|
|
450
450
|
ot worklogs record --summary "Codex CLI 登录需要用户确认" --type blocker
|
|
451
451
|
ot worklogs create --body-file worklog.json --dry-run
|
|
452
452
|
```
|
|
@@ -487,7 +487,7 @@ ot projects resolve "项目名"
|
|
|
487
487
|
ot context get --project <project-id>
|
|
488
488
|
ot meetings list --project <project-id>
|
|
489
489
|
ot todos progress <todo-id> --message "..."
|
|
490
|
-
ot worklogs record --summary "..." --type progress
|
|
490
|
+
ot worklogs record --summary "..." --type progress --todo <todo-id>
|
|
491
491
|
ot report draft --today
|
|
492
492
|
```
|
|
493
493
|
|
|
@@ -21,7 +21,7 @@ export function createResourceCommands(client = new ApiClient()) {
|
|
|
21
21
|
return client.patch(`/api/todos/${encodeURIComponent(todoId)}/status`, { status });
|
|
22
22
|
},
|
|
23
23
|
async updateTodoProgress(todoId, message) {
|
|
24
|
-
return client.
|
|
24
|
+
return client.put(`/api/todos/${encodeURIComponent(todoId)}/progress-description`, {
|
|
25
25
|
progress_description: message,
|
|
26
26
|
});
|
|
27
27
|
},
|
|
@@ -31,6 +31,16 @@ export function createResourceCommands(client = new ApiClient()) {
|
|
|
31
31
|
async showKnowledge(knowledgeId) {
|
|
32
32
|
return client.get(`/api/memory/objects/${encodeURIComponent(knowledgeId)}`);
|
|
33
33
|
},
|
|
34
|
+
async rememberKnowledge(options) {
|
|
35
|
+
return client.post('/api/memory/remember', {
|
|
36
|
+
what: options.what,
|
|
37
|
+
why: options.why ?? '',
|
|
38
|
+
how_to_apply: options.howToApply ?? '',
|
|
39
|
+
kind: options.kind ?? 'note',
|
|
40
|
+
scope: options.scope ?? 'org',
|
|
41
|
+
project_id: options.project,
|
|
42
|
+
});
|
|
43
|
+
},
|
|
34
44
|
async searchKnowledge(keyword, options = {}) {
|
|
35
45
|
return client.get('/api/memory/search', listQuery({
|
|
36
46
|
q: keyword,
|
|
@@ -49,14 +59,33 @@ export function createResourceCommands(client = new ApiClient()) {
|
|
|
49
59
|
async listWorklogs(options) {
|
|
50
60
|
return client.get('/api/work-logs', listQuery(options));
|
|
51
61
|
},
|
|
52
|
-
async recordWorklog(summary, type = 'note') {
|
|
62
|
+
async recordWorklog(summary, type = 'note', references = {}) {
|
|
53
63
|
return client.post('/api/work-logs', {
|
|
64
|
+
...(references.project ? { project_id: references.project } : {}),
|
|
65
|
+
...(references.goal ? { goal_id: references.goal } : {}),
|
|
66
|
+
...(references.todo ? { todo_id: references.todo } : {}),
|
|
54
67
|
summary,
|
|
55
68
|
event_type: type,
|
|
56
69
|
source: 'manual',
|
|
57
70
|
metadata: { source_client: 'ot-cli' },
|
|
58
71
|
});
|
|
59
72
|
},
|
|
73
|
+
async listEvolutionReports(options) {
|
|
74
|
+
return client.get('/api/memory/evolution/reports', listQuery(options));
|
|
75
|
+
},
|
|
76
|
+
async triggerEvolution() {
|
|
77
|
+
// 找到「组织记忆自进化」内置 job 并手动触发一次(异步执行,立即返回)。
|
|
78
|
+
const res = await client.get('/api/system-config/scheduled-jobs', {
|
|
79
|
+
page: 1,
|
|
80
|
+
page_size: 100,
|
|
81
|
+
});
|
|
82
|
+
const jobs = res?.items ?? res ?? [];
|
|
83
|
+
const job = jobs.find((j) => j.handler === 'memory_org_evolution');
|
|
84
|
+
if (!job)
|
|
85
|
+
throw new Error('未找到「组织记忆自进化」定时任务(handler=memory_org_evolution)');
|
|
86
|
+
await client.post(`/api/system-config/scheduled-jobs/${job.id}/trigger`, {});
|
|
87
|
+
return { triggered: true, job: { id: job.id, name: job.name, cron: job.cron } };
|
|
88
|
+
},
|
|
60
89
|
};
|
|
61
90
|
}
|
|
62
91
|
function knowledgeQuery(options) {
|
package/dist/core/api-client.js
CHANGED
package/dist/index.js
CHANGED
|
@@ -250,6 +250,24 @@ knowledge
|
|
|
250
250
|
.option('--json')
|
|
251
251
|
.action(action(async (filePath, options) => print(await resources.readKnowledgeSource(filePath), options.json)));
|
|
252
252
|
registerLocalKnowledgeCommands(knowledge, { print, fatal });
|
|
253
|
+
program
|
|
254
|
+
.command('remember')
|
|
255
|
+
.description('随手记一条团队记忆(坑/决策/真相),进草稿待 AI 审核')
|
|
256
|
+
.requiredOption('--what <fact>', '一句话原子事实,如「溯源接口在测试环境会 404」')
|
|
257
|
+
.option('--why <reason>', '为什么值得记(根因/决策理由)')
|
|
258
|
+
.option('--how-to-apply <action>', '下次怎么用(避坑动作/决策依据)')
|
|
259
|
+
.option('--kind <kind>', 'note|decision|fact', 'note')
|
|
260
|
+
.option('--scope <scope>', 'org|project', 'org')
|
|
261
|
+
.option('--project <id>', '可选项目归属')
|
|
262
|
+
.option('--json')
|
|
263
|
+
.action(action(async (options) => print(await resources.rememberKnowledge({
|
|
264
|
+
what: options.what,
|
|
265
|
+
why: options.why,
|
|
266
|
+
howToApply: options.howToApply,
|
|
267
|
+
kind: options.kind,
|
|
268
|
+
scope: options.scope,
|
|
269
|
+
project: options.project,
|
|
270
|
+
}), options.json)));
|
|
253
271
|
const worklogs = program.command('worklogs');
|
|
254
272
|
worklogs
|
|
255
273
|
.command('list')
|
|
@@ -261,6 +279,9 @@ worklogs
|
|
|
261
279
|
.command('record')
|
|
262
280
|
.option('--summary <text>')
|
|
263
281
|
.option('--type <type>', 'progress|blocker|decision|commit|note|meeting', 'note')
|
|
282
|
+
.option('--project <id>', 'optional project reference')
|
|
283
|
+
.option('--goal <id>', 'optional goal reference')
|
|
284
|
+
.option('--todo <id>', 'optional Todo reference')
|
|
264
285
|
.option('--dry-run')
|
|
265
286
|
.action(action(async (options) => {
|
|
266
287
|
requireOption(options.summary, '--summary');
|
|
@@ -271,6 +292,9 @@ worklogs
|
|
|
271
292
|
method: 'POST',
|
|
272
293
|
path: '/api/work-logs',
|
|
273
294
|
body: {
|
|
295
|
+
...(options.project ? { project_id: options.project } : {}),
|
|
296
|
+
...(options.goal ? { goal_id: options.goal } : {}),
|
|
297
|
+
...(options.todo ? { todo_id: options.todo } : {}),
|
|
274
298
|
summary: options.summary,
|
|
275
299
|
event_type: options.type,
|
|
276
300
|
source: 'manual',
|
|
@@ -280,9 +304,26 @@ worklogs
|
|
|
280
304
|
});
|
|
281
305
|
return;
|
|
282
306
|
}
|
|
283
|
-
print(await resources.recordWorklog(options.summary, options.type
|
|
307
|
+
print(await resources.recordWorklog(options.summary, options.type, {
|
|
308
|
+
project: options.project,
|
|
309
|
+
goal: options.goal,
|
|
310
|
+
todo: options.todo,
|
|
311
|
+
}));
|
|
284
312
|
}));
|
|
285
313
|
registerCollaborationCommands(program, { goals, todos, knowledge, worklogs }, { print, fatal });
|
|
314
|
+
const evolution = program.command('evolution').description('组织记忆自进化(演化报告与手动触发)');
|
|
315
|
+
evolution
|
|
316
|
+
.command('reports')
|
|
317
|
+
.description('列出组织记忆自进化报告(按运行时间倒序)')
|
|
318
|
+
.option('--page <number>', 'page number', Number)
|
|
319
|
+
.option('--page-size <number>', 'items per page', Number)
|
|
320
|
+
.option('--json')
|
|
321
|
+
.action(action(async (options) => print(await resources.listEvolutionReports(options), options.json)));
|
|
322
|
+
evolution
|
|
323
|
+
.command('run')
|
|
324
|
+
.description('手动触发一次组织记忆自进化(异步执行)')
|
|
325
|
+
.option('--json')
|
|
326
|
+
.action(action(async (options) => print(await resources.triggerEvolution(), options.json)));
|
|
286
327
|
program
|
|
287
328
|
.command('report [subcommand]')
|
|
288
329
|
.description('daily report commands')
|
|
@@ -113,7 +113,13 @@ async function indexAsset(asset, existing, statements) {
|
|
|
113
113
|
return;
|
|
114
114
|
}
|
|
115
115
|
const content = bytes.toString('utf8');
|
|
116
|
-
const chunks =
|
|
116
|
+
const chunks = [];
|
|
117
|
+
// 表单标题作为元数据行(line 0)单独索引,不拼进正文——这样标题可搜,且正文 chunk
|
|
118
|
+
// 保持源文件行号(1-based),citation 能指回原文真实行。
|
|
119
|
+
const title = asset.entry?.title?.trim();
|
|
120
|
+
if (title)
|
|
121
|
+
chunks.push({ content: title, lineStart: 0, lineEnd: 0 });
|
|
122
|
+
chunks.push(...textChunks(content));
|
|
117
123
|
chunks.forEach((chunk, index) => statements.insertChunk.run(asset.id, index, chunk.lineStart, chunk.lineEnd, chunk.content));
|
|
118
124
|
setIndexStatus(statements, asset, 'indexed');
|
|
119
125
|
}
|
package/package.json
CHANGED
|
@@ -26,7 +26,8 @@ ot --json doctor
|
|
|
26
26
|
2. 用 `ot roster list --project <id>` 解析成员;先匹配 canonical `display_name`,再参考 aliases 和项目角色,重名或无法唯一匹配时询问用户。
|
|
27
27
|
3. 用 `ot context get --project <id> --query <term>` 获取项目上下文;复杂问题拆成少量明确查询词。
|
|
28
28
|
4. 按对象读取:`ot work summary`、`ot goals list/show`、`ot todos list/show`、`ot knowledge list/show/search`、`ot knowledge local list/search/read`、`ot meetings list/show/transcript/minutes/participants`、`ot worklogs list`。
|
|
29
|
-
5.
|
|
29
|
+
5. 记录 Todo 执行进展时优先使用 `ot worklogs record --summary "..." --type progress --todo <todo-id>`,可同时传 `--project` / `--goal`,不要只把关联 ID 塞进 metadata。
|
|
30
|
+
6. 高层命令缺失时才使用只读逃生口 `ot request get /api/...`。
|
|
30
31
|
|
|
31
32
|
## 写入规则
|
|
32
33
|
|