docs: 補齊 JSDoc 與指令檔註解、測試移至 app/test 並重建 README #10
+1
-1
@@ -3,7 +3,7 @@
|
|||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "node --test *.test.js"
|
"test": "node --test test/*.test.js"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"axios": "^1.6.7",
|
"axios": "^1.6.7",
|
||||||
|
|||||||
@@ -3,8 +3,8 @@ import assert from 'node:assert/strict';
|
|||||||
import fs from 'node:fs';
|
import fs from 'node:fs';
|
||||||
import os from 'node:os';
|
import os from 'node:os';
|
||||||
import path from 'node:path';
|
import path from 'node:path';
|
||||||
import { saveFindings, parseLocation, postNewCriticalComments, postFindingsReview, formatFindingsStats, formatFindingsStatsLine } from './comments.js';
|
import { saveFindings, parseLocation, postNewCriticalComments, postFindingsReview, formatFindingsStats, formatFindingsStatsLine } from '../comments.js';
|
||||||
import { FINDINGS_PATH } from './config.js';
|
import { FINDINGS_PATH } from '../config.js';
|
||||||
|
|
||||||
describe('saveFindings', () => {
|
describe('saveFindings', () => {
|
||||||
const tempDirs = [];
|
const tempDirs = [];
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
import { describe, it, beforeEach, afterEach } from 'node:test';
|
import { describe, it, beforeEach, afterEach } from 'node:test';
|
||||||
import assert from 'node:assert/strict';
|
import assert from 'node:assert/strict';
|
||||||
import { getLLMConfig, getOpenCodeHttpsAgent } from './config.js';
|
import { getLLMConfig, getOpenCodeHttpsAgent } from '../config.js';
|
||||||
|
|
||||||
const ENV_KEYS = [
|
const ENV_KEYS = [
|
||||||
'OPENCODE_BASE_URL', 'OPENCODE_MODEL', 'OPENCODE_PROVIDER',
|
'OPENCODE_BASE_URL', 'OPENCODE_MODEL', 'OPENCODE_PROVIDER',
|
||||||
@@ -3,8 +3,8 @@ import assert from 'node:assert/strict';
|
|||||||
import fs from 'node:fs';
|
import fs from 'node:fs';
|
||||||
import os from 'node:os';
|
import os from 'node:os';
|
||||||
import path from 'node:path';
|
import path from 'node:path';
|
||||||
import { loadOldFindings, loadExclusions, applyExclusions, filterFalsePositivesWithAI, appendExclusions, resolveMissingLineNumbers } from './findings.js';
|
import { loadOldFindings, loadExclusions, applyExclusions, filterFalsePositivesWithAI, appendExclusions, resolveMissingLineNumbers } from '../findings.js';
|
||||||
import { EXCLUSIONS_PATH, FINDINGS_PATH } from './config.js';
|
import { EXCLUSIONS_PATH, FINDINGS_PATH } from '../config.js';
|
||||||
|
|
||||||
describe('findings exclusions', () => {
|
describe('findings exclusions', () => {
|
||||||
let workspace;
|
let workspace;
|
||||||
@@ -3,7 +3,7 @@ import assert from 'node:assert/strict';
|
|||||||
import fs from 'fs';
|
import fs from 'fs';
|
||||||
import os from 'os';
|
import os from 'os';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
import { commitAndPush, cloneRepo, verifyRemoteAccess, BOT_COMMIT_MARKER, getHeadCommitMessage, isBotAutoCommit } from './git.js';
|
import { commitAndPush, cloneRepo, verifyRemoteAccess, BOT_COMMIT_MARKER, getHeadCommitMessage, isBotAutoCommit } from '../git.js';
|
||||||
|
|
||||||
// --- helpers ---
|
// --- helpers ---
|
||||||
function makeTmpWorkspace() {
|
function makeTmpWorkspace() {
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
import { describe, it, afterEach, mock } from 'node:test';
|
import { describe, it, afterEach, mock } from 'node:test';
|
||||||
import assert from 'node:assert/strict';
|
import assert from 'node:assert/strict';
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import { getPRDiff, filterDiff, postComment, postPullReviewComment, postPullReview, getCommitMessageBySha, getBranchHeadCommitMessage, shouldSkipBotCommit, getBotReviewOutcome, listPullReviews, getPullReviewComments, listAllReviewComments, resolvePullReviewComment, getFileContentAtRef } from './gitea.js';
|
import { getPRDiff, filterDiff, postComment, postPullReviewComment, postPullReview, getCommitMessageBySha, getBranchHeadCommitMessage, shouldSkipBotCommit, getBotReviewOutcome, listPullReviews, getPullReviewComments, listAllReviewComments, resolvePullReviewComment, getFileContentAtRef } from '../gitea.js';
|
||||||
|
|
||||||
afterEach(() => mock.restoreAll());
|
afterEach(() => mock.restoreAll());
|
||||||
|
|
||||||
@@ -3,7 +3,7 @@ import assert from 'node:assert/strict';
|
|||||||
import fs from 'fs';
|
import fs from 'fs';
|
||||||
import os from 'os';
|
import os from 'os';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
import { stripCodeFence, repairJSONArrayWithAI, validateJSONArrayFile, ensureJSONArrayFileExists } from './json.js';
|
import { stripCodeFence, repairJSONArrayWithAI, validateJSONArrayFile, ensureJSONArrayFileExists } from '../json.js';
|
||||||
|
|
||||||
describe('json helpers', () => {
|
describe('json helpers', () => {
|
||||||
const MAX_JSON_BYTES = 1024 * 1024;
|
const MAX_JSON_BYTES = 1024 * 1024;
|
||||||
@@ -29,7 +29,7 @@ function mockOpenCodeResponse(content) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
describe('chat - OpenCode', async () => {
|
describe('chat - OpenCode', async () => {
|
||||||
const { chat } = await import('./llm.js');
|
const { chat } = await import('../llm.js');
|
||||||
|
|
||||||
it('uses OpenCode server session API', async () => {
|
it('uses OpenCode server session API', async () => {
|
||||||
process.env.OPENCODE_BASE_URL = 'http://opencode.local:4096';
|
process.env.OPENCODE_BASE_URL = 'http://opencode.local:4096';
|
||||||
@@ -96,7 +96,7 @@ describe('chat - OpenCode', async () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('chatJSON', async () => {
|
describe('chatJSON', async () => {
|
||||||
const { chatJSON } = await import('./llm.js');
|
const { chatJSON } = await import('../llm.js');
|
||||||
|
|
||||||
it('parses plain JSON response', async () => {
|
it('parses plain JSON response', async () => {
|
||||||
process.env.OPENCODE_BASE_URL = 'http://opencode.local:4096';
|
process.env.OPENCODE_BASE_URL = 'http://opencode.local:4096';
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
import { describe, it, afterEach, mock } from 'node:test';
|
import { describe, it, afterEach, mock } from 'node:test';
|
||||||
import assert from 'node:assert/strict';
|
import assert from 'node:assert/strict';
|
||||||
import { section, step, line, input, output, result, ok, warn, error } from './log.js';
|
import { section, step, line, input, output, result, ok, warn, error } from '../log.js';
|
||||||
|
|
||||||
afterEach(() => mock.restoreAll());
|
afterEach(() => mock.restoreAll());
|
||||||
|
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
import { describe, it, afterEach, mock } from 'node:test';
|
import { describe, it, afterEach, mock } from 'node:test';
|
||||||
import assert from 'node:assert/strict';
|
import assert from 'node:assert/strict';
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import { checkRequiredEnv, verifyGiteaToken, verifyCommentToken, verifyLLM, runPreflight } from './preflight.js';
|
import { checkRequiredEnv, verifyGiteaToken, verifyCommentToken, verifyLLM, runPreflight } from '../preflight.js';
|
||||||
|
|
||||||
const LLM_ENV_KEYS = [
|
const LLM_ENV_KEYS = [
|
||||||
'OPENCODE_BASE_URL', 'OPENCODE_MODEL', 'OPENCODE_PROVIDER',
|
'OPENCODE_BASE_URL', 'OPENCODE_MODEL', 'OPENCODE_PROVIDER',
|
||||||
@@ -8,7 +8,7 @@ import {
|
|||||||
reconcileConversations,
|
reconcileConversations,
|
||||||
dropResolvedFindings,
|
dropResolvedFindings,
|
||||||
addCarriedFindings,
|
addCarriedFindings,
|
||||||
} from './resolve.js';
|
} from '../resolve.js';
|
||||||
|
|
||||||
const reviewBody = (level, role, problem, suggestion) =>
|
const reviewBody = (level, role, problem, suggestion) =>
|
||||||
`**嚴重等級**:${level}\n**審查員**:${role}\n**問題**:${problem}\n**建議**:${suggestion}`;
|
`**嚴重等級**:${level}\n**審查員**:${role}\n**問題**:${problem}\n**建議**:${suggestion}`;
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
import { describe, it } from 'node:test';
|
import { describe, it } from 'node:test';
|
||||||
import assert from 'node:assert/strict';
|
import assert from 'node:assert/strict';
|
||||||
import { parseRoleFile, loadRoles, loadRole, buildAnalysisPrompt, buildLocateLinePrompt, getRoleIntro } from './roles.js';
|
import { parseRoleFile, loadRoles, loadRole, buildAnalysisPrompt, buildLocateLinePrompt, getRoleIntro } from '../roles.js';
|
||||||
|
|
||||||
const SAMPLE = `---
|
const SAMPLE = `---
|
||||||
name: Tester
|
name: Tester
|
||||||
@@ -12,7 +12,7 @@ import {
|
|||||||
fetchAccountQuota,
|
fetchAccountQuota,
|
||||||
formatUsageStats,
|
formatUsageStats,
|
||||||
formatUsageStatsLine,
|
formatUsageStatsLine,
|
||||||
} from './usage.js';
|
} from '../usage.js';
|
||||||
|
|
||||||
describe('extractUsage', () => {
|
describe('extractUsage', () => {
|
||||||
it('parses OpenAI-compatible usage', () => {
|
it('parses OpenAI-compatible usage', () => {
|
||||||
Reference in New Issue
Block a user