logwork-cli 1.2.0 → 1.3.0
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 +37 -25
- package/RELEASE.md +3 -2
- package/bin/logwork.mjs +2 -2
- package/commands/commits.mjs +78 -14
- package/commands/mcp.mjs +266 -0
- package/commands/setup.mjs +161 -40
- package/docs/advanced.md +7 -6
- package/docs/mcp-setup.md +80 -28
- package/docs/operations-guide.md +18 -3
- package/docs/recipes.md +18 -5
- package/docs/security.md +20 -1
- package/examples/mcp/antigravity.mcp_config.json +2 -2
- package/examples/mcp/codex.config.toml +2 -2
- package/examples/mcp/copilot.mcp.json +2 -2
- package/lib/commit-workflow.mjs +160 -5
- package/lib/diagnostics.mjs +72 -9
- package/lib/launcher.mjs +303 -0
- package/lib/manual-commands.mjs +2 -2
- package/lib/manual-ink-app.mjs +34 -1
- package/lib/manual-ink-interaction.mjs +12 -0
- package/lib/manual-ink-ui.mjs +38 -0
- package/lib/manual-mcp.mjs +68 -22
- package/lib/manual-repl.mjs +147 -34
- package/lib/mcp-install.mjs +930 -0
- package/lib/mcp-server.mjs +2 -2
- package/lib/node-runtime.mjs +52 -12
- package/lib/project-mapping-workflow.mjs +2 -20
- package/lib/query-workflow.mjs +19 -0
- package/lib/reminder-scheduler.mjs +34 -18
- package/lib/reminder-service.mjs +18 -4
- package/lib/repo-project-suggestions.mjs +285 -0
- package/lib/ui.mjs +44 -0
- package/package.json +1 -1
- package/skills/logwork/SKILL.md +6 -1
package/lib/ui.mjs
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import * as clackPrompts from '@clack/prompts';
|
|
2
2
|
import { CONFIG } from './config.mjs';
|
|
3
|
+
import { formatSuggestionReason, orderProjectsForPicker } from './repo-project-suggestions.mjs';
|
|
3
4
|
|
|
4
5
|
// Every prompt function takes an optional `{ prompts }` (default: @clack/prompts)
|
|
5
6
|
// so tests can answer prompts without a terminal.
|
|
@@ -28,6 +29,49 @@ export function projectSelectOptions(projects, daySummaries) {
|
|
|
28
29
|
});
|
|
29
30
|
}
|
|
30
31
|
|
|
32
|
+
export const SKIP_REPO_PROJECT = '__skip__';
|
|
33
|
+
|
|
34
|
+
// Options for "which RO project does this repo belong to?": suggested projects
|
|
35
|
+
// first (reason as hint), then every other member project, then skip. Values
|
|
36
|
+
// are option keys; resolve them with the returned items.
|
|
37
|
+
export function repoProjectSelectOptions(suggestions = [], candidates = [], { skipLabel = 'Skip for now' } = {}) {
|
|
38
|
+
const items = orderProjectsForPicker(candidates, suggestions);
|
|
39
|
+
const options = items.map((item, index) => ({
|
|
40
|
+
value: `project:${index}`,
|
|
41
|
+
label: item.project.projectName || `project member ${item.project.projectMemberId}`,
|
|
42
|
+
...(item.suggestion ? { hint: formatSuggestionReason(item.suggestion) } : {})
|
|
43
|
+
}));
|
|
44
|
+
options.push({ value: SKIP_REPO_PROJECT, label: skipLabel });
|
|
45
|
+
return {
|
|
46
|
+
items,
|
|
47
|
+
options,
|
|
48
|
+
initialValue: options[0].value
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export function repoProjectFromOption(items, value) {
|
|
53
|
+
const match = /^project:(\d+)$/.exec(String(value || ''));
|
|
54
|
+
return match ? items[Number(match[1])]?.project || null : null;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// Asks which project a repo belongs to. Returns the chosen project, or null
|
|
58
|
+
// when the user skips (Escape / Ctrl+C also skip).
|
|
59
|
+
export async function chooseRepoProject({ repoName, suggestions = [], candidates = [] }, { prompts = clackPrompts } = {}) {
|
|
60
|
+
const { items, options, initialValue } = repoProjectSelectOptions(suggestions, candidates);
|
|
61
|
+
if (!items.length) {
|
|
62
|
+
return null;
|
|
63
|
+
}
|
|
64
|
+
const value = await prompts.select({
|
|
65
|
+
message: `Which RO project does ${repoName} belong to?`,
|
|
66
|
+
options,
|
|
67
|
+
initialValue
|
|
68
|
+
});
|
|
69
|
+
if (prompts.isCancel(value)) {
|
|
70
|
+
return null;
|
|
71
|
+
}
|
|
72
|
+
return repoProjectFromOption(items, value);
|
|
73
|
+
}
|
|
74
|
+
|
|
31
75
|
export async function chooseTask(tasks, { prompts = clackPrompts } = {}) {
|
|
32
76
|
const taskId = handleCancel(await prompts.select({
|
|
33
77
|
message: 'Chọn loại công việc:',
|
package/package.json
CHANGED
package/skills/logwork/SKILL.md
CHANGED
|
@@ -19,7 +19,12 @@ Goal: every logged line is backed by real work (the user's commits or what the u
|
|
|
19
19
|
- Use 0.5h steps.
|
|
20
20
|
- Do not log weekends or days without a booking unless the user asks.
|
|
21
21
|
- Work without commits (meetings, reviews, support) only comes from the user; ask, then log it as `Other Activities` or `Code Review & Refactoring`.
|
|
22
|
-
6. **Resolve projects.** The draft's `projectOverrides` already name the project of every resolved line. For `unmappedRepos` (lines with no project)
|
|
22
|
+
6. **Resolve projects.** The draft's `projectOverrides` already name the project of every resolved line. For each repo in `unmappedRepos` (lines with no project):
|
|
23
|
+
- Take the top entry of `repoSuggestions[repo]` (ranked by ticket history, repo/remote name and single booked project; `reasons` say why).
|
|
24
|
+
- Ask one short question per repo, by project name: "Is `<repo name>` part of **<projectName>**? (<first reason>)". With no suggestion, ask which project it belongs to and offer names from `projectCandidates`.
|
|
25
|
+
- On a yes (or the user's own pick), call `map_project` with `projectName` (or that suggestion's `projectMemberId`), `repos: [repo]` and `confirm: true`. Never ask the user for ids.
|
|
26
|
+
- Then run `draft_from_commits` again so those lines get their project and hours.
|
|
27
|
+
A line `log_work` still cannot resolve: ask the user and add its id to `projectOverrides`.
|
|
23
28
|
7. **Get approval, then write.**
|
|
24
29
|
- Show the final block to the user.
|
|
25
30
|
- On approval, call `log_work(text, projectOverrides)` and show its preview summary. Pass `projectOverrides` from the draft unchanged when `draftText` is unchanged. Entry ids are `<date>-<NN>` with NN counting lines through the whole text, so if you add, remove or reorder lines, renumber the overrides to match.
|