codesift-mcp 0.5.21 → 0.5.27
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 +9 -9
- package/dist/cli/commands.d.ts.map +1 -1
- package/dist/cli/commands.js +28 -0
- package/dist/cli/commands.js.map +1 -1
- package/dist/cli/help.js +1 -1
- package/dist/cli/help.js.map +1 -1
- package/dist/cli/hooks.d.ts +4 -0
- package/dist/cli/hooks.d.ts.map +1 -1
- package/dist/cli/hooks.js +15 -4
- package/dist/cli/hooks.js.map +1 -1
- package/dist/cli/journal-commands.d.ts +9 -0
- package/dist/cli/journal-commands.d.ts.map +1 -0
- package/dist/cli/journal-commands.js +160 -0
- package/dist/cli/journal-commands.js.map +1 -0
- package/dist/cli/wiki-commands.d.ts.map +1 -1
- package/dist/cli/wiki-commands.js +5 -0
- package/dist/cli/wiki-commands.js.map +1 -1
- package/dist/instructions.d.ts +1 -1
- package/dist/instructions.d.ts.map +1 -1
- package/dist/instructions.js +41 -47
- package/dist/instructions.js.map +1 -1
- package/dist/parser/extractors/_shared.d.ts +2 -0
- package/dist/parser/extractors/_shared.d.ts.map +1 -1
- package/dist/parser/extractors/_shared.js +4 -0
- package/dist/parser/extractors/_shared.js.map +1 -1
- package/dist/parser/extractors/typescript.d.ts.map +1 -1
- package/dist/parser/extractors/typescript.js +606 -31
- package/dist/parser/extractors/typescript.js.map +1 -1
- package/dist/parser/parse-worker.d.ts +2 -0
- package/dist/parser/parse-worker.d.ts.map +1 -0
- package/dist/parser/parse-worker.js +47 -0
- package/dist/parser/parse-worker.js.map +1 -0
- package/dist/parser/parser-manager.d.ts +10 -1
- package/dist/parser/parser-manager.d.ts.map +1 -1
- package/dist/parser/parser-manager.js +40 -2
- package/dist/parser/parser-manager.js.map +1 -1
- package/dist/parser/parser-pool.d.ts +31 -0
- package/dist/parser/parser-pool.d.ts.map +1 -0
- package/dist/parser/parser-pool.js +211 -0
- package/dist/parser/parser-pool.js.map +1 -0
- package/dist/register-tools.d.ts.map +1 -1
- package/dist/register-tools.js +394 -35
- package/dist/register-tools.js.map +1 -1
- package/dist/retrieval/codebase-retrieval.d.ts.map +1 -1
- package/dist/retrieval/codebase-retrieval.js +9 -1
- package/dist/retrieval/codebase-retrieval.js.map +1 -1
- package/dist/search/chunker.d.ts +1 -0
- package/dist/search/chunker.d.ts.map +1 -1
- package/dist/search/chunker.js +8 -1
- package/dist/search/chunker.js.map +1 -1
- package/dist/server-helpers.d.ts +27 -0
- package/dist/server-helpers.d.ts.map +1 -1
- package/dist/server-helpers.js +90 -9
- package/dist/server-helpers.js.map +1 -1
- package/dist/server.js +31 -0
- package/dist/server.js.map +1 -1
- package/dist/storage/index-store.d.ts +41 -4
- package/dist/storage/index-store.d.ts.map +1 -1
- package/dist/storage/index-store.js +89 -6
- package/dist/storage/index-store.js.map +1 -1
- package/dist/storage/watcher.d.ts +33 -6
- package/dist/storage/watcher.d.ts.map +1 -1
- package/dist/storage/watcher.js +73 -34
- package/dist/storage/watcher.js.map +1 -1
- package/dist/storage/workspace-resolver.d.ts +15 -0
- package/dist/storage/workspace-resolver.d.ts.map +1 -0
- package/dist/storage/workspace-resolver.js +130 -0
- package/dist/storage/workspace-resolver.js.map +1 -0
- package/dist/tools/_helpers.d.ts +37 -0
- package/dist/tools/_helpers.d.ts.map +1 -0
- package/dist/tools/_helpers.js +31 -0
- package/dist/tools/_helpers.js.map +1 -0
- package/dist/tools/constant-resolution-tools.d.ts +8 -0
- package/dist/tools/constant-resolution-tools.d.ts.map +1 -0
- package/dist/tools/constant-resolution-tools.js +68 -0
- package/dist/tools/constant-resolution-tools.js.map +1 -0
- package/dist/tools/graph-tools.d.ts +27 -5
- package/dist/tools/graph-tools.d.ts.map +1 -1
- package/dist/tools/graph-tools.js +141 -18
- package/dist/tools/graph-tools.js.map +1 -1
- package/dist/tools/hotspot-tools.d.ts +6 -0
- package/dist/tools/hotspot-tools.d.ts.map +1 -1
- package/dist/tools/hotspot-tools.js +48 -8
- package/dist/tools/hotspot-tools.js.map +1 -1
- package/dist/tools/impact-tools.d.ts.map +1 -1
- package/dist/tools/impact-tools.js +9 -2
- package/dist/tools/impact-tools.js.map +1 -1
- package/dist/tools/index-tools.d.ts +15 -1
- package/dist/tools/index-tools.d.ts.map +1 -1
- package/dist/tools/index-tools.js +161 -16
- package/dist/tools/index-tools.js.map +1 -1
- package/dist/tools/journal-generator-helpers.d.ts +55 -0
- package/dist/tools/journal-generator-helpers.d.ts.map +1 -0
- package/dist/tools/journal-generator-helpers.js +250 -0
- package/dist/tools/journal-generator-helpers.js.map +1 -0
- package/dist/tools/journal-generator.d.ts +48 -0
- package/dist/tools/journal-generator.d.ts.map +1 -0
- package/dist/tools/journal-generator.js +204 -0
- package/dist/tools/journal-generator.js.map +1 -0
- package/dist/tools/journal-git-client.d.ts +20 -0
- package/dist/tools/journal-git-client.d.ts.map +1 -0
- package/dist/tools/journal-git-client.js +57 -0
- package/dist/tools/journal-git-client.js.map +1 -0
- package/dist/tools/journal-llm-client.d.ts +57 -0
- package/dist/tools/journal-llm-client.d.ts.map +1 -0
- package/dist/tools/journal-llm-client.js +175 -0
- package/dist/tools/journal-llm-client.js.map +1 -0
- package/dist/tools/journal-migrator.d.ts +22 -0
- package/dist/tools/journal-migrator.d.ts.map +1 -0
- package/dist/tools/journal-migrator.js +183 -0
- package/dist/tools/journal-migrator.js.map +1 -0
- package/dist/tools/journal-phase-detector.d.ts +26 -0
- package/dist/tools/journal-phase-detector.d.ts.map +1 -0
- package/dist/tools/journal-phase-detector.js +126 -0
- package/dist/tools/journal-phase-detector.js.map +1 -0
- package/dist/tools/journal-sentinel.d.ts +15 -0
- package/dist/tools/journal-sentinel.d.ts.map +1 -0
- package/dist/tools/journal-sentinel.js +110 -0
- package/dist/tools/journal-sentinel.js.map +1 -0
- package/dist/tools/journal-templates.d.ts +28 -0
- package/dist/tools/journal-templates.d.ts.map +1 -0
- package/dist/tools/journal-templates.js +93 -0
- package/dist/tools/journal-templates.js.map +1 -0
- package/dist/tools/pattern-tools.d.ts +2 -0
- package/dist/tools/pattern-tools.d.ts.map +1 -1
- package/dist/tools/pattern-tools.js +73 -0
- package/dist/tools/pattern-tools.js.map +1 -1
- package/dist/tools/perf-tools.d.ts.map +1 -1
- package/dist/tools/perf-tools.js +6 -0
- package/dist/tools/perf-tools.js.map +1 -1
- package/dist/tools/plan-turn-tools.d.ts.map +1 -1
- package/dist/tools/plan-turn-tools.js +38 -2
- package/dist/tools/plan-turn-tools.js.map +1 -1
- package/dist/tools/project-tools.d.ts +6 -0
- package/dist/tools/project-tools.d.ts.map +1 -1
- package/dist/tools/project-tools.js +65 -25
- package/dist/tools/project-tools.js.map +1 -1
- package/dist/tools/python-constants-tools.d.ts +6 -0
- package/dist/tools/python-constants-tools.d.ts.map +1 -1
- package/dist/tools/python-constants-tools.js.map +1 -1
- package/dist/tools/react-tools.d.ts +44 -1
- package/dist/tools/react-tools.d.ts.map +1 -1
- package/dist/tools/react-tools.js +142 -9
- package/dist/tools/react-tools.js.map +1 -1
- package/dist/tools/search-tools.d.ts.map +1 -1
- package/dist/tools/search-tools.js +21 -2
- package/dist/tools/search-tools.js.map +1 -1
- package/dist/tools/status-tools.d.ts +10 -0
- package/dist/tools/status-tools.d.ts.map +1 -1
- package/dist/tools/status-tools.js +53 -2
- package/dist/tools/status-tools.js.map +1 -1
- package/dist/tools/symbol-tools.d.ts +13 -0
- package/dist/tools/symbol-tools.d.ts.map +1 -1
- package/dist/tools/symbol-tools.js +38 -0
- package/dist/tools/symbol-tools.js.map +1 -1
- package/dist/tools/typescript-constants-tools.d.ts +6 -0
- package/dist/tools/typescript-constants-tools.d.ts.map +1 -0
- package/dist/tools/typescript-constants-tools.js +687 -0
- package/dist/tools/typescript-constants-tools.js.map +1 -0
- package/dist/tools/wiki-hub-ranker.d.ts +36 -0
- package/dist/tools/wiki-hub-ranker.d.ts.map +1 -0
- package/dist/tools/wiki-hub-ranker.js +72 -0
- package/dist/tools/wiki-hub-ranker.js.map +1 -0
- package/dist/tools/wiki-lint.d.ts +7 -2
- package/dist/tools/wiki-lint.d.ts.map +1 -1
- package/dist/tools/wiki-lint.js +73 -1
- package/dist/tools/wiki-lint.js.map +1 -1
- package/dist/tools/wiki-manifest.d.ts +129 -21
- package/dist/tools/wiki-manifest.d.ts.map +1 -1
- package/dist/tools/wiki-manifest.js +16 -9
- package/dist/tools/wiki-manifest.js.map +1 -1
- package/dist/tools/wiki-module-builder.d.ts +42 -0
- package/dist/tools/wiki-module-builder.d.ts.map +1 -0
- package/dist/tools/wiki-module-builder.js +449 -0
- package/dist/tools/wiki-module-builder.js.map +1 -0
- package/dist/tools/wiki-overview-sources.d.ts +26 -0
- package/dist/tools/wiki-overview-sources.d.ts.map +1 -0
- package/dist/tools/wiki-overview-sources.js +128 -0
- package/dist/tools/wiki-overview-sources.js.map +1 -0
- package/dist/tools/wiki-page-generators.d.ts +19 -3
- package/dist/tools/wiki-page-generators.d.ts.map +1 -1
- package/dist/tools/wiki-page-generators.js +156 -22
- package/dist/tools/wiki-page-generators.js.map +1 -1
- package/dist/tools/wiki-tools.d.ts +20 -0
- package/dist/tools/wiki-tools.d.ts.map +1 -1
- package/dist/tools/wiki-tools.js +181 -29
- package/dist/tools/wiki-tools.js.map +1 -1
- package/dist/tools/workspace-scope-helper.d.ts +21 -0
- package/dist/tools/workspace-scope-helper.d.ts.map +1 -0
- package/dist/tools/workspace-scope-helper.js +50 -0
- package/dist/tools/workspace-scope-helper.js.map +1 -0
- package/dist/tools/workspace-tools.d.ts +74 -0
- package/dist/tools/workspace-tools.d.ts.map +1 -0
- package/dist/tools/workspace-tools.js +366 -0
- package/dist/tools/workspace-tools.js.map +1 -0
- package/dist/types.d.ts +65 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/utils/import-graph.d.ts +27 -0
- package/dist/utils/import-graph.d.ts.map +1 -1
- package/dist/utils/import-graph.js +331 -8
- package/dist/utils/import-graph.js.map +1 -1
- package/dist/utils/ts-imports.d.ts +30 -0
- package/dist/utils/ts-imports.d.ts.map +1 -0
- package/dist/utils/ts-imports.js +168 -0
- package/dist/utils/ts-imports.js.map +1 -0
- package/dist/utils/tsconfig-paths.d.ts +59 -0
- package/dist/utils/tsconfig-paths.d.ts.map +1 -0
- package/dist/utils/tsconfig-paths.js +176 -0
- package/dist/utils/tsconfig-paths.js.map +1 -0
- package/dist/utils/walk.d.ts.map +1 -1
- package/dist/utils/walk.js +1 -0
- package/dist/utils/walk.js.map +1 -1
- package/package.json +13 -3
- package/rules/codesift.md +19 -2
- package/rules/codesift.mdc +2 -2
- package/rules/codex.md +13 -2
- package/rules/gemini.md +13 -2
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
export declare const LLM_TIMEOUT_MS = 30000;
|
|
2
|
+
export declare const LLM_MAX_RETRIES = 2;
|
|
3
|
+
export declare const DEFAULT_MAX_COST_USD = 2;
|
|
4
|
+
export declare const MODEL_PRICING: Record<string, {
|
|
5
|
+
input: number;
|
|
6
|
+
output: number;
|
|
7
|
+
}>;
|
|
8
|
+
export interface LlmResult {
|
|
9
|
+
content: string;
|
|
10
|
+
tokensInput: number;
|
|
11
|
+
tokensOutput: number;
|
|
12
|
+
costUsd: number;
|
|
13
|
+
provider: "anthropic" | "openai" | "scaffold";
|
|
14
|
+
}
|
|
15
|
+
export interface GenerateOptions {
|
|
16
|
+
model: string;
|
|
17
|
+
systemPrompt?: string;
|
|
18
|
+
maxTokens?: number;
|
|
19
|
+
/** When true, non-JSON content triggers one retry then MalformedJsonError. */
|
|
20
|
+
parseJson?: boolean;
|
|
21
|
+
}
|
|
22
|
+
export interface JournalLlmProvider {
|
|
23
|
+
generate(prompt: string, options: GenerateOptions): Promise<LlmResult>;
|
|
24
|
+
}
|
|
25
|
+
export declare class CostCapExceededError extends Error {
|
|
26
|
+
readonly runningCost: number;
|
|
27
|
+
readonly cap: number;
|
|
28
|
+
constructor(runningCost: number, cap: number);
|
|
29
|
+
}
|
|
30
|
+
export declare class MalformedJsonError extends Error {
|
|
31
|
+
constructor(m?: string);
|
|
32
|
+
}
|
|
33
|
+
export declare class CostTracker {
|
|
34
|
+
private readonly cap;
|
|
35
|
+
private running;
|
|
36
|
+
constructor(cap?: number);
|
|
37
|
+
assertCanAfford(estimatedCost: number): void;
|
|
38
|
+
recordActual(cost: number): void;
|
|
39
|
+
getTotal(): number;
|
|
40
|
+
}
|
|
41
|
+
/** CQ14: ONLY site that reads provider env keys (returns env-var NAME). */
|
|
42
|
+
export declare function resolveCredentialsForModel(modelId: string): string | null;
|
|
43
|
+
export declare class AnthropicJournalProvider implements JournalLlmProvider {
|
|
44
|
+
private readonly apiKey?;
|
|
45
|
+
constructor(apiKey?: string | undefined);
|
|
46
|
+
generate(prompt: string, opts: GenerateOptions): Promise<LlmResult>;
|
|
47
|
+
}
|
|
48
|
+
export declare class OpenAiJournalProvider implements JournalLlmProvider {
|
|
49
|
+
private readonly apiKey?;
|
|
50
|
+
constructor(apiKey?: string | undefined);
|
|
51
|
+
generate(prompt: string, opts: GenerateOptions): Promise<LlmResult>;
|
|
52
|
+
}
|
|
53
|
+
export declare class ScaffoldFallbackProvider implements JournalLlmProvider {
|
|
54
|
+
generate(_prompt: string, _opts: GenerateOptions): Promise<LlmResult>;
|
|
55
|
+
}
|
|
56
|
+
export declare function selectProvider(): JournalLlmProvider;
|
|
57
|
+
//# sourceMappingURL=journal-llm-client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"journal-llm-client.d.ts","sourceRoot":"","sources":["../../src/tools/journal-llm-client.ts"],"names":[],"mappings":"AAOA,eAAO,MAAM,cAAc,QAAS,CAAC;AACrC,eAAO,MAAM,eAAe,IAAI,CAAC;AACjC,eAAO,MAAM,oBAAoB,IAAM,CAAC;AAExC,eAAO,MAAM,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAOzE,CAAC;AAEJ,MAAM,WAAW,SAAS;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,WAAW,GAAG,QAAQ,GAAG,UAAU,CAAC;CAC/C;AAED,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,8EAA8E;IAC9E,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC;CACxE;AAED,qBAAa,oBAAqB,SAAQ,KAAK;IAC7C,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;gBACT,WAAW,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM;CAM7C;AAED,qBAAa,kBAAmB,SAAQ,KAAK;gBAC/B,CAAC,SAA8C;CAC5D;AAED,qBAAa,WAAW;IAEV,OAAO,CAAC,QAAQ,CAAC,GAAG;IADhC,OAAO,CAAC,OAAO,CAAK;gBACS,GAAG,GAAE,MAA6B;IAC/D,eAAe,CAAC,aAAa,EAAE,MAAM,GAAG,IAAI;IAG5C,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAChC,QAAQ,IAAI,MAAM;CACnB;AAED,2EAA2E;AAC3E,wBAAgB,0BAA0B,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAIzE;AAkDD,qBAAa,wBAAyB,YAAW,kBAAkB;IACrD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC;gBAAP,MAAM,CAAC,EAAE,MAAM,YAAA;IACtC,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,eAAe,GAAG,OAAO,CAAC,SAAS,CAAC;CA4B1E;AAED,qBAAa,qBAAsB,YAAW,kBAAkB;IAClD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC;gBAAP,MAAM,CAAC,EAAE,MAAM,YAAA;IACtC,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,eAAe,GAAG,OAAO,CAAC,SAAS,CAAC;CA0B1E;AAED,qBAAa,wBAAyB,YAAW,kBAAkB;IAC3D,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,eAAe,GAAG,OAAO,CAAC,SAAS,CAAC;CAM5E;AAED,wBAAgB,cAAc,IAAI,kBAAkB,CAQnD"}
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
// LLM client for the wiki journal generator.
|
|
2
|
+
// CQ14: env credentials are read ONLY inside resolveCredentialsForModel +
|
|
3
|
+
// readCredentialValue (helper invoked by selectProvider). Providers
|
|
4
|
+
// receive the key via their constructor — they do not touch process.env.
|
|
5
|
+
// CQ8: external calls wrapped in timeout + typed errors.
|
|
6
|
+
// CQ12: SDKs imported dynamically via await import() to keep them optional.
|
|
7
|
+
export const LLM_TIMEOUT_MS = 30_000;
|
|
8
|
+
export const LLM_MAX_RETRIES = 2;
|
|
9
|
+
export const DEFAULT_MAX_COST_USD = 2.0;
|
|
10
|
+
export const MODEL_PRICING = {
|
|
11
|
+
"claude-opus-4-7": { input: 15.0, output: 75.0 },
|
|
12
|
+
"claude-sonnet-4-6": { input: 3.0, output: 15.0 },
|
|
13
|
+
"claude-haiku-4-5": { input: 0.8, output: 4.0 },
|
|
14
|
+
"gpt-4o": { input: 2.5, output: 10.0 },
|
|
15
|
+
"gpt-4o-mini": { input: 0.15, output: 0.6 },
|
|
16
|
+
};
|
|
17
|
+
export class CostCapExceededError extends Error {
|
|
18
|
+
runningCost;
|
|
19
|
+
cap;
|
|
20
|
+
constructor(runningCost, cap) {
|
|
21
|
+
super(`Cost cap exceeded: running=$${runningCost.toFixed(4)} cap=$${cap.toFixed(2)}`);
|
|
22
|
+
this.name = "CostCapExceededError";
|
|
23
|
+
this.runningCost = runningCost;
|
|
24
|
+
this.cap = cap;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
export class MalformedJsonError extends Error {
|
|
28
|
+
constructor(m = "LLM returned non-JSON content after retry") { super(m); this.name = "MalformedJsonError"; }
|
|
29
|
+
}
|
|
30
|
+
export class CostTracker {
|
|
31
|
+
cap;
|
|
32
|
+
running = 0;
|
|
33
|
+
constructor(cap = DEFAULT_MAX_COST_USD) {
|
|
34
|
+
this.cap = cap;
|
|
35
|
+
}
|
|
36
|
+
assertCanAfford(estimatedCost) {
|
|
37
|
+
if (this.running + estimatedCost > this.cap)
|
|
38
|
+
throw new CostCapExceededError(this.running, this.cap);
|
|
39
|
+
}
|
|
40
|
+
recordActual(cost) { this.running += cost; }
|
|
41
|
+
getTotal() { return this.running; }
|
|
42
|
+
}
|
|
43
|
+
/** CQ14: ONLY site that reads provider env keys (returns env-var NAME). */
|
|
44
|
+
export function resolveCredentialsForModel(modelId) {
|
|
45
|
+
if (modelId.startsWith("claude-"))
|
|
46
|
+
return process.env.ANTHROPIC_API_KEY ? "ANTHROPIC_API_KEY" : null;
|
|
47
|
+
if (modelId.startsWith("gpt-"))
|
|
48
|
+
return process.env.OPENAI_API_KEY ? "OPENAI_API_KEY" : null;
|
|
49
|
+
return null;
|
|
50
|
+
}
|
|
51
|
+
/** Internal helper — reads the actual value for a credential name resolved above. */
|
|
52
|
+
function readCredentialValue(name) {
|
|
53
|
+
return process.env[name];
|
|
54
|
+
}
|
|
55
|
+
function computeCost(model, tIn, tOut) {
|
|
56
|
+
const p = MODEL_PRICING[model];
|
|
57
|
+
if (!p)
|
|
58
|
+
throw new Error(`No pricing for model "${model}"; refusing to estimate cost (cap-safety)`);
|
|
59
|
+
return tIn * 1e-6 * p.input + tOut * 1e-6 * p.output;
|
|
60
|
+
}
|
|
61
|
+
function withTimeout(p, ms) {
|
|
62
|
+
return new Promise((resolve, reject) => {
|
|
63
|
+
const h = setTimeout(() => reject(new Error(`LLM request timed out after ${ms}ms`)), ms);
|
|
64
|
+
p.then((v) => { clearTimeout(h); resolve(v); }, (e) => { clearTimeout(h); reject(e); });
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
|
|
68
|
+
const isRetryable = (s) => s === 500 || s === 503 || s === 504;
|
|
69
|
+
async function callWithRetry(op) {
|
|
70
|
+
let lastErr;
|
|
71
|
+
for (let attempt = 0; attempt <= LLM_MAX_RETRIES; attempt++) {
|
|
72
|
+
try {
|
|
73
|
+
return await withTimeout(op(), LLM_TIMEOUT_MS);
|
|
74
|
+
}
|
|
75
|
+
catch (err) {
|
|
76
|
+
lastErr = err;
|
|
77
|
+
const status = err.status;
|
|
78
|
+
if (!isRetryable(status) || attempt === LLM_MAX_RETRIES)
|
|
79
|
+
throw err;
|
|
80
|
+
await sleep(1000 * Math.pow(2, attempt));
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
throw lastErr;
|
|
84
|
+
}
|
|
85
|
+
const isJsonParseable = (t) => { try {
|
|
86
|
+
JSON.parse(t);
|
|
87
|
+
return true;
|
|
88
|
+
}
|
|
89
|
+
catch {
|
|
90
|
+
return false;
|
|
91
|
+
} };
|
|
92
|
+
async function withJsonRetry(opts, doOnce) {
|
|
93
|
+
const first = await doOnce();
|
|
94
|
+
if (!opts.parseJson || isJsonParseable(first.content))
|
|
95
|
+
return first;
|
|
96
|
+
const second = await doOnce();
|
|
97
|
+
if (!isJsonParseable(second.content))
|
|
98
|
+
throw new MalformedJsonError();
|
|
99
|
+
return second;
|
|
100
|
+
}
|
|
101
|
+
export class AnthropicJournalProvider {
|
|
102
|
+
apiKey;
|
|
103
|
+
constructor(apiKey) {
|
|
104
|
+
this.apiKey = apiKey;
|
|
105
|
+
}
|
|
106
|
+
async generate(prompt, opts) {
|
|
107
|
+
const mod = (await import("@anthropic-ai/sdk"));
|
|
108
|
+
const client = new mod.default({ apiKey: this.apiKey });
|
|
109
|
+
const body = {
|
|
110
|
+
model: opts.model,
|
|
111
|
+
max_tokens: opts.maxTokens ?? 4096,
|
|
112
|
+
messages: [{ role: "user", content: prompt }],
|
|
113
|
+
};
|
|
114
|
+
if (opts.systemPrompt)
|
|
115
|
+
body["system"] = opts.systemPrompt;
|
|
116
|
+
const doOnce = async () => {
|
|
117
|
+
const resp = await callWithRetry(() => client.messages.create(body));
|
|
118
|
+
const tIn = resp.usage.input_tokens, tOut = resp.usage.output_tokens;
|
|
119
|
+
return {
|
|
120
|
+
content: resp.content[0]?.text ?? "",
|
|
121
|
+
tokensInput: tIn, tokensOutput: tOut,
|
|
122
|
+
costUsd: computeCost(opts.model, tIn, tOut),
|
|
123
|
+
provider: "anthropic",
|
|
124
|
+
};
|
|
125
|
+
};
|
|
126
|
+
return withJsonRetry(opts, doOnce);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
export class OpenAiJournalProvider {
|
|
130
|
+
apiKey;
|
|
131
|
+
constructor(apiKey) {
|
|
132
|
+
this.apiKey = apiKey;
|
|
133
|
+
}
|
|
134
|
+
async generate(prompt, opts) {
|
|
135
|
+
const mod = (await import("openai"));
|
|
136
|
+
const client = new mod.default({ apiKey: this.apiKey });
|
|
137
|
+
const msgs = [];
|
|
138
|
+
if (opts.systemPrompt)
|
|
139
|
+
msgs.push({ role: "system", content: opts.systemPrompt });
|
|
140
|
+
msgs.push({ role: "user", content: prompt });
|
|
141
|
+
const body = { model: opts.model, messages: msgs, max_tokens: opts.maxTokens ?? 4096 };
|
|
142
|
+
const doOnce = async () => {
|
|
143
|
+
const resp = await callWithRetry(() => client.chat.completions.create(body));
|
|
144
|
+
const tIn = resp.usage.prompt_tokens, tOut = resp.usage.completion_tokens;
|
|
145
|
+
return {
|
|
146
|
+
content: resp.choices[0]?.message?.content ?? "",
|
|
147
|
+
tokensInput: tIn, tokensOutput: tOut,
|
|
148
|
+
costUsd: computeCost(opts.model, tIn, tOut),
|
|
149
|
+
provider: "openai",
|
|
150
|
+
};
|
|
151
|
+
};
|
|
152
|
+
return withJsonRetry(opts, doOnce);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
export class ScaffoldFallbackProvider {
|
|
156
|
+
async generate(_prompt, _opts) {
|
|
157
|
+
return {
|
|
158
|
+
content: JSON.stringify({ summary: "TODO: fill in summary", highlights: [], risks: [] }),
|
|
159
|
+
tokensInput: 0, tokensOutput: 0, costUsd: 0, provider: "scaffold",
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
export function selectProvider() {
|
|
164
|
+
const model = process.env["CODESIFT_JOURNAL_MODEL"] ?? "claude-sonnet-4-6";
|
|
165
|
+
const cred = resolveCredentialsForModel(model);
|
|
166
|
+
if (!cred)
|
|
167
|
+
return new ScaffoldFallbackProvider();
|
|
168
|
+
const value = readCredentialValue(cred);
|
|
169
|
+
if (cred === "ANTHROPIC_API_KEY")
|
|
170
|
+
return new AnthropicJournalProvider(value);
|
|
171
|
+
if (cred === "OPENAI_API_KEY")
|
|
172
|
+
return new OpenAiJournalProvider(value);
|
|
173
|
+
return new ScaffoldFallbackProvider();
|
|
174
|
+
}
|
|
175
|
+
//# sourceMappingURL=journal-llm-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"journal-llm-client.js","sourceRoot":"","sources":["../../src/tools/journal-llm-client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export declare class NoPhasesError extends Error {
|
|
2
|
+
constructor();
|
|
3
|
+
}
|
|
4
|
+
export declare class SlugCollisionError extends Error {
|
|
5
|
+
constructor(slug: string);
|
|
6
|
+
}
|
|
7
|
+
export declare class SourceDriftError extends Error {
|
|
8
|
+
constructor(newSha: string, recordedSha: string);
|
|
9
|
+
}
|
|
10
|
+
export interface MigrateOptions {
|
|
11
|
+
source: string;
|
|
12
|
+
repoRoot: string;
|
|
13
|
+
outputDir: string;
|
|
14
|
+
dryRun: boolean;
|
|
15
|
+
}
|
|
16
|
+
export interface MigrateResult {
|
|
17
|
+
status: "planned" | "ok" | "aborted";
|
|
18
|
+
phaseCount: number;
|
|
19
|
+
reason?: string;
|
|
20
|
+
}
|
|
21
|
+
export declare function runMigrate(opts: MigrateOptions): Promise<MigrateResult>;
|
|
22
|
+
//# sourceMappingURL=journal-migrator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"journal-migrator.d.ts","sourceRoot":"","sources":["../../src/tools/journal-migrator.ts"],"names":[],"mappings":"AAUA,qBAAa,aAAc,SAAQ,KAAK;;CAEvC;AACD,qBAAa,kBAAmB,SAAQ,KAAK;gBAC/B,IAAI,EAAE,MAAM;CAIzB;AACD,qBAAa,gBAAiB,SAAQ,KAAK;gBAC7B,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM;CAIhD;AAED,MAAM,WAAW,cAAc;IAAG,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,OAAO,CAAA;CAAE;AACxG,MAAM,WAAW,aAAa;IAAG,MAAM,EAAE,SAAS,GAAG,IAAI,GAAG,SAAS,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE;AAgH5G,wBAAsB,UAAU,CAAC,IAAI,EAAE,cAAc,GAAG,OAAO,CAAC,aAAa,CAAC,CA0D7E"}
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
import { readFile, writeFile, copyFile, mkdir } from "node:fs/promises";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
import { computeBlockHash } from "./journal-sentinel.js";
|
|
5
|
+
import { buildJournalManifestEntries, mergeJournalIntoManifest, renderJournalSectionMd, insertJournalSectionIntoIndex, readManifestIfExists, } from "./journal-generator-helpers.js";
|
|
6
|
+
// Typed errors (CQ8)
|
|
7
|
+
export class NoPhasesError extends Error {
|
|
8
|
+
constructor() { super("no `### Week` headings found in source; NoPhasesError"); this.name = "NoPhasesError"; }
|
|
9
|
+
}
|
|
10
|
+
export class SlugCollisionError extends Error {
|
|
11
|
+
constructor(slug) {
|
|
12
|
+
super(`slug collision: two weeks resolve to "${slug}". Disambiguate titles or date ranges. SlugCollisionError`);
|
|
13
|
+
this.name = "SlugCollisionError";
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
export class SourceDriftError extends Error {
|
|
17
|
+
constructor(newSha, recordedSha) {
|
|
18
|
+
super(`source file changed since dry-run (sha ${newSha} ≠ ${recordedSha}), aborting`);
|
|
19
|
+
this.name = "SourceDriftError";
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
// Constants + path helpers (CQ14 single-site path construction)
|
|
23
|
+
const SCHEMA_VERSION = "1";
|
|
24
|
+
const GITIGNORE_ENTRY_REL = ".codesift/wiki/journal/.migrate-state.json";
|
|
25
|
+
const NO_PLAN_MSG = "No migration plan found. Run 'codesift journal migrate --dry-run' first to generate a migration plan, then run without --dry-run to execute.";
|
|
26
|
+
const journalDir = (outputDir) => join(outputDir, "journal");
|
|
27
|
+
const phasesDir = (outputDir) => join(journalDir(outputDir), "phases");
|
|
28
|
+
const phasePath = (outputDir, slug) => join(phasesDir(outputDir), `${slug}.md`);
|
|
29
|
+
const overviewPath = (outputDir) => join(journalDir(outputDir), "overview.md");
|
|
30
|
+
const statePath = (outputDir) => join(journalDir(outputDir), ".migrate-state.json");
|
|
31
|
+
const gitignorePath = (repoRoot) => join(repoRoot, ".gitignore");
|
|
32
|
+
const RE_H2 = /^## (.+)$/;
|
|
33
|
+
const RE_TIMELINE = /^## Timeline\s*$/;
|
|
34
|
+
const RE_WEEK = /^### Week (\d+) — (.+)$/;
|
|
35
|
+
const RE_ENTRY_SINGLE = /^#### (\d{4}-\d{2}-\d{2}) — /;
|
|
36
|
+
const RE_ENTRY_RANGE = /^#### (\d{4}-\d{2}-\d{2}) [–-] (\d{4}-\d{2}-\d{2}) — /;
|
|
37
|
+
function parse(source) {
|
|
38
|
+
const lines = source.replace(/\r\n/g, "\n").split("\n");
|
|
39
|
+
const weeks = [];
|
|
40
|
+
const overviewSections = [];
|
|
41
|
+
let mode = { kind: "none" };
|
|
42
|
+
for (const line of lines) {
|
|
43
|
+
if (RE_TIMELINE.test(line)) {
|
|
44
|
+
mode = { kind: "none" };
|
|
45
|
+
continue;
|
|
46
|
+
}
|
|
47
|
+
const weekMatch = RE_WEEK.exec(line);
|
|
48
|
+
if (weekMatch) {
|
|
49
|
+
const week = { headingLine: line, title: weekMatch[2], entries: [], preamble: [] };
|
|
50
|
+
weeks.push(week);
|
|
51
|
+
mode = { kind: "week", week, currentEntry: null };
|
|
52
|
+
continue;
|
|
53
|
+
}
|
|
54
|
+
if (RE_H2.test(line)) { // Any ## heading ends week/overview mode and starts a new overview section.
|
|
55
|
+
const sec = { headingLine: line, bodyLines: [] };
|
|
56
|
+
overviewSections.push(sec);
|
|
57
|
+
mode = { kind: "overview", sec };
|
|
58
|
+
continue;
|
|
59
|
+
}
|
|
60
|
+
if (mode.kind === "week") {
|
|
61
|
+
const rangeMatch = RE_ENTRY_RANGE.exec(line);
|
|
62
|
+
const singleMatch = rangeMatch ? null : RE_ENTRY_SINGLE.exec(line);
|
|
63
|
+
if (rangeMatch || singleMatch) {
|
|
64
|
+
const startDate = (rangeMatch ? rangeMatch[1] : singleMatch[1]);
|
|
65
|
+
const entry = { startDate, titleLine: line, bodyLines: [] };
|
|
66
|
+
mode.week.entries.push(entry);
|
|
67
|
+
mode.currentEntry = entry;
|
|
68
|
+
continue;
|
|
69
|
+
}
|
|
70
|
+
if (mode.currentEntry)
|
|
71
|
+
mode.currentEntry.bodyLines.push(line);
|
|
72
|
+
else
|
|
73
|
+
mode.week.preamble.push(line);
|
|
74
|
+
}
|
|
75
|
+
else if (mode.kind === "overview") {
|
|
76
|
+
mode.sec.bodyLines.push(line);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
return { weeks, overviewSections };
|
|
80
|
+
}
|
|
81
|
+
const slugifyTitle = (title) => title.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
|
|
82
|
+
const deriveSlug = (week) => {
|
|
83
|
+
const month = week.entries[0]?.startDate.slice(0, 7) ?? "0000-00";
|
|
84
|
+
return `${month}-${slugifyTitle(week.title)}`;
|
|
85
|
+
};
|
|
86
|
+
function renderPhaseFile(week) {
|
|
87
|
+
const lines = [
|
|
88
|
+
`## ${week.title}`, "",
|
|
89
|
+
"<!-- auto:begin phase-summary -->",
|
|
90
|
+
"<!-- TODO: generate phase summary via `codesift journal init` -->",
|
|
91
|
+
"<!-- auto:end phase-summary -->",
|
|
92
|
+
"", "## My notes", week.headingLine, ...week.preamble,
|
|
93
|
+
];
|
|
94
|
+
for (const entry of week.entries)
|
|
95
|
+
lines.push(entry.titleLine, ...entry.bodyLines);
|
|
96
|
+
return lines.join("\n").replace(/\n+$/, "\n");
|
|
97
|
+
}
|
|
98
|
+
function renderOverviewFile(sections) {
|
|
99
|
+
const lines = ["# Overview", "", "<!-- manual:begin migrated-overview -->"];
|
|
100
|
+
for (const sec of sections)
|
|
101
|
+
lines.push(sec.headingLine, ...sec.bodyLines);
|
|
102
|
+
lines.push("<!-- manual:end migrated-overview -->", "");
|
|
103
|
+
return lines.join("\n");
|
|
104
|
+
}
|
|
105
|
+
const sha256 = (s) => createHash("sha256").update(s).digest("hex");
|
|
106
|
+
async function ensureGitignoreEntry(repoRoot, entry) {
|
|
107
|
+
const path = gitignorePath(repoRoot);
|
|
108
|
+
try {
|
|
109
|
+
const existing = await readFile(path, "utf-8").catch(() => "");
|
|
110
|
+
if (existing.split("\n").includes(entry))
|
|
111
|
+
return;
|
|
112
|
+
const suffix = existing && !existing.endsWith("\n") ? "\n" : "";
|
|
113
|
+
await writeFile(path, existing + suffix + entry + "\n", "utf-8");
|
|
114
|
+
}
|
|
115
|
+
catch (err) {
|
|
116
|
+
console.warn(`WARN journal: could not update .gitignore (${err.message}); add ${entry} manually.`);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
export async function runMigrate(opts) {
|
|
120
|
+
const { source, repoRoot, outputDir, dryRun } = opts;
|
|
121
|
+
const sourceContent = await readFile(source, "utf-8");
|
|
122
|
+
const parsed = parse(sourceContent);
|
|
123
|
+
if (parsed.weeks.length === 0)
|
|
124
|
+
throw new NoPhasesError();
|
|
125
|
+
const slugs = parsed.weeks.map(deriveSlug);
|
|
126
|
+
const seen = new Set();
|
|
127
|
+
for (const s of slugs) {
|
|
128
|
+
if (seen.has(s))
|
|
129
|
+
throw new SlugCollisionError(s);
|
|
130
|
+
seen.add(s);
|
|
131
|
+
}
|
|
132
|
+
const sourceSha = sha256(sourceContent);
|
|
133
|
+
await mkdir(journalDir(outputDir), { recursive: true });
|
|
134
|
+
if (dryRun) {
|
|
135
|
+
const state = { source_sha256: sourceSha, planned_phase_slugs: slugs, schema_version: SCHEMA_VERSION };
|
|
136
|
+
await writeFile(statePath(outputDir), JSON.stringify(state, null, 2), "utf-8");
|
|
137
|
+
await ensureGitignoreEntry(repoRoot, GITIGNORE_ENTRY_REL);
|
|
138
|
+
return { status: "planned", phaseCount: parsed.weeks.length };
|
|
139
|
+
}
|
|
140
|
+
// Live run: require plan, validate SHA.
|
|
141
|
+
let stateRaw;
|
|
142
|
+
try {
|
|
143
|
+
stateRaw = await readFile(statePath(outputDir), "utf-8");
|
|
144
|
+
}
|
|
145
|
+
catch {
|
|
146
|
+
throw new Error(NO_PLAN_MSG);
|
|
147
|
+
}
|
|
148
|
+
const state = JSON.parse(stateRaw);
|
|
149
|
+
if (state.source_sha256 !== sourceSha)
|
|
150
|
+
throw new SourceDriftError(sourceSha, state.source_sha256);
|
|
151
|
+
// .bak MUST precede any phase writes (test i).
|
|
152
|
+
await copyFile(source, source + ".bak");
|
|
153
|
+
await mkdir(phasesDir(outputDir), { recursive: true });
|
|
154
|
+
const wx = { encoding: "utf-8", flag: "wx" }; // no-clobber; hand-edits require .bak rollback
|
|
155
|
+
const phaseWrites = [];
|
|
156
|
+
const scaffoldHash = computeBlockHash("\n<!-- TODO: generate phase summary via `codesift journal init` -->\n");
|
|
157
|
+
for (let i = 0; i < parsed.weeks.length; i++) {
|
|
158
|
+
const slug = slugs[i];
|
|
159
|
+
await writeFile(phasePath(outputDir, slug), renderPhaseFile(parsed.weeks[i]), wx);
|
|
160
|
+
phaseWrites.push({ slug, title: parsed.weeks[i].title, file: `journal/phases/${slug}.md`, hash: scaffoldHash });
|
|
161
|
+
}
|
|
162
|
+
await writeFile(overviewPath(outputDir), renderOverviewFile(parsed.overviewSections), wx);
|
|
163
|
+
// Register journal pages in wiki-manifest.json + index.md (best-effort, CQ8).
|
|
164
|
+
const manifestPath = join(outputDir, "wiki-manifest.json");
|
|
165
|
+
const indexPath = join(outputDir, "index.md");
|
|
166
|
+
const entries = buildJournalManifestEntries(phaseWrites, true); // migrator always writes overview.md
|
|
167
|
+
try {
|
|
168
|
+
const merged = mergeJournalIntoManifest(await readManifestIfExists(manifestPath), entries);
|
|
169
|
+
await writeFile(manifestPath, JSON.stringify(merged, null, 2), "utf-8");
|
|
170
|
+
try {
|
|
171
|
+
const existing = await readFile(indexPath, "utf-8").catch(() => "");
|
|
172
|
+
await writeFile(indexPath, insertJournalSectionIntoIndex(existing, renderJournalSectionMd(entries)), "utf-8");
|
|
173
|
+
}
|
|
174
|
+
catch (err) {
|
|
175
|
+
console.warn(`WARN journal: could not update index.md (${err.message})`);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
catch (err) {
|
|
179
|
+
console.warn(`WARN journal: could not update wiki-manifest.json (${err.message})`);
|
|
180
|
+
}
|
|
181
|
+
return { status: "ok", phaseCount: parsed.weeks.length };
|
|
182
|
+
}
|
|
183
|
+
//# sourceMappingURL=journal-migrator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"journal-migrator.js","sourceRoot":"","sources":["../../src/tools/journal-migrator.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { GitCommit } from "./journal-git-client.js";
|
|
2
|
+
export interface PhaseOverride {
|
|
3
|
+
date: string;
|
|
4
|
+
slug: string;
|
|
5
|
+
title: string;
|
|
6
|
+
}
|
|
7
|
+
export interface PhasePlan {
|
|
8
|
+
slug: string;
|
|
9
|
+
title: string;
|
|
10
|
+
startDate: string;
|
|
11
|
+
endDate: string;
|
|
12
|
+
commits: GitCommit[];
|
|
13
|
+
source: "auto" | "manual";
|
|
14
|
+
}
|
|
15
|
+
export declare class PhaseOverridesParseError extends Error {
|
|
16
|
+
readonly line: number;
|
|
17
|
+
constructor(message: string, line: number);
|
|
18
|
+
}
|
|
19
|
+
export interface DetectPhasesOptions {
|
|
20
|
+
/** Drop auto-titled "unclassified" phases with fewer than N commits (default 0 = keep all).
|
|
21
|
+
* Manual phases and named auto phases are never dropped. */
|
|
22
|
+
minUnclassifiedCommits?: number;
|
|
23
|
+
}
|
|
24
|
+
export declare function detectPhases(commits: GitCommit[], overrides?: PhaseOverride[], options?: DetectPhasesOptions): PhasePlan[];
|
|
25
|
+
export declare function parsePhaseOverridesYAML(raw: string): PhaseOverride[];
|
|
26
|
+
//# sourceMappingURL=journal-phase-detector.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"journal-phase-detector.d.ts","sourceRoot":"","sources":["../../src/tools/journal-phase-detector.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AAEzD,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,SAAS,EAAE,CAAC;IACrB,MAAM,EAAE,MAAM,GAAG,QAAQ,CAAC;CAC3B;AAED,qBAAa,wBAAyB,SAAQ,KAAK;IACjD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;gBACV,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM;CAK1C;AA6BD,MAAM,WAAW,mBAAmB;IAClC;iEAC6D;IAC7D,sBAAsB,CAAC,EAAE,MAAM,CAAC;CACjC;AAED,wBAAgB,YAAY,CAC1B,OAAO,EAAE,SAAS,EAAE,EACpB,SAAS,CAAC,EAAE,aAAa,EAAE,EAC3B,OAAO,CAAC,EAAE,mBAAmB,GAC5B,SAAS,EAAE,CAgDb;AAID,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,MAAM,GAAG,aAAa,EAAE,CA8CpE"}
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
export class PhaseOverridesParseError extends Error {
|
|
2
|
+
line;
|
|
3
|
+
constructor(message, line) {
|
|
4
|
+
super(`${message} (line ${line})`);
|
|
5
|
+
this.name = "PhaseOverridesParseError";
|
|
6
|
+
this.line = line;
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
// Helpers
|
|
10
|
+
const TAG_REF_RE = /^tag:\s*v?\d/;
|
|
11
|
+
const SCOPE_RE = /^(?:feat|refactor|docs|fix)\(([^)]+)\)/;
|
|
12
|
+
const MS_PER_DAY = 86_400_000;
|
|
13
|
+
const isoDay = (s) => s.slice(0, 10);
|
|
14
|
+
const gapDays = (a, b) => (Date.parse(isoDay(b)) - Date.parse(isoDay(a))) / MS_PER_DAY;
|
|
15
|
+
const slugify = (t) => t.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
|
|
16
|
+
function titleFrom(commits) {
|
|
17
|
+
for (const c of commits) {
|
|
18
|
+
const m = SCOPE_RE.exec(c.subject);
|
|
19
|
+
if (m?.[1])
|
|
20
|
+
return m[1];
|
|
21
|
+
}
|
|
22
|
+
return "unclassified";
|
|
23
|
+
}
|
|
24
|
+
function makePlan(commits, source, slug, title) {
|
|
25
|
+
const t = title ?? titleFrom(commits);
|
|
26
|
+
const days = commits.map((c) => isoDay(c.date)).sort();
|
|
27
|
+
return { slug: slug ?? slugify(t), title: t, startDate: days[0] ?? "", endDate: days[days.length - 1] ?? "", commits, source };
|
|
28
|
+
}
|
|
29
|
+
function dedupSlugs(plans) {
|
|
30
|
+
const seen = new Map();
|
|
31
|
+
return plans.map((p) => { const n = seen.get(p.slug) ?? 0; seen.set(p.slug, n + 1); return n === 0 ? p : { ...p, slug: `${p.slug}-${n + 1}` }; });
|
|
32
|
+
}
|
|
33
|
+
export function detectPhases(commits, overrides, options) {
|
|
34
|
+
if (commits.length === 0)
|
|
35
|
+
return [];
|
|
36
|
+
const sorted = [...commits].sort((a, b) => Date.parse(a.date) - Date.parse(b.date));
|
|
37
|
+
const ovMap = new Map();
|
|
38
|
+
for (const ov of overrides ?? [])
|
|
39
|
+
ovMap.set(ov.date, ov);
|
|
40
|
+
const groups = [];
|
|
41
|
+
let cur = [];
|
|
42
|
+
for (let i = 0; i < sorted.length; i++) {
|
|
43
|
+
const c = sorted[i];
|
|
44
|
+
const prev = sorted[i - 1];
|
|
45
|
+
const day = isoDay(c.date);
|
|
46
|
+
// Boundary BEFORE this commit: override date or >2-day gap
|
|
47
|
+
if (cur.length > 0 && (ovMap.has(day) || (prev !== undefined && gapDays(prev.date, c.date) > 2))) {
|
|
48
|
+
groups.push(cur);
|
|
49
|
+
cur = [];
|
|
50
|
+
}
|
|
51
|
+
cur.push(c);
|
|
52
|
+
// Boundary AFTER this commit: merge or tag (next commit starts new group)
|
|
53
|
+
const isMerge = c.parentShas.length >= 2;
|
|
54
|
+
const isTagged = c.refs.some((r) => TAG_REF_RE.test(r));
|
|
55
|
+
if ((isMerge || isTagged) && i < sorted.length - 1) {
|
|
56
|
+
groups.push(cur);
|
|
57
|
+
cur = [];
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
if (cur.length > 0)
|
|
61
|
+
groups.push(cur);
|
|
62
|
+
const plans = groups.map((grp) => {
|
|
63
|
+
for (const c of grp) {
|
|
64
|
+
const ov = ovMap.get(isoDay(c.date));
|
|
65
|
+
if (ov !== undefined)
|
|
66
|
+
return makePlan(grp, "manual", ov.slug, ov.title);
|
|
67
|
+
}
|
|
68
|
+
return makePlan(grp, "auto");
|
|
69
|
+
});
|
|
70
|
+
const minUnclassified = options?.minUnclassifiedCommits ?? 0;
|
|
71
|
+
const filtered = minUnclassified > 0
|
|
72
|
+
? plans.filter((p) => p.source !== "auto" || p.title !== "unclassified" || p.commits.length >= minUnclassified)
|
|
73
|
+
: plans;
|
|
74
|
+
return dedupSlugs(filtered);
|
|
75
|
+
}
|
|
76
|
+
// parsePhaseOverridesYAML — inline parser (no yaml dep required)
|
|
77
|
+
export function parsePhaseOverridesYAML(raw) {
|
|
78
|
+
const lines = raw.split("\n");
|
|
79
|
+
const result = [];
|
|
80
|
+
let cur = null;
|
|
81
|
+
const flush = (lineNum) => {
|
|
82
|
+
if (cur === null)
|
|
83
|
+
return;
|
|
84
|
+
if (!cur.date || !cur.slug || !cur.title) {
|
|
85
|
+
throw new PhaseOverridesParseError("incomplete override entry", lineNum);
|
|
86
|
+
}
|
|
87
|
+
result.push(cur);
|
|
88
|
+
cur = null;
|
|
89
|
+
};
|
|
90
|
+
const setKV = (kv, lineNum) => {
|
|
91
|
+
const idx = kv.indexOf(":");
|
|
92
|
+
if (idx === -1)
|
|
93
|
+
throw new PhaseOverridesParseError("expected 'key: value'", lineNum);
|
|
94
|
+
const key = kv.slice(0, idx).trim();
|
|
95
|
+
const val = kv.slice(idx + 1).trim();
|
|
96
|
+
if (!key)
|
|
97
|
+
throw new PhaseOverridesParseError("invalid key format", lineNum);
|
|
98
|
+
cur[key] = val;
|
|
99
|
+
};
|
|
100
|
+
for (let i = 0; i < lines.length; i++) {
|
|
101
|
+
const lineNum = i + 1;
|
|
102
|
+
const line = lines[i];
|
|
103
|
+
if (line.trim() === "")
|
|
104
|
+
continue;
|
|
105
|
+
if (line.startsWith("- ")) {
|
|
106
|
+
flush(lineNum);
|
|
107
|
+
cur = {};
|
|
108
|
+
setKV(line.slice(2), lineNum);
|
|
109
|
+
}
|
|
110
|
+
else if (line.startsWith(" ")) {
|
|
111
|
+
if (cur === null)
|
|
112
|
+
throw new PhaseOverridesParseError("unexpected indented line", lineNum);
|
|
113
|
+
const trimmed = line.trimStart();
|
|
114
|
+
if (!/^[a-zA-Z]/.test(trimmed)) {
|
|
115
|
+
throw new PhaseOverridesParseError("invalid key format", lineNum);
|
|
116
|
+
}
|
|
117
|
+
setKV(trimmed, lineNum);
|
|
118
|
+
}
|
|
119
|
+
else {
|
|
120
|
+
throw new PhaseOverridesParseError("unexpected line format", lineNum);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
flush(lines.length);
|
|
124
|
+
return result;
|
|
125
|
+
}
|
|
126
|
+
//# sourceMappingURL=journal-phase-detector.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"journal-phase-detector.js","sourceRoot":"","sources":["../../src/tools/journal-phase-detector.ts"],"names":[],"mappings":"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"}
|