@tomingtoming/kioq 0.7.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.
@@ -0,0 +1,160 @@
1
+ export function summarizeLintStructureResponse(args) {
2
+ if (args.unresolvedWikiLinkCount > 0) {
3
+ return {
4
+ primaryNavigationSignal: "audit_project_structure",
5
+ primaryQualitySignal: "unresolved_wikilinks_present",
6
+ nextRecommendedAction: "fix_unresolved_wikilinks",
7
+ nextRecommendedTarget: args.firstIssueTitle,
8
+ };
9
+ }
10
+ if (args.memoryContractViolationCount > 0) {
11
+ return {
12
+ primaryNavigationSignal: "audit_project_structure",
13
+ primaryQualitySignal: "memory_contract_violations_present",
14
+ nextRecommendedAction: "fix_memory_contract_violations",
15
+ nextRecommendedTarget: args.firstIssueTitle,
16
+ };
17
+ }
18
+ if (args.duplicateWarningCount > 0) {
19
+ return {
20
+ primaryNavigationSignal: "audit_project_structure",
21
+ primaryQualitySignal: "duplicate_warnings_present",
22
+ nextRecommendedAction: "review_duplicates",
23
+ nextRecommendedTarget: args.firstIssueTitle,
24
+ };
25
+ }
26
+ if (args.dependencyDirectionViolationCount > 0) {
27
+ return {
28
+ primaryNavigationSignal: "audit_project_structure",
29
+ primaryQualitySignal: "dependency_direction_violations_present",
30
+ nextRecommendedAction: "review_dependency_direction_violations",
31
+ nextRecommendedTarget: args.firstIssueTitle,
32
+ };
33
+ }
34
+ if (args.weakStructureCount > 0) {
35
+ return {
36
+ primaryNavigationSignal: "audit_project_structure",
37
+ primaryQualitySignal: "weak_structure_present",
38
+ nextRecommendedAction: "review_weak_structure_notes",
39
+ nextRecommendedTarget: args.firstIssueTitle,
40
+ };
41
+ }
42
+ if (args.orphanNoteCount > 0) {
43
+ return {
44
+ primaryNavigationSignal: "audit_project_structure",
45
+ primaryQualitySignal: "orphan_notes_present",
46
+ nextRecommendedAction: "review_orphan_notes",
47
+ nextRecommendedTarget: args.firstIssueTitle,
48
+ };
49
+ }
50
+ if (args.staleFlowCount > 0) {
51
+ return {
52
+ primaryNavigationSignal: "audit_project_structure",
53
+ primaryQualitySignal: "stale_flows_present",
54
+ nextRecommendedAction: "review_stale_flows",
55
+ nextRecommendedTarget: args.firstIssueTitle,
56
+ };
57
+ }
58
+ if (args.titleBodyMismatchCandidateCount > 0) {
59
+ return {
60
+ primaryNavigationSignal: "audit_project_structure",
61
+ primaryQualitySignal: "title_body_mismatch_candidates_present",
62
+ nextRecommendedAction: "review_title_body_mismatches",
63
+ nextRecommendedTarget: args.firstIssueTitle,
64
+ };
65
+ }
66
+ if (args.singleUseTagCandidateCount > 0) {
67
+ return {
68
+ primaryNavigationSignal: "audit_project_structure",
69
+ primaryQualitySignal: "single_use_tag_candidates_present",
70
+ nextRecommendedAction: "review_single_use_tags",
71
+ nextRecommendedTarget: args.firstIssueTitle,
72
+ };
73
+ }
74
+ return {
75
+ primaryNavigationSignal: "audit_project_structure",
76
+ primaryQualitySignal: "structure_health_ok",
77
+ nextRecommendedAction: "continue_work",
78
+ };
79
+ }
80
+ export function lintStructureResponsePlan(mode) {
81
+ if (mode === "minimal") {
82
+ return {
83
+ includeDebtBreakdown: false,
84
+ includeCompactIssues: false,
85
+ includeDetailedIssues: false,
86
+ };
87
+ }
88
+ if (mode === "standard") {
89
+ return {
90
+ includeDebtBreakdown: true,
91
+ includeCompactIssues: true,
92
+ includeDetailedIssues: false,
93
+ };
94
+ }
95
+ return {
96
+ includeDebtBreakdown: true,
97
+ includeCompactIssues: false,
98
+ includeDetailedIssues: true,
99
+ };
100
+ }
101
+ export function lintStructureResponseModeHint(args) {
102
+ const hasIssues = args.unresolvedWikiLinkCount > 0
103
+ || args.memoryContractViolationCount > 0
104
+ || args.duplicateWarningCount > 0
105
+ || args.dependencyDirectionViolationCount > 0
106
+ || args.weakStructureCount > 0
107
+ || args.orphanNoteCount > 0
108
+ || args.staleFlowCount > 0
109
+ || args.singleUseTagCandidateCount > 0
110
+ || args.titleBodyMismatchCandidateCount > 0;
111
+ if (args.mode === "minimal" && hasIssues) {
112
+ return {
113
+ recommendedResponseMode: "standard",
114
+ responseModeHint: "debt breakdown と top issues を見るには standard に上げる",
115
+ };
116
+ }
117
+ const needsDetailedIssueText = args.unresolvedWikiLinkCount > 0
118
+ || args.memoryContractViolationCount > 0
119
+ || args.duplicateWarningCount > 0
120
+ || args.dependencyDirectionViolationCount > 0
121
+ || args.weakStructureCount > 0
122
+ || args.orphanNoteCount > 0;
123
+ const onlySingleUseTagCandidates = args.singleUseTagCandidateCount > 0
124
+ && args.unresolvedWikiLinkCount === 0
125
+ && args.memoryContractViolationCount === 0
126
+ && args.duplicateWarningCount === 0
127
+ && args.dependencyDirectionViolationCount === 0
128
+ && args.weakStructureCount === 0
129
+ && args.orphanNoteCount === 0
130
+ && args.staleFlowCount === 0
131
+ && args.titleBodyMismatchCandidateCount === 0;
132
+ const onlyTitleBodyMismatchCandidates = args.titleBodyMismatchCandidateCount > 0
133
+ && args.unresolvedWikiLinkCount === 0
134
+ && args.memoryContractViolationCount === 0
135
+ && args.duplicateWarningCount === 0
136
+ && args.dependencyDirectionViolationCount === 0
137
+ && args.weakStructureCount === 0
138
+ && args.orphanNoteCount === 0
139
+ && args.staleFlowCount === 0
140
+ && args.singleUseTagCandidateCount === 0;
141
+ if (args.mode === "standard" && needsDetailedIssueText) {
142
+ return {
143
+ recommendedResponseMode: "verbose",
144
+ responseModeHint: "issue の message / suggestion を見るには verbose に上げる",
145
+ };
146
+ }
147
+ if (args.mode === "standard" && onlySingleUseTagCandidates) {
148
+ return {
149
+ recommendedResponseMode: "verbose",
150
+ responseModeHint: "単発使用 tag 候補の tag 名を確認するには verbose に上げる",
151
+ };
152
+ }
153
+ if (args.mode === "standard" && onlyTitleBodyMismatchCandidates) {
154
+ return {
155
+ recommendedResponseMode: "verbose",
156
+ responseModeHint: "title と本文のズレ理由を見るには verbose に上げる",
157
+ };
158
+ }
159
+ return {};
160
+ }
@@ -0,0 +1,116 @@
1
+ export function summarizeReadChangeTrigger(args) {
2
+ if (args.unresolvedWikiLinkCount > 0) {
3
+ return {
4
+ code: "unresolved_wikilinks",
5
+ confidence: "high",
6
+ cascadeTargets: ["resolve_links", "repair_note_links"],
7
+ noiseRisk: "low",
8
+ };
9
+ }
10
+ if (args.boundaryWarningCount > 0) {
11
+ return {
12
+ code: "responsibility_boundary",
13
+ confidence: "medium",
14
+ cascadeTargets: ["review_boundary_warnings", "rewrite_with_correct_tool"],
15
+ noiseRisk: "medium",
16
+ };
17
+ }
18
+ if (args.orphanWarning) {
19
+ return {
20
+ code: "orphan_note",
21
+ confidence: "medium",
22
+ cascadeTargets: args.indexCandidateAvailable
23
+ ? ["open_index_candidate", "add_backlinks"]
24
+ : ["add_backlinks", "review_note_context"],
25
+ noiseRisk: "medium",
26
+ };
27
+ }
28
+ if (args.clarityAttention) {
29
+ return {
30
+ code: "document_clarity",
31
+ confidence: "medium",
32
+ cascadeTargets: ["review_document_clarity", "rewrite_summary"],
33
+ noiseRisk: "medium",
34
+ };
35
+ }
36
+ return {
37
+ code: "none",
38
+ };
39
+ }
40
+ export function summarizeLintChangeTrigger(args) {
41
+ if (args.unresolvedWikiLinkCount > 0) {
42
+ return {
43
+ code: "unresolved_wikilinks",
44
+ confidence: "high",
45
+ cascadeTargets: ["resolve_links", "repair_note_structure"],
46
+ noiseRisk: "low",
47
+ };
48
+ }
49
+ if (args.memoryContractViolationCount > 0) {
50
+ return {
51
+ code: "memory_contract_violation",
52
+ confidence: "high",
53
+ cascadeTargets: ["read_note", "repair_note_structure"],
54
+ noiseRisk: "low",
55
+ };
56
+ }
57
+ if (args.duplicateWarningCount > 0) {
58
+ return {
59
+ code: "duplicate_conflict",
60
+ confidence: "medium",
61
+ cascadeTargets: ["review_duplicates", "rename_or_merge"],
62
+ noiseRisk: "low",
63
+ };
64
+ }
65
+ if (args.dependencyDirectionViolationCount > 0) {
66
+ return {
67
+ code: "dependency_direction_violation",
68
+ confidence: "medium",
69
+ cascadeTargets: ["review_dependency_direction_violations", "move_links_to_related"],
70
+ noiseRisk: "low",
71
+ };
72
+ }
73
+ if (args.weakStructureCount > 0) {
74
+ return {
75
+ code: "weak_structure",
76
+ confidence: "medium",
77
+ cascadeTargets: ["read_note", "add_links"],
78
+ noiseRisk: "medium",
79
+ };
80
+ }
81
+ if (args.orphanNoteCount > 0) {
82
+ return {
83
+ code: "orphan_note",
84
+ confidence: "medium",
85
+ cascadeTargets: ["review_orphan_repair_queue", "link_or_reparent_notes"],
86
+ noiseRisk: "low",
87
+ };
88
+ }
89
+ if (args.staleFlowCount > 0) {
90
+ return {
91
+ code: "stale_flow",
92
+ confidence: "medium",
93
+ cascadeTargets: ["triage_flows", "update_flow_state"],
94
+ noiseRisk: "low",
95
+ };
96
+ }
97
+ if (args.titleBodyMismatchCandidateCount > 0) {
98
+ return {
99
+ code: "title_body_mismatch",
100
+ confidence: "low",
101
+ cascadeTargets: ["review_title_body_mismatches", "rewrite_note_summary"],
102
+ noiseRisk: "medium",
103
+ };
104
+ }
105
+ if (args.singleUseTagCandidateCount > 0) {
106
+ return {
107
+ code: "single_use_tag",
108
+ confidence: "low",
109
+ cascadeTargets: ["review_single_use_tags", "normalize_tags"],
110
+ noiseRisk: "medium",
111
+ };
112
+ }
113
+ return {
114
+ code: "none",
115
+ };
116
+ }
@@ -0,0 +1,192 @@
1
+ import path from "node:path";
2
+ import os from "node:os";
3
+ function parsePreviewLength(value) {
4
+ const parsed = Number(value ?? "320");
5
+ if (!Number.isFinite(parsed) || parsed <= 0) {
6
+ return 320;
7
+ }
8
+ return Math.floor(parsed);
9
+ }
10
+ function parseNonNegativeInteger(value, fallback) {
11
+ const parsed = Number(value ?? String(fallback));
12
+ if (!Number.isFinite(parsed) || parsed < 0) {
13
+ return fallback;
14
+ }
15
+ return Math.floor(parsed);
16
+ }
17
+ function parsePositiveInteger(value, fallback) {
18
+ const parsed = Number(value ?? String(fallback));
19
+ if (!Number.isFinite(parsed) || parsed < 1) {
20
+ return fallback;
21
+ }
22
+ return Math.floor(parsed);
23
+ }
24
+ function readOptionValue(argv, index) {
25
+ const arg = argv[index];
26
+ if (!arg.startsWith("--")) {
27
+ return { nextIndex: index };
28
+ }
29
+ const equalIndex = arg.indexOf("=");
30
+ if (equalIndex >= 0) {
31
+ return {
32
+ value: arg.slice(equalIndex + 1),
33
+ nextIndex: index,
34
+ };
35
+ }
36
+ const nextValue = argv[index + 1];
37
+ if (nextValue && !nextValue.startsWith("--")) {
38
+ return {
39
+ value: nextValue,
40
+ nextIndex: index + 1,
41
+ };
42
+ }
43
+ return { nextIndex: index };
44
+ }
45
+ function matchesOption(arg, optionName) {
46
+ return arg === optionName || arg.startsWith(`${optionName}=`);
47
+ }
48
+ function parseDefaultDirectory(value) {
49
+ const candidate = value?.trim();
50
+ return candidate && candidate.length > 0 ? candidate : "Inbox";
51
+ }
52
+ function parseCliOptions(argv) {
53
+ const options = {};
54
+ for (let index = 0; index < argv.length; index += 1) {
55
+ const arg = argv[index];
56
+ if (!arg.startsWith("--")) {
57
+ continue;
58
+ }
59
+ if (matchesOption(arg, "--root")) {
60
+ const { value, nextIndex } = readOptionValue(argv, index);
61
+ if (value && value.trim().length > 0) {
62
+ options.root = value;
63
+ }
64
+ index = nextIndex;
65
+ continue;
66
+ }
67
+ if (matchesOption(arg, "--github-token")) {
68
+ throw new Error("--github-token has been removed; use KIOQ_GITHUB_TOKEN");
69
+ }
70
+ if (matchesOption(arg, "--github-token-file")) {
71
+ throw new Error("--github-token-file has been removed; use KIOQ_GITHUB_TOKEN");
72
+ }
73
+ if (matchesOption(arg, "--github-branch")) {
74
+ const { value, nextIndex } = readOptionValue(argv, index);
75
+ if (value && value.trim().length > 0) {
76
+ options.githubBranch = value;
77
+ }
78
+ index = nextIndex;
79
+ continue;
80
+ }
81
+ if (matchesOption(arg, "--github-repo")) {
82
+ const { value, nextIndex } = readOptionValue(argv, index);
83
+ if (value && value.trim().length > 0) {
84
+ options.github = value;
85
+ }
86
+ index = nextIndex;
87
+ continue;
88
+ }
89
+ if (matchesOption(arg, "--github")) {
90
+ const { value, nextIndex } = readOptionValue(argv, index);
91
+ if (value && value.trim().length > 0) {
92
+ options.github = value;
93
+ }
94
+ index = nextIndex;
95
+ continue;
96
+ }
97
+ if (matchesOption(arg, "--default-directory")) {
98
+ const { value, nextIndex } = readOptionValue(argv, index);
99
+ if (value && value.trim().length > 0) {
100
+ options.defaultDirectory = value;
101
+ }
102
+ index = nextIndex;
103
+ continue;
104
+ }
105
+ if (matchesOption(arg, "--preview-length")) {
106
+ const { value, nextIndex } = readOptionValue(argv, index);
107
+ if (value && value.trim().length > 0) {
108
+ options.previewLength = value;
109
+ }
110
+ index = nextIndex;
111
+ continue;
112
+ }
113
+ if (matchesOption(arg, "--index-score-threshold")) {
114
+ const { value, nextIndex } = readOptionValue(argv, index);
115
+ if (value && value.trim().length > 0) {
116
+ options.indexScoreThreshold = value;
117
+ }
118
+ index = nextIndex;
119
+ continue;
120
+ }
121
+ if (matchesOption(arg, "--index-section-threshold")) {
122
+ const { value, nextIndex } = readOptionValue(argv, index);
123
+ if (value && value.trim().length > 0) {
124
+ options.indexSectionThreshold = value;
125
+ }
126
+ index = nextIndex;
127
+ continue;
128
+ }
129
+ if (matchesOption(arg, "--stale-flow-days")) {
130
+ const { value, nextIndex } = readOptionValue(argv, index);
131
+ if (value && value.trim().length > 0) {
132
+ options.staleFlowDays = value;
133
+ }
134
+ index = nextIndex;
135
+ continue;
136
+ }
137
+ }
138
+ return options;
139
+ }
140
+ function parseGitHubSlug(value) {
141
+ const slashIndex = value.indexOf("/");
142
+ if (slashIndex <= 0 || slashIndex === value.length - 1) {
143
+ throw new Error(`Invalid GitHub slug "${value}": expected "owner/repo" format`);
144
+ }
145
+ return {
146
+ owner: value.slice(0, slashIndex),
147
+ repo: value.slice(slashIndex + 1),
148
+ };
149
+ }
150
+ export function loadConfig(env = process.env, argv = process.argv.slice(2)) {
151
+ const cli = parseCliOptions(argv);
152
+ if (env.KIOQ_GITHUB_TOKEN_FILE) {
153
+ throw new Error("KIOQ_GITHUB_TOKEN_FILE has been removed; use KIOQ_GITHUB_TOKEN");
154
+ }
155
+ const githubSlug = cli.github ?? env.KIOQ_GITHUB;
156
+ const isGitHubMode = !!githubSlug;
157
+ let github;
158
+ let root;
159
+ if (isGitHubMode) {
160
+ const { owner, repo } = parseGitHubSlug(githubSlug);
161
+ const token = env.KIOQ_GITHUB_TOKEN;
162
+ const branch = cli.githubBranch ?? env.KIOQ_GITHUB_BRANCH ?? "main";
163
+ if (!token) {
164
+ throw new Error("KIOQ_GITHUB_TOKEN is required when GitHub mode is enabled");
165
+ }
166
+ github = { owner, repo, branch, token };
167
+ const rawRoot = cli.root ?? env.KIOQ_ROOT;
168
+ root = rawRoot
169
+ ? path.resolve(rawRoot)
170
+ : path.join(os.homedir(), ".cache", "kioq", owner, repo);
171
+ }
172
+ else {
173
+ const rawRoot = cli.root ?? env.KIOQ_ROOT;
174
+ if (!rawRoot) {
175
+ throw new Error("KIOQ_ROOT or --root is required");
176
+ }
177
+ root = path.resolve(rawRoot);
178
+ }
179
+ return {
180
+ root,
181
+ defaultDirectory: parseDefaultDirectory(cli.defaultDirectory ?? env.KIOQ_DEFAULT_DIRECTORY),
182
+ github,
183
+ previewLength: parsePreviewLength(cli.previewLength ?? env.KIOQ_PREVIEW_LENGTH),
184
+ indexNavigation: {
185
+ scoreThreshold: parseNonNegativeInteger(cli.indexScoreThreshold ?? env.KIOQ_INDEX_SCORE_THRESHOLD, 70),
186
+ sectionThreshold: parsePositiveInteger(cli.indexSectionThreshold ?? env.KIOQ_INDEX_SECTION_THRESHOLD, 2),
187
+ },
188
+ technicalDebt: {
189
+ staleFlowDays: parsePositiveInteger(cli.staleFlowDays ?? env.KIOQ_STALE_FLOW_DAYS, 7),
190
+ },
191
+ };
192
+ }
@@ -0,0 +1,7 @@
1
+ export function summarizeNoConflict(args) {
2
+ return {
3
+ conflictType: "none",
4
+ serverUpdated: args.serverUpdated,
5
+ retryHint: "reread_before_retry_if_parallel_edits_possible",
6
+ };
7
+ }
@@ -0,0 +1,43 @@
1
+ export function summarizeMemoryContractResponse() {
2
+ return {
3
+ primaryNavigationSignal: "contract_available",
4
+ primaryQualitySignal: "contract_ready",
5
+ nextRecommendedAction: "follow_memory_contract",
6
+ };
7
+ }
8
+ export function memoryContractResponsePlan(mode) {
9
+ if (mode === "minimal") {
10
+ return {
11
+ includePolicyRules: false,
12
+ includePolicySignals: false,
13
+ includeSampleTemplates: false,
14
+ };
15
+ }
16
+ if (mode === "standard") {
17
+ return {
18
+ includePolicyRules: true,
19
+ includePolicySignals: false,
20
+ includeSampleTemplates: false,
21
+ };
22
+ }
23
+ return {
24
+ includePolicyRules: true,
25
+ includePolicySignals: true,
26
+ includeSampleTemplates: true,
27
+ };
28
+ }
29
+ export function memoryContractResponseModeHint(mode) {
30
+ if (mode === "minimal") {
31
+ return {
32
+ recommendedResponseMode: "standard",
33
+ responseModeHint: "policy と rules を見るには standard に上げる",
34
+ };
35
+ }
36
+ if (mode === "standard") {
37
+ return {
38
+ recommendedResponseMode: "verbose",
39
+ responseModeHint: "sample template 本文を見るには verbose に上げる",
40
+ };
41
+ }
42
+ return {};
43
+ }