@equinor/fusion-framework-cli-plugin-ai-index 1.0.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/CHANGELOG.md +63 -0
- package/LICENSE +21 -0
- package/README.md +114 -0
- package/dist/esm/bin/apply-metadata.js +63 -0
- package/dist/esm/bin/apply-metadata.js.map +1 -0
- package/dist/esm/bin/delete-removed-files.js +36 -0
- package/dist/esm/bin/delete-removed-files.js.map +1 -0
- package/dist/esm/bin/embed.js +196 -0
- package/dist/esm/bin/embed.js.map +1 -0
- package/dist/esm/bin/execute-pipeline.js +40 -0
- package/dist/esm/bin/execute-pipeline.js.map +1 -0
- package/dist/esm/bin/file-stream.js +22 -0
- package/dist/esm/bin/file-stream.js.map +1 -0
- package/dist/esm/bin/get-diff.js +29 -0
- package/dist/esm/bin/get-diff.js.map +1 -0
- package/dist/esm/bin/index.js +2 -0
- package/dist/esm/bin/index.js.map +1 -0
- package/dist/esm/bin/types.js +2 -0
- package/dist/esm/bin/types.js.map +1 -0
- package/dist/esm/command.js +82 -0
- package/dist/esm/command.js.map +1 -0
- package/dist/esm/command.options.js +48 -0
- package/dist/esm/command.options.js.map +1 -0
- package/dist/esm/config.js +2 -0
- package/dist/esm/config.js.map +1 -0
- package/dist/esm/index.js +13 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/utils/generate-chunk-id.js +18 -0
- package/dist/esm/utils/generate-chunk-id.js.map +1 -0
- package/dist/esm/utils/git/file-changes.js +196 -0
- package/dist/esm/utils/git/file-changes.js.map +1 -0
- package/dist/esm/utils/git/git-client.js +39 -0
- package/dist/esm/utils/git/git-client.js.map +1 -0
- package/dist/esm/utils/git/index.js +9 -0
- package/dist/esm/utils/git/index.js.map +1 -0
- package/dist/esm/utils/git/metadata.js +41 -0
- package/dist/esm/utils/git/metadata.js.map +1 -0
- package/dist/esm/utils/git/status.js +34 -0
- package/dist/esm/utils/git/status.js.map +1 -0
- package/dist/esm/utils/git/types.js +2 -0
- package/dist/esm/utils/git/types.js.map +1 -0
- package/dist/esm/utils/markdown/index.js +3 -0
- package/dist/esm/utils/markdown/index.js.map +1 -0
- package/dist/esm/utils/markdown/parser.js +72 -0
- package/dist/esm/utils/markdown/parser.js.map +1 -0
- package/dist/esm/utils/markdown/types.js +2 -0
- package/dist/esm/utils/markdown/types.js.map +1 -0
- package/dist/esm/utils/package-resolver.js +40 -0
- package/dist/esm/utils/package-resolver.js.map +1 -0
- package/dist/esm/utils/ts-doc/constants.js +13 -0
- package/dist/esm/utils/ts-doc/constants.js.map +1 -0
- package/dist/esm/utils/ts-doc/extractors.js +175 -0
- package/dist/esm/utils/ts-doc/extractors.js.map +1 -0
- package/dist/esm/utils/ts-doc/index.js +3 -0
- package/dist/esm/utils/ts-doc/index.js.map +1 -0
- package/dist/esm/utils/ts-doc/parser.js +37 -0
- package/dist/esm/utils/ts-doc/parser.js.map +1 -0
- package/dist/esm/utils/ts-doc/types.js +2 -0
- package/dist/esm/utils/ts-doc/types.js.map +1 -0
- package/dist/esm/utils/types.js +2 -0
- package/dist/esm/utils/types.js.map +1 -0
- package/dist/esm/version.js +3 -0
- package/dist/esm/version.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/dist/types/bin/apply-metadata.d.ts +1 -0
- package/dist/types/bin/delete-removed-files.d.ts +1 -0
- package/dist/types/bin/embed.d.ts +1 -0
- package/dist/types/bin/execute-pipeline.d.ts +1 -0
- package/dist/types/bin/file-stream.d.ts +1 -0
- package/dist/types/bin/get-diff.d.ts +1 -0
- package/dist/types/bin/index.d.ts +1 -0
- package/dist/types/bin/types.d.ts +1 -0
- package/dist/types/command.d.ts +2 -0
- package/dist/types/command.options.d.ts +62 -0
- package/dist/types/config.d.ts +33 -0
- package/dist/types/index.d.ts +8 -0
- package/dist/types/utils/generate-chunk-id.d.ts +8 -0
- package/dist/types/utils/git/file-changes.d.ts +21 -0
- package/dist/types/utils/git/git-client.d.ts +17 -0
- package/dist/types/utils/git/index.d.ts +5 -0
- package/dist/types/utils/git/metadata.d.ts +7 -0
- package/dist/types/utils/git/status.d.ts +12 -0
- package/dist/types/utils/git/types.d.ts +33 -0
- package/dist/types/utils/markdown/index.d.ts +2 -0
- package/dist/types/utils/markdown/parser.d.ts +21 -0
- package/dist/types/utils/markdown/types.d.ts +11 -0
- package/dist/types/utils/package-resolver.d.ts +14 -0
- package/dist/types/utils/ts-doc/constants.d.ts +5 -0
- package/dist/types/utils/ts-doc/extractors.d.ts +28 -0
- package/dist/types/utils/ts-doc/index.d.ts +2 -0
- package/dist/types/utils/ts-doc/parser.d.ts +23 -0
- package/dist/types/utils/ts-doc/types.d.ts +20 -0
- package/dist/types/utils/types.d.ts +17 -0
- package/dist/types/version.d.ts +1 -0
- package/package.json +72 -0
- package/src/bin/apply-metadata.ts +77 -0
- package/src/bin/delete-removed-files.ts +49 -0
- package/src/bin/embed.ts +262 -0
- package/src/bin/execute-pipeline.ts +48 -0
- package/src/bin/file-stream.ts +34 -0
- package/src/bin/get-diff.ts +33 -0
- package/src/bin/index.ts +1 -0
- package/src/bin/types.ts +48 -0
- package/src/command.options.ts +58 -0
- package/src/command.ts +100 -0
- package/src/config.ts +39 -0
- package/src/index.ts +19 -0
- package/src/utils/generate-chunk-id.ts +17 -0
- package/src/utils/git/file-changes.ts +213 -0
- package/src/utils/git/git-client.ts +43 -0
- package/src/utils/git/index.ts +19 -0
- package/src/utils/git/metadata.ts +47 -0
- package/src/utils/git/status.ts +48 -0
- package/src/utils/git/types.ts +36 -0
- package/src/utils/markdown/index.ts +5 -0
- package/src/utils/markdown/parser.ts +92 -0
- package/src/utils/markdown/types.ts +20 -0
- package/src/utils/package-resolver.ts +44 -0
- package/src/utils/ts-doc/constants.ts +13 -0
- package/src/utils/ts-doc/extractors.ts +246 -0
- package/src/utils/ts-doc/index.ts +5 -0
- package/src/utils/ts-doc/parser.ts +51 -0
- package/src/utils/ts-doc/types.ts +26 -0
- package/src/utils/types.ts +18 -0
- package/src/version.ts +2 -0
- package/tsconfig.json +27 -0
- package/vitest.config.ts +14 -0
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { createCommand, createOption } from 'commander';
|
|
2
|
+
import { loadFusionAIConfig, setupFramework } from '@equinor/fusion-framework-cli-plugin-ai-base';
|
|
3
|
+
import { withOptions as withAiOptions } from '@equinor/fusion-framework-cli-plugin-ai-base/command-options';
|
|
4
|
+
import { embed } from './bin/embed.js';
|
|
5
|
+
import { CommandOptionsSchema } from './command.options.js';
|
|
6
|
+
/**
|
|
7
|
+
* CLI command: `ai embeddings`
|
|
8
|
+
*
|
|
9
|
+
* Document embedding utilities for Large Language Model processing.
|
|
10
|
+
*
|
|
11
|
+
* Features:
|
|
12
|
+
* - Markdown/MDX document chunking with frontmatter extraction
|
|
13
|
+
* - TypeScript/TSX TSDoc extraction and chunking
|
|
14
|
+
* - Glob pattern support for file collection
|
|
15
|
+
* - Git diff-based processing for workflow integration
|
|
16
|
+
* - Dry-run mode for testing without actual processing
|
|
17
|
+
* - Configurable file patterns via fusion-ai.config.ts
|
|
18
|
+
*
|
|
19
|
+
* Usage:
|
|
20
|
+
* $ ffc ai embeddings [options] [glob-patterns...]
|
|
21
|
+
*
|
|
22
|
+
* Arguments:
|
|
23
|
+
* glob-patterns Glob patterns to match files (optional when using --diff)
|
|
24
|
+
* Defaults to patterns from fusion-ai.config.ts if not provided
|
|
25
|
+
*
|
|
26
|
+
* Options:
|
|
27
|
+
* --dry-run Show what would be processed without actually doing it
|
|
28
|
+
* --config <config> Path to a config file (default: fusion-ai.config)
|
|
29
|
+
* --diff Process only changed files (workflow mode)
|
|
30
|
+
* --base-ref <ref> Git reference to compare against (default: HEAD~1)
|
|
31
|
+
* --clean Delete all existing documents from the vector store before processing
|
|
32
|
+
*
|
|
33
|
+
* AI Options (required):
|
|
34
|
+
* --openai-api-key <key> Azure OpenAI API key (or AZURE_OPENAI_API_KEY env var)
|
|
35
|
+
* --openai-api-version <version> Azure OpenAI API version (default: 2024-02-15-preview)
|
|
36
|
+
* --openai-instance <name> Azure OpenAI instance name (or AZURE_OPENAI_INSTANCE_NAME env var)
|
|
37
|
+
* --openai-embedding-deployment <name> Azure OpenAI embedding deployment name (or AZURE_OPENAI_EMBEDDING_DEPLOYMENT_NAME env var)
|
|
38
|
+
* --azure-search-endpoint <url> Azure Search endpoint URL (or AZURE_SEARCH_ENDPOINT env var)
|
|
39
|
+
* --azure-search-api-key <key> Azure Search API key (or AZURE_SEARCH_API_KEY env var)
|
|
40
|
+
* --azure-search-index-name <name> Azure Search index name (or AZURE_SEARCH_INDEX_NAME env var)
|
|
41
|
+
*
|
|
42
|
+
* Examples:
|
|
43
|
+
* $ ffc ai embeddings --dry-run ./src
|
|
44
|
+
* $ ffc ai embeddings "*.ts" "*.md" "*.mdx"
|
|
45
|
+
* $ ffc ai embeddings --diff
|
|
46
|
+
* $ ffc ai embeddings --diff --base-ref origin/main
|
|
47
|
+
* $ ffc ai embeddings --clean "*.ts"
|
|
48
|
+
*/
|
|
49
|
+
const _command = createCommand('embeddings')
|
|
50
|
+
.description('Document embedding utilities for Large Language Model processing')
|
|
51
|
+
.addOption(createOption('--dry-run', 'Show what would be processed without actually doing it').default(false))
|
|
52
|
+
.addOption(createOption('--config <config>', 'Path to a config file').default('fusion-ai.config'))
|
|
53
|
+
.addOption(createOption('--diff', 'Process only changed files (workflow mode)').default(false))
|
|
54
|
+
.addOption(createOption('--base-ref <ref>', 'Git reference to compare against').default('HEAD~1'))
|
|
55
|
+
.addOption(createOption('--clean', 'Delete all existing documents from the vector store before processing').default(false))
|
|
56
|
+
.argument('[glob-patterns...]', 'Glob patterns to match files (optional when using --diff)')
|
|
57
|
+
.action(async (patterns, commandOptions) => {
|
|
58
|
+
const options = await CommandOptionsSchema.parseAsync(commandOptions);
|
|
59
|
+
// Load configuration
|
|
60
|
+
const config = await loadFusionAIConfig(options.config, {
|
|
61
|
+
baseDir: process.cwd(),
|
|
62
|
+
});
|
|
63
|
+
// CLI args take precedence over config patterns
|
|
64
|
+
const indexConfig = config.index ?? {};
|
|
65
|
+
const allowedFilePatterns = indexConfig.patterns ?? ['**/*.ts', '**/*.md', '**/*.mdx'];
|
|
66
|
+
const filePatterns = patterns.length ? patterns : allowedFilePatterns;
|
|
67
|
+
// Initialize framework
|
|
68
|
+
const framework = await setupFramework(options);
|
|
69
|
+
// Execute embeddings bin with framework and options
|
|
70
|
+
await embed({
|
|
71
|
+
framework,
|
|
72
|
+
options,
|
|
73
|
+
config,
|
|
74
|
+
filePatterns,
|
|
75
|
+
});
|
|
76
|
+
});
|
|
77
|
+
export const command = withAiOptions(_command, {
|
|
78
|
+
includeEmbedding: true,
|
|
79
|
+
includeSearch: true,
|
|
80
|
+
});
|
|
81
|
+
export default command;
|
|
82
|
+
//# sourceMappingURL=command.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"command.js","sourceRoot":"","sources":["../../src/command.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAExD,OAAO,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,8CAA8C,CAAC;AAClG,OAAO,EAAE,WAAW,IAAI,aAAa,EAAE,MAAM,8DAA8D,CAAC;AAE5G,OAAO,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AACvC,OAAO,EAAE,oBAAoB,EAAuB,MAAM,sBAAsB,CAAC;AAGjF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0CG;AACH,MAAM,QAAQ,GAAG,aAAa,CAAC,YAAY,CAAC;KACzC,WAAW,CAAC,kEAAkE,CAAC;KAC/E,SAAS,CACR,YAAY,CAAC,WAAW,EAAE,wDAAwD,CAAC,CAAC,OAAO,CACzF,KAAK,CACN,CACF;KACA,SAAS,CAAC,YAAY,CAAC,mBAAmB,EAAE,uBAAuB,CAAC,CAAC,OAAO,CAAC,kBAAkB,CAAC,CAAC;KACjG,SAAS,CAAC,YAAY,CAAC,QAAQ,EAAE,4CAA4C,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;KAC9F,SAAS,CAAC,YAAY,CAAC,kBAAkB,EAAE,kCAAkC,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;KACjG,SAAS,CACR,YAAY,CACV,SAAS,EACT,uEAAuE,CACxE,CAAC,OAAO,CAAC,KAAK,CAAC,CACjB;KACA,QAAQ,CAAC,oBAAoB,EAAE,2DAA2D,CAAC;KAC3F,MAAM,CAAC,KAAK,EAAE,QAAkB,EAAE,cAA8B,EAAE,EAAE;IACnE,MAAM,OAAO,GAAG,MAAM,oBAAoB,CAAC,UAAU,CAAC,cAAc,CAAC,CAAC;IAEtE,qBAAqB;IACrB,MAAM,MAAM,GAAG,MAAM,kBAAkB,CAA0B,OAAO,CAAC,MAAM,EAAE;QAC/E,OAAO,EAAE,OAAO,CAAC,GAAG,EAAE;KACvB,CAAC,CAAC;IAEH,gDAAgD;IAChD,MAAM,WAAW,GAAG,MAAM,CAAC,KAAK,IAAI,EAAE,CAAC;IACvC,MAAM,mBAAmB,GAAG,WAAW,CAAC,QAAQ,IAAI,CAAC,SAAS,EAAE,SAAS,EAAE,UAAU,CAAC,CAAC;IACvF,MAAM,YAAY,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,mBAAmB,CAAC;IAEtE,uBAAuB;IACvB,MAAM,SAAS,GAAG,MAAM,cAAc,CAAC,OAAO,CAAC,CAAC;IAEhD,oDAAoD;IACpD,MAAM,KAAK,CAAC;QACV,SAAS;QACT,OAAO;QACP,MAAM;QACN,YAAY;KACb,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEL,MAAM,CAAC,MAAM,OAAO,GAAG,aAAa,CAAC,QAAQ,EAAE;IAC7C,gBAAgB,EAAE,IAAI;IACtB,aAAa,EAAE,IAAI;CACpB,CAAC,CAAC;AAEH,eAAe,OAAO,CAAC"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { AiOptionsSchema } from '@equinor/fusion-framework-cli-plugin-ai-base/command-options';
|
|
3
|
+
/**
|
|
4
|
+
* Zod schema for validating command options for the embeddings command.
|
|
5
|
+
*
|
|
6
|
+
* This schema extends the base AI options schema with embeddings-specific options,
|
|
7
|
+
* ensuring type safety and runtime validation of command arguments.
|
|
8
|
+
*
|
|
9
|
+
* Note: Some optional AI options become required for the embeddings command
|
|
10
|
+
* (openaiEmbeddingDeployment, azureSearchEndpoint, azureSearchApiKey, azureSearchIndexName)
|
|
11
|
+
* because the command uses withAiOptions with includeEmbedding and includeSearch set to true.
|
|
12
|
+
*/
|
|
13
|
+
export const CommandOptionsSchema = AiOptionsSchema.extend({
|
|
14
|
+
// Override optional AI options to make them required for embeddings command
|
|
15
|
+
openaiEmbeddingDeployment: z
|
|
16
|
+
.string({ message: 'Embedding deployment name is required for embeddings command.' })
|
|
17
|
+
.min(1, 'Embedding deployment name must be a non-empty string.')
|
|
18
|
+
.describe('Azure OpenAI embedding deployment name'),
|
|
19
|
+
azureSearchEndpoint: z
|
|
20
|
+
.string({ message: 'Azure Search endpoint is required for embeddings command.' })
|
|
21
|
+
.url('Azure Search endpoint must be a valid URL.')
|
|
22
|
+
.min(1, 'Azure Search endpoint must be a non-empty string.')
|
|
23
|
+
.describe('Azure Search endpoint URL'),
|
|
24
|
+
azureSearchApiKey: z
|
|
25
|
+
.string({ message: 'Azure Search API key is required for embeddings command.' })
|
|
26
|
+
.min(1, 'Azure Search API key must be a non-empty string.')
|
|
27
|
+
.describe('Azure Search API key'),
|
|
28
|
+
azureSearchIndexName: z
|
|
29
|
+
.string({ message: 'Azure Search index name is required for embeddings command.' })
|
|
30
|
+
.min(1, 'Azure Search index name must be a non-empty string.')
|
|
31
|
+
.describe('Azure Search index name'),
|
|
32
|
+
// Embeddings-specific options
|
|
33
|
+
dryRun: z
|
|
34
|
+
.boolean({ message: 'dryRun must be a boolean value.' })
|
|
35
|
+
.describe('Show what would be processed without actually doing it'),
|
|
36
|
+
config: z
|
|
37
|
+
.string({ message: 'Config file path is required and must be a non-empty string.' })
|
|
38
|
+
.min(1, 'Config file path must be a non-empty string.')
|
|
39
|
+
.describe('Path to a config file'),
|
|
40
|
+
diff: z
|
|
41
|
+
.boolean({ message: 'diff must be a boolean value.' })
|
|
42
|
+
.describe('Process only changed files (workflow mode)'),
|
|
43
|
+
baseRef: z.string().min(1).optional().describe('Git reference to compare against'),
|
|
44
|
+
clean: z
|
|
45
|
+
.boolean({ message: 'clean must be a boolean value.' })
|
|
46
|
+
.describe('Delete all existing documents from the vector store before processing'),
|
|
47
|
+
}).describe('Command options for the embeddings command');
|
|
48
|
+
//# sourceMappingURL=command.options.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"command.options.js","sourceRoot":"","sources":["../../src/command.options.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,eAAe,EAAE,MAAM,8DAA8D,CAAC;AAE/F;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,eAAe,CAAC,MAAM,CAAC;IACzD,4EAA4E;IAC5E,yBAAyB,EAAE,CAAC;SACzB,MAAM,CAAC,EAAE,OAAO,EAAE,+DAA+D,EAAE,CAAC;SACpF,GAAG,CAAC,CAAC,EAAE,uDAAuD,CAAC;SAC/D,QAAQ,CAAC,wCAAwC,CAAC;IACrD,mBAAmB,EAAE,CAAC;SACnB,MAAM,CAAC,EAAE,OAAO,EAAE,2DAA2D,EAAE,CAAC;SAChF,GAAG,CAAC,4CAA4C,CAAC;SACjD,GAAG,CAAC,CAAC,EAAE,mDAAmD,CAAC;SAC3D,QAAQ,CAAC,2BAA2B,CAAC;IACxC,iBAAiB,EAAE,CAAC;SACjB,MAAM,CAAC,EAAE,OAAO,EAAE,0DAA0D,EAAE,CAAC;SAC/E,GAAG,CAAC,CAAC,EAAE,kDAAkD,CAAC;SAC1D,QAAQ,CAAC,sBAAsB,CAAC;IACnC,oBAAoB,EAAE,CAAC;SACpB,MAAM,CAAC,EAAE,OAAO,EAAE,6DAA6D,EAAE,CAAC;SAClF,GAAG,CAAC,CAAC,EAAE,qDAAqD,CAAC;SAC7D,QAAQ,CAAC,yBAAyB,CAAC;IAEtC,8BAA8B;IAC9B,MAAM,EAAE,CAAC;SACN,OAAO,CAAC,EAAE,OAAO,EAAE,iCAAiC,EAAE,CAAC;SACvD,QAAQ,CAAC,wDAAwD,CAAC;IACrE,MAAM,EAAE,CAAC;SACN,MAAM,CAAC,EAAE,OAAO,EAAE,8DAA8D,EAAE,CAAC;SACnF,GAAG,CAAC,CAAC,EAAE,8CAA8C,CAAC;SACtD,QAAQ,CAAC,uBAAuB,CAAC;IACpC,IAAI,EAAE,CAAC;SACJ,OAAO,CAAC,EAAE,OAAO,EAAE,+BAA+B,EAAE,CAAC;SACrD,QAAQ,CAAC,4CAA4C,CAAC;IACzD,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,kCAAkC,CAAC;IAClF,KAAK,EAAE,CAAC;SACL,OAAO,CAAC,EAAE,OAAO,EAAE,gCAAgC,EAAE,CAAC;SACtD,QAAQ,CAAC,uEAAuE,CAAC;CACrF,CAAC,CAAC,QAAQ,CAAC,4CAA4C,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/config.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { registerAiPlugin as registerAiPluginBase } from '@equinor/fusion-framework-cli-plugin-ai-base';
|
|
2
|
+
import { command as embeddingsCommand } from './command.js';
|
|
3
|
+
/**
|
|
4
|
+
* Registers the AI index plugin command with the CLI program
|
|
5
|
+
* @param program - The Commander program instance to register commands with
|
|
6
|
+
*/
|
|
7
|
+
export function registerAiPlugin(program) {
|
|
8
|
+
registerAiPluginBase(program, embeddingsCommand);
|
|
9
|
+
}
|
|
10
|
+
export default registerAiPlugin;
|
|
11
|
+
// Re-export config utilities for convenience
|
|
12
|
+
export { configureFusionAI, } from '@equinor/fusion-framework-cli-plugin-ai-base';
|
|
13
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,IAAI,oBAAoB,EAAE,MAAM,8CAA8C,CAAC;AACxG,OAAO,EAAE,OAAO,IAAI,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAE5D;;;GAGG;AACH,MAAM,UAAU,gBAAgB,CAAC,OAAgB;IAC/C,oBAAoB,CAAC,OAAO,EAAE,iBAAiB,CAAC,CAAC;AACnD,CAAC;AAED,eAAe,gBAAgB,CAAC;AAEhC,6CAA6C;AAC7C,OAAO,EACL,iBAAiB,GAElB,MAAM,8CAA8C,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generates a unique identifier for a document chunk based on file path
|
|
3
|
+
* Creates a deterministic, URL-safe hash from the file path for validation and checks
|
|
4
|
+
* @param filePath - The file path to generate an ID from
|
|
5
|
+
* @param chunkIndex - Optional chunk index to append for multi-chunk documents
|
|
6
|
+
* @returns A base64-encoded hash of the file path, optionally suffixed with chunk index
|
|
7
|
+
*/
|
|
8
|
+
export const generateChunkId = (filePath, chunkIndex) => {
|
|
9
|
+
// Convert file path to base64 and remove non-alphanumeric characters
|
|
10
|
+
// This creates a stable, URL-safe identifier from the file path
|
|
11
|
+
// The deterministic nature allows for validation and duplicate detection
|
|
12
|
+
const pathHash = Buffer.from(filePath)
|
|
13
|
+
.toString('base64')
|
|
14
|
+
.replace(/[^a-zA-Z0-9]/g, '');
|
|
15
|
+
// Append chunk index if provided to distinguish multiple chunks from the same file
|
|
16
|
+
return chunkIndex ? `${pathHash}-${chunkIndex}` : pathHash;
|
|
17
|
+
};
|
|
18
|
+
//# sourceMappingURL=generate-chunk-id.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generate-chunk-id.js","sourceRoot":"","sources":["../../../src/utils/generate-chunk-id.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,QAAgB,EAAE,UAAmB,EAAU,EAAE;IAC/E,qEAAqE;IACrE,gEAAgE;IAChE,yEAAyE;IACzE,MAAM,QAAQ,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC;SACnC,QAAQ,CAAC,QAAQ,CAAC;SAClB,OAAO,CAAC,eAAe,EAAE,EAAE,CAAC,CAAC;IAChC,mFAAmF;IACnF,OAAO,UAAU,CAAC,CAAC,CAAC,GAAG,QAAQ,IAAI,UAAU,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC;AAC7D,CAAC,CAAC"}
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
import { join, relative } from 'node:path';
|
|
2
|
+
import { resolveProjectRoot, getGit } from './git-client.js';
|
|
3
|
+
/**
|
|
4
|
+
* Get list of changed files using git diff with status
|
|
5
|
+
* @param options - Git diff configuration options
|
|
6
|
+
* @returns Array of changed files with their status
|
|
7
|
+
*/
|
|
8
|
+
export const getChangedFiles = async (options) => {
|
|
9
|
+
const { diff, baseRef = 'HEAD~1', cwd = process.cwd() } = options;
|
|
10
|
+
if (!diff) {
|
|
11
|
+
return [];
|
|
12
|
+
}
|
|
13
|
+
const projectRoot = resolveProjectRoot(cwd);
|
|
14
|
+
if (!projectRoot) {
|
|
15
|
+
throw new Error('Not in a git repository. Cannot use --diff option.');
|
|
16
|
+
}
|
|
17
|
+
const { git } = getGit(cwd) ?? {};
|
|
18
|
+
if (!git) {
|
|
19
|
+
throw new Error('Failed to initialize git client');
|
|
20
|
+
}
|
|
21
|
+
try {
|
|
22
|
+
// Get changes since baseRef with status (A=added, M=modified, D=deleted)
|
|
23
|
+
try {
|
|
24
|
+
const diffResult = await git.diff([`${baseRef}`, '--name-status']);
|
|
25
|
+
const lines = diffResult.split('\n').filter((line) => line.trim() !== '');
|
|
26
|
+
const changedFiles = [];
|
|
27
|
+
for (const line of lines) {
|
|
28
|
+
// Match status and file path
|
|
29
|
+
// Format: "A\tfile.ts" or "M\tfile.ts" or "D\tfile.ts"
|
|
30
|
+
// Also handle renames: "R100\told.ts\tnew.ts"
|
|
31
|
+
const renameMatch = line.match(/^R\d*\s+(.+?)\s+(.+)$/);
|
|
32
|
+
if (renameMatch) {
|
|
33
|
+
const [, oldFile, newFile] = renameMatch;
|
|
34
|
+
// Add both the removed old file and the new file
|
|
35
|
+
changedFiles.push({ filepath: `${projectRoot}/${oldFile}`, status: 'removed' });
|
|
36
|
+
changedFiles.push({ filepath: `${projectRoot}/${newFile}`, status: 'new' });
|
|
37
|
+
continue;
|
|
38
|
+
}
|
|
39
|
+
const match = line.match(/^([AMD])\s+(.+)$/);
|
|
40
|
+
if (match) {
|
|
41
|
+
const [, gitStatus, file] = match;
|
|
42
|
+
const fullPath = `${projectRoot}/${file}`;
|
|
43
|
+
let status;
|
|
44
|
+
if (gitStatus === 'A') {
|
|
45
|
+
status = 'new';
|
|
46
|
+
}
|
|
47
|
+
else if (gitStatus === 'M') {
|
|
48
|
+
status = 'modified';
|
|
49
|
+
}
|
|
50
|
+
else if (gitStatus === 'D') {
|
|
51
|
+
status = 'removed';
|
|
52
|
+
}
|
|
53
|
+
else {
|
|
54
|
+
// Skip unknown statuses (C=copied, etc.)
|
|
55
|
+
continue;
|
|
56
|
+
}
|
|
57
|
+
changedFiles.push({ filepath: fullPath, status });
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
return changedFiles;
|
|
61
|
+
}
|
|
62
|
+
catch {
|
|
63
|
+
// Handle case where baseRef doesn't exist (e.g., first commit)
|
|
64
|
+
console.warn(`⚠️ Warning: Git reference '${baseRef}' not found. Processing all files.`);
|
|
65
|
+
return [];
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
catch (error) {
|
|
69
|
+
throw new Error(`Git diff failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
/**
|
|
73
|
+
* Determine the git status of a file, including handling renames
|
|
74
|
+
* Returns an array of ChangedFile objects - if the file was renamed, returns both old and new paths
|
|
75
|
+
* @param filePath - Absolute file path to check
|
|
76
|
+
* @returns Promise resolving to array of changed files (1 or 2 items if renamed)
|
|
77
|
+
*/
|
|
78
|
+
export const getFileStatus = async (filePath) => {
|
|
79
|
+
const { git, gitRepoPath } = getGit(filePath) ?? {};
|
|
80
|
+
if (!git || !gitRepoPath) {
|
|
81
|
+
// Not in a git repository, assume new
|
|
82
|
+
return [{ filepath: filePath, status: 'new' }];
|
|
83
|
+
}
|
|
84
|
+
const gitFilePath = relative(gitRepoPath, filePath);
|
|
85
|
+
// Normalize path separators for git commands (git uses forward slashes on all platforms)
|
|
86
|
+
const normalizedGitFilePath = gitFilePath.replace(/\\/g, '/');
|
|
87
|
+
try {
|
|
88
|
+
// First check if file is tracked in git at the current path
|
|
89
|
+
const isTracked = await git
|
|
90
|
+
.raw(['ls-files', '--error-unmatch', normalizedGitFilePath])
|
|
91
|
+
.then(() => true)
|
|
92
|
+
.catch(() => false);
|
|
93
|
+
if (isTracked) {
|
|
94
|
+
// File is tracked at this path, it's modified
|
|
95
|
+
return [{ filepath: filePath, status: 'modified' }];
|
|
96
|
+
}
|
|
97
|
+
// File is not tracked - quickly check if it's explicitly untracked
|
|
98
|
+
// This is much faster than checking full status or history
|
|
99
|
+
try {
|
|
100
|
+
const fileStatusOutput = await git.raw([
|
|
101
|
+
'status',
|
|
102
|
+
'--porcelain',
|
|
103
|
+
'--',
|
|
104
|
+
normalizedGitFilePath,
|
|
105
|
+
]);
|
|
106
|
+
const trimmed = fileStatusOutput.trim();
|
|
107
|
+
if (trimmed.length > 0) {
|
|
108
|
+
// If status shows ??, it's untracked (truly new)
|
|
109
|
+
if (/^\?\?/.test(trimmed)) {
|
|
110
|
+
return [{ filepath: filePath, status: 'new' }];
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
catch {
|
|
115
|
+
// If status check fails, continue to rename/history checks
|
|
116
|
+
}
|
|
117
|
+
// File is not tracked and not explicitly untracked - check if it's a rename
|
|
118
|
+
// Only do expensive checks if we haven't determined status yet
|
|
119
|
+
try {
|
|
120
|
+
// Get full git status to check for renames (only if needed)
|
|
121
|
+
const statusOutput = await git.raw(['status', '--porcelain']);
|
|
122
|
+
const lines = statusOutput.split('\n').filter((line) => line.trim() !== '');
|
|
123
|
+
for (const line of lines) {
|
|
124
|
+
// Check for rename format: "R100\told.ts\tnew.ts"
|
|
125
|
+
const renameMatch = line.match(/^R\d+\s+(.+?)\s+(.+)$/);
|
|
126
|
+
if (renameMatch) {
|
|
127
|
+
const [, oldPath, newPath] = renameMatch;
|
|
128
|
+
const oldFullPath = join(gitRepoPath, oldPath);
|
|
129
|
+
const newFullPath = join(gitRepoPath, newPath);
|
|
130
|
+
// Check if the current file is the new path in a rename
|
|
131
|
+
if (newFullPath === filePath) {
|
|
132
|
+
return [
|
|
133
|
+
{ filepath: oldFullPath, status: 'removed' },
|
|
134
|
+
{ filepath: newFullPath, status: 'new' },
|
|
135
|
+
];
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
// Check for copy format: "C100\told.ts\tnew.ts" (similar to rename)
|
|
139
|
+
const copyMatch = line.match(/^C\d+\s+(.+?)\s+(.+)$/);
|
|
140
|
+
if (copyMatch) {
|
|
141
|
+
const [, , newPath] = copyMatch;
|
|
142
|
+
const newFullPath = join(gitRepoPath, newPath);
|
|
143
|
+
// For copies, the old file still exists, so only return the new one
|
|
144
|
+
if (newFullPath === filePath) {
|
|
145
|
+
return [{ filepath: newFullPath, status: 'new' }];
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
catch {
|
|
151
|
+
// If status check fails, continue to history check
|
|
152
|
+
}
|
|
153
|
+
// Last resort: check if file content exists in git history (very slow, only if needed)
|
|
154
|
+
// Use --follow to track renames, limit to 1 commit for performance
|
|
155
|
+
try {
|
|
156
|
+
const hasHistory = await git
|
|
157
|
+
.raw([
|
|
158
|
+
'log',
|
|
159
|
+
'--all',
|
|
160
|
+
'--full-history',
|
|
161
|
+
'--follow',
|
|
162
|
+
'--oneline',
|
|
163
|
+
'-1',
|
|
164
|
+
'--',
|
|
165
|
+
normalizedGitFilePath,
|
|
166
|
+
])
|
|
167
|
+
.then((output) => output.trim().length > 0)
|
|
168
|
+
.catch(() => false);
|
|
169
|
+
// If file has history but isn't tracked, it might have been moved
|
|
170
|
+
// For now, treat as 'new' at the new location
|
|
171
|
+
// Note: We can't easily find the old path without more complex git operations
|
|
172
|
+
return [{ filepath: filePath, status: hasHistory ? 'modified' : 'new' }];
|
|
173
|
+
}
|
|
174
|
+
catch {
|
|
175
|
+
// If we can't determine, default to 'new'
|
|
176
|
+
return [{ filepath: filePath, status: 'new' }];
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
catch {
|
|
180
|
+
// If we can't determine status, default to 'new'
|
|
181
|
+
return [{ filepath: filePath, status: 'new' }];
|
|
182
|
+
}
|
|
183
|
+
};
|
|
184
|
+
/**
|
|
185
|
+
* Check if a file path matches any of the changed files
|
|
186
|
+
* @param filePath - File path to check
|
|
187
|
+
* @param changedFiles - Array of changed file objects
|
|
188
|
+
* @returns True if file has changed
|
|
189
|
+
*/
|
|
190
|
+
export const isFileChanged = (filePath, changedFiles) => {
|
|
191
|
+
if (changedFiles.length === 0) {
|
|
192
|
+
return true; // If no diff filtering, process all files
|
|
193
|
+
}
|
|
194
|
+
return changedFiles.some((file) => file.filepath === filePath);
|
|
195
|
+
};
|
|
196
|
+
//# sourceMappingURL=file-changes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-changes.js","sourceRoot":"","sources":["../../../../src/utils/git/file-changes.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { simpleGit } from 'simple-git';
|
|
2
|
+
import { findUpSync } from 'find-up';
|
|
3
|
+
import { dirname, join } from 'node:path';
|
|
4
|
+
import { existsSync } from 'node:fs';
|
|
5
|
+
const gitCache = new Map();
|
|
6
|
+
/**
|
|
7
|
+
* Resolve the project root (git repository root) for a given file path
|
|
8
|
+
* @param filePath - File path to resolve from
|
|
9
|
+
* @returns Project root path or undefined if not in a git repository
|
|
10
|
+
*/
|
|
11
|
+
export const resolveProjectRoot = (filePath) => {
|
|
12
|
+
// if we are in the root of the git repository, return the root
|
|
13
|
+
if (existsSync(join(filePath, '.git'))) {
|
|
14
|
+
return filePath;
|
|
15
|
+
}
|
|
16
|
+
const gitRepoPath = findUpSync('.git', { cwd: dirname(filePath), type: 'both' });
|
|
17
|
+
const projectRoot = gitRepoPath?.replace(/\.git$/, '');
|
|
18
|
+
return projectRoot;
|
|
19
|
+
};
|
|
20
|
+
/**
|
|
21
|
+
* Get or create a SimpleGit instance for a given file path
|
|
22
|
+
* Uses caching to avoid creating multiple instances for the same repository
|
|
23
|
+
* @param filePath - File path to get git instance for
|
|
24
|
+
* @returns Git instance and repository path, or undefined if not in a git repository
|
|
25
|
+
*/
|
|
26
|
+
export const getGit = (filePath) => {
|
|
27
|
+
const gitRepoPath = resolveProjectRoot(filePath);
|
|
28
|
+
if (gitRepoPath) {
|
|
29
|
+
if (!gitCache.has(gitRepoPath)) {
|
|
30
|
+
gitCache.set(gitRepoPath, simpleGit(gitRepoPath));
|
|
31
|
+
}
|
|
32
|
+
return {
|
|
33
|
+
git: gitCache.get(gitRepoPath),
|
|
34
|
+
gitRepoPath,
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
return undefined;
|
|
38
|
+
};
|
|
39
|
+
//# sourceMappingURL=git-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"git-client.js","sourceRoot":"","sources":["../../../../src/utils/git/git-client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAkB,MAAM,YAAY,CAAC;AACvD,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAErC,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAqB,CAAC;AAE9C;;;;GAIG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,QAAgB,EAAsB,EAAE;IACzE,+DAA+D;IAC/D,IAAI,UAAU,CAAC,IAAI,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC,EAAE,CAAC;QACvC,OAAO,QAAQ,CAAC;IAClB,CAAC;IACD,MAAM,WAAW,GAAG,UAAU,CAAC,MAAM,EAAE,EAAE,GAAG,EAAE,OAAO,CAAC,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;IACjF,MAAM,WAAW,GAAG,WAAW,EAAE,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;IACvD,OAAO,WAAW,CAAC;AACrB,CAAC,CAAC;AAEF;;;;;GAKG;AACH,MAAM,CAAC,MAAM,MAAM,GAAG,CACpB,QAAgB,EACiD,EAAE;IACnE,MAAM,WAAW,GAAG,kBAAkB,CAAC,QAAQ,CAAC,CAAC;IACjD,IAAI,WAAW,EAAE,CAAC;QAChB,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,WAAW,CAAC,EAAE,CAAC;YAC/B,QAAQ,CAAC,GAAG,CAAC,WAAW,EAAE,SAAS,CAAC,WAAW,CAAC,CAAC,CAAC;QACpD,CAAC;QACD,OAAO;YACL,GAAG,EAAE,QAAQ,CAAC,GAAG,CAAC,WAAW,CAAC;YAC9B,WAAW;SACZ,CAAC;IACJ,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
// Re-export git client utilities
|
|
2
|
+
export { resolveProjectRoot, getGit } from './git-client.js';
|
|
3
|
+
// Re-export metadata functions
|
|
4
|
+
export { extractGitMetadata } from './metadata.js';
|
|
5
|
+
// Re-export file change functions
|
|
6
|
+
export { getChangedFiles, getFileStatus, isFileChanged } from './file-changes.js';
|
|
7
|
+
// Re-export status functions
|
|
8
|
+
export { getGitStatus } from './status.js';
|
|
9
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/utils/git/index.ts"],"names":[],"mappings":"AAQA,iCAAiC;AACjC,OAAO,EAAE,kBAAkB,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAE7D,+BAA+B;AAC/B,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAEnD,kCAAkC;AAClC,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAElF,6BAA6B;AAC7B,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { relative } from 'node:path';
|
|
2
|
+
import { getGit } from './git-client.js';
|
|
3
|
+
/**
|
|
4
|
+
* Generate a GitHub permalink for a file
|
|
5
|
+
* @param gitRemoteUrl - Git remote URL
|
|
6
|
+
* @param filePath - Relative file path from repository root
|
|
7
|
+
* @param slug - Git reference (branch/tag/commit), defaults to 'main'
|
|
8
|
+
* @returns GitHub permalink URL or undefined if not a GitHub repository
|
|
9
|
+
* @internal
|
|
10
|
+
*/
|
|
11
|
+
const generateGithubPermalink = (gitRemoteUrl, filePath, slug) => {
|
|
12
|
+
const githubMatch = gitRemoteUrl.match(/github\.com[:/]([^/]+)\/([^/.]+)(?:\.git)?$/);
|
|
13
|
+
if (githubMatch) {
|
|
14
|
+
const [, owner, repo] = githubMatch;
|
|
15
|
+
return `https://github.com/${owner}/${repo}/blob/${slug ?? 'main'}/${filePath}`;
|
|
16
|
+
}
|
|
17
|
+
return undefined;
|
|
18
|
+
};
|
|
19
|
+
/**
|
|
20
|
+
* Extract git metadata for a file
|
|
21
|
+
* @param filePath - Absolute file path
|
|
22
|
+
* @returns Git metadata or undefined if not in a git repository
|
|
23
|
+
*/
|
|
24
|
+
export const extractGitMetadata = async (filePath) => {
|
|
25
|
+
const { git, gitRepoPath: gitRepoRoot } = getGit(filePath) ?? {};
|
|
26
|
+
if (!git || !gitRepoRoot) {
|
|
27
|
+
return undefined;
|
|
28
|
+
}
|
|
29
|
+
const gitFilePath = relative(gitRepoRoot, filePath);
|
|
30
|
+
const { latest } = await git.log({ file: gitFilePath, maxCount: 1 });
|
|
31
|
+
const gitRemoteUrl = await git
|
|
32
|
+
.getConfig('remote.origin.url')
|
|
33
|
+
.then(({ value }) => value ?? undefined);
|
|
34
|
+
const git_link = gitRemoteUrl ? generateGithubPermalink(gitRemoteUrl, gitFilePath) : undefined;
|
|
35
|
+
return {
|
|
36
|
+
git_link,
|
|
37
|
+
git_commit_hash: latest?.hash,
|
|
38
|
+
git_commit_date: latest?.date,
|
|
39
|
+
};
|
|
40
|
+
};
|
|
41
|
+
//# sourceMappingURL=metadata.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"metadata.js","sourceRoot":"","sources":["../../../../src/utils/git/metadata.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAErC,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAEzC;;;;;;;GAOG;AACH,MAAM,uBAAuB,GAAG,CAC9B,YAAoB,EACpB,QAAgB,EAChB,IAAa,EACO,EAAE;IACtB,MAAM,WAAW,GAAG,YAAY,CAAC,KAAK,CAAC,6CAA6C,CAAC,CAAC;IACtF,IAAI,WAAW,EAAE,CAAC;QAChB,MAAM,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,GAAG,WAAW,CAAC;QACpC,OAAO,sBAAsB,KAAK,IAAI,IAAI,SAAS,IAAI,IAAI,MAAM,IAAI,QAAQ,EAAE,CAAC;IAClF,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC,CAAC;AAEF;;;;GAIG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,KAAK,EAAE,QAAgB,EAAoC,EAAE;IAC7F,MAAM,EAAE,GAAG,EAAE,WAAW,EAAE,WAAW,EAAE,GAAG,MAAM,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;IACjE,IAAI,CAAC,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;QACzB,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,MAAM,WAAW,GAAG,QAAQ,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC;IACpD,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,GAAG,CAAC,GAAG,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC,CAAC;IACrE,MAAM,YAAY,GAAG,MAAM,GAAG;SAC3B,SAAS,CAAC,mBAAmB,CAAC;SAC9B,IAAI,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,KAAK,IAAI,SAAS,CAAC,CAAC;IAC3C,MAAM,QAAQ,GAAG,YAAY,CAAC,CAAC,CAAC,uBAAuB,CAAC,YAAY,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAC/F,OAAO;QACL,QAAQ;QACR,eAAe,EAAE,MAAM,EAAE,IAAI;QAC7B,eAAe,EAAE,MAAM,EAAE,IAAI;KAC9B,CAAC;AACJ,CAAC,CAAC"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { resolveProjectRoot, getGit } from './git-client.js';
|
|
2
|
+
/**
|
|
3
|
+
* Get git status information for debugging
|
|
4
|
+
* @param cwd - Working directory
|
|
5
|
+
* @returns Git status information
|
|
6
|
+
*/
|
|
7
|
+
export const getGitStatus = async (cwd = process.cwd()) => {
|
|
8
|
+
const projectRoot = resolveProjectRoot(cwd);
|
|
9
|
+
if (!projectRoot) {
|
|
10
|
+
throw new Error('Not in a git repository');
|
|
11
|
+
}
|
|
12
|
+
const { git } = getGit(cwd) ?? {};
|
|
13
|
+
if (!git) {
|
|
14
|
+
throw new Error('Failed to initialize git client');
|
|
15
|
+
}
|
|
16
|
+
try {
|
|
17
|
+
const branch = await git.revparse(['--abbrev-ref', 'HEAD']);
|
|
18
|
+
const commit = await git.revparse(['--short', 'HEAD']);
|
|
19
|
+
const statusResult = await git.status();
|
|
20
|
+
const stagedFiles = statusResult.staged.length;
|
|
21
|
+
const unstagedFiles = statusResult.modified.length + statusResult.deleted.length + statusResult.not_added.length;
|
|
22
|
+
return {
|
|
23
|
+
branch: branch.trim(),
|
|
24
|
+
commit: commit.trim(),
|
|
25
|
+
hasChanges: stagedFiles > 0 || unstagedFiles > 0,
|
|
26
|
+
stagedFiles,
|
|
27
|
+
unstagedFiles,
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
catch (error) {
|
|
31
|
+
throw new Error(`Failed to get git status: ${error instanceof Error ? error.message : String(error)}`);
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
//# sourceMappingURL=status.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"status.js","sourceRoot":"","sources":["../../../../src/utils/git/status.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAE7D;;;;GAIG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,KAAK,EAC/B,MAAc,OAAO,CAAC,GAAG,EAAE,EAO1B,EAAE;IACH,MAAM,WAAW,GAAG,kBAAkB,CAAC,GAAG,CAAC,CAAC;IAC5C,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,MAAM,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC;IAC7C,CAAC;IAED,MAAM,EAAE,GAAG,EAAE,GAAG,MAAM,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;IAClC,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,MAAM,IAAI,KAAK,CAAC,iCAAiC,CAAC,CAAC;IACrD,CAAC;IAED,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,QAAQ,CAAC,CAAC,cAAc,EAAE,MAAM,CAAC,CAAC,CAAC;QAC5D,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,QAAQ,CAAC,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC,CAAC;QAEvD,MAAM,YAAY,GAAG,MAAM,GAAG,CAAC,MAAM,EAAE,CAAC;QACxC,MAAM,WAAW,GAAG,YAAY,CAAC,MAAM,CAAC,MAAM,CAAC;QAC/C,MAAM,aAAa,GACjB,YAAY,CAAC,QAAQ,CAAC,MAAM,GAAG,YAAY,CAAC,OAAO,CAAC,MAAM,GAAG,YAAY,CAAC,SAAS,CAAC,MAAM,CAAC;QAE7F,OAAO;YACL,MAAM,EAAE,MAAM,CAAC,IAAI,EAAE;YACrB,MAAM,EAAE,MAAM,CAAC,IAAI,EAAE;YACrB,UAAU,EAAE,WAAW,GAAG,CAAC,IAAI,aAAa,GAAG,CAAC;YAChD,WAAW;YACX,aAAa;SACd,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CACb,6BAA6B,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CACtF,CAAC;IACJ,CAAC;AACH,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../src/utils/git/types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/utils/markdown/index.ts"],"names":[],"mappings":"AAGA,6BAA6B;AAC7B,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { readFileSync } from 'node:fs';
|
|
2
|
+
import { assert } from 'node:console';
|
|
3
|
+
import { default as grayMatter } from 'gray-matter';
|
|
4
|
+
import { RecursiveCharacterTextSplitter } from '@langchain/textsplitters';
|
|
5
|
+
import { generateChunkId } from '../generate-chunk-id.js';
|
|
6
|
+
const markdownConfig = {
|
|
7
|
+
chunkSize: 3000,
|
|
8
|
+
chunkOverlap: 300,
|
|
9
|
+
keepSeparator: true,
|
|
10
|
+
separators: [
|
|
11
|
+
'\n# ',
|
|
12
|
+
'\n## ',
|
|
13
|
+
'\n### ',
|
|
14
|
+
'\n#### ',
|
|
15
|
+
'\n##### ',
|
|
16
|
+
'\n###### ',
|
|
17
|
+
'\n```',
|
|
18
|
+
'\n---\n',
|
|
19
|
+
'\n\n',
|
|
20
|
+
],
|
|
21
|
+
};
|
|
22
|
+
/**
|
|
23
|
+
* Check if a file is a markdown or MDX file
|
|
24
|
+
* @param filePath - File path to check
|
|
25
|
+
* @returns True if file has .md or .mdx extension
|
|
26
|
+
*/
|
|
27
|
+
export const isMarkdownFile = (filePath) => {
|
|
28
|
+
return filePath.endsWith('.md') || filePath.endsWith('.mdx');
|
|
29
|
+
};
|
|
30
|
+
/**
|
|
31
|
+
* Parse markdown or MDX content into document chunks
|
|
32
|
+
* @param content - Markdown or MDX content string
|
|
33
|
+
* @param source - Source file path
|
|
34
|
+
* @returns Array of markdown documents
|
|
35
|
+
*/
|
|
36
|
+
export const parseMarkdown = async (content, source) => {
|
|
37
|
+
const { content: markdownContent, data } = grayMatter(content);
|
|
38
|
+
const markdownAttributes = Object.entries(data).reduce((acc, [key, value]) => {
|
|
39
|
+
acc[`md_${key}`] = value;
|
|
40
|
+
return acc;
|
|
41
|
+
}, {
|
|
42
|
+
type: 'markdown',
|
|
43
|
+
});
|
|
44
|
+
const textSplitter = new RecursiveCharacterTextSplitter(markdownConfig);
|
|
45
|
+
const chunks = await textSplitter.splitText(markdownContent);
|
|
46
|
+
return chunks.map((chunk, _index) => ({
|
|
47
|
+
id: generateChunkId(source, _index),
|
|
48
|
+
pageContent: chunk,
|
|
49
|
+
metadata: {
|
|
50
|
+
source,
|
|
51
|
+
attributes: markdownAttributes,
|
|
52
|
+
},
|
|
53
|
+
}));
|
|
54
|
+
};
|
|
55
|
+
/**
|
|
56
|
+
* Parse a markdown or MDX file into document chunks
|
|
57
|
+
* @param file - Source file object
|
|
58
|
+
* @returns Array of markdown documents with root path metadata
|
|
59
|
+
*/
|
|
60
|
+
export const parseMarkdownFile = async (file) => {
|
|
61
|
+
assert(isMarkdownFile(file.path), `File ${file.path} is not a markdown or MDX file`);
|
|
62
|
+
const content = readFileSync(file.path, 'utf8');
|
|
63
|
+
const result = await parseMarkdown(content, file.relativePath ?? file.path);
|
|
64
|
+
return result.map((document) => ({
|
|
65
|
+
...document,
|
|
66
|
+
metadata: {
|
|
67
|
+
...document.metadata,
|
|
68
|
+
rootPath: file.projectRoot,
|
|
69
|
+
},
|
|
70
|
+
}));
|
|
71
|
+
};
|
|
72
|
+
//# sourceMappingURL=parser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parser.js","sourceRoot":"","sources":["../../../../src/utils/markdown/parser.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAEtC,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,aAAa,CAAC;AAEpD,OAAO,EAAE,8BAA8B,EAAE,MAAM,0BAA0B,CAAC;AAI1E,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAE1D,MAAM,cAAc,GAAG;IACrB,SAAS,EAAE,IAAI;IACf,YAAY,EAAE,GAAG;IACjB,aAAa,EAAE,IAAI;IACnB,UAAU,EAAE;QACV,MAAM;QACN,OAAO;QACP,QAAQ;QACR,SAAS;QACT,UAAU;QACV,WAAW;QACX,OAAO;QACP,SAAS;QACT,MAAM;KACP;CACF,CAAC;AAEF;;;;GAIG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,QAAgB,EAAW,EAAE;IAC1D,OAAO,QAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;AAC/D,CAAC,CAAC;AAEF;;;;;GAKG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,KAAK,EAChC,OAAe,EACf,MAAc,EACkB,EAAE;IAClC,MAAM,EAAE,OAAO,EAAE,eAAe,EAAE,IAAI,EAAE,GAAG,UAAU,CAAC,OAAO,CAAC,CAAC;IAC/D,MAAM,kBAAkB,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,MAAM,CACpD,CAAC,GAAG,EAAE,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE;QACpB,GAAG,CAAC,MAAM,GAAG,EAAE,CAAC,GAAG,KAAK,CAAC;QACzB,OAAO,GAAG,CAAC;IACb,CAAC,EACD;QACE,IAAI,EAAE,UAAU;KACU,CAC7B,CAAC;IACF,MAAM,YAAY,GAAG,IAAI,8BAA8B,CAAC,cAAc,CAAC,CAAC;IACxE,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,SAAS,CAAC,eAAe,CAAC,CAAC;IAC7D,OAAO,MAAM,CAAC,GAAG,CACf,CAAC,KAAK,EAAE,MAAM,EAAuB,EAAE,CAAC,CAAC;QACvC,EAAE,EAAE,eAAe,CAAC,MAAM,EAAE,MAAM,CAAC;QACnC,WAAW,EAAE,KAAK;QAClB,QAAQ,EAAE;YACR,MAAM;YACN,UAAU,EAAE,kBAAuD;SACpE;KACF,CAAC,CACH,CAAC;AACJ,CAAC,CAAC;AAEF;;;;GAIG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,KAAK,EAGpC,IAAgB,EACgB,EAAE;IAClC,MAAM,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,QAAQ,IAAI,CAAC,IAAI,gCAAgC,CAAC,CAAC;IACrF,MAAM,OAAO,GAAG,YAAY,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IAChD,MAAM,MAAM,GAAG,MAAM,aAAa,CAAI,OAAO,EAAE,IAAI,CAAC,YAAY,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC;IAC/E,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;QAC/B,GAAG,QAAQ;QACX,QAAQ,EAAE;YACR,GAAG,QAAQ,CAAC,QAAQ;YACpB,QAAQ,EAAE,IAAI,CAAC,WAAW;SAC3B;KACF,CAAC,CAAC,CAAC;AACN,CAAC,CAAC"}
|