@context-forge/core 0.1.0 → 0.2.2
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 +12 -1
- package/assets/prompt.ai-project.system.md +919 -0
- package/dist/config/ConfigKeys.d.ts +9 -0
- package/dist/config/ConfigKeys.d.ts.map +1 -0
- package/dist/config/ConfigKeys.js +24 -0
- package/dist/config/ConfigKeys.js.map +1 -0
- package/dist/config/ConfigManager.d.ts +18 -0
- package/dist/config/ConfigManager.d.ts.map +1 -0
- package/dist/config/ConfigManager.js +129 -0
- package/dist/config/ConfigManager.js.map +1 -0
- package/dist/config/configPaths.d.ts +5 -0
- package/dist/config/configPaths.d.ts.map +1 -0
- package/dist/config/configPaths.js +11 -0
- package/dist/config/configPaths.js.map +1 -0
- package/dist/config/index.d.ts +4 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +4 -0
- package/dist/config/index.js.map +1 -0
- package/dist/guides/GuideDetector.d.ts +20 -0
- package/dist/guides/GuideDetector.d.ts.map +1 -0
- package/dist/guides/GuideDetector.js +142 -0
- package/dist/guides/GuideDetector.js.map +1 -0
- package/dist/guides/GuideManager.d.ts +21 -0
- package/dist/guides/GuideManager.d.ts.map +1 -0
- package/dist/guides/GuideManager.js +88 -0
- package/dist/guides/GuideManager.js.map +1 -0
- package/dist/guides/gitExec.d.ts +15 -0
- package/dist/guides/gitExec.d.ts.map +1 -0
- package/dist/guides/gitExec.js +39 -0
- package/dist/guides/gitExec.js.map +1 -0
- package/dist/guides/index.d.ts +4 -0
- package/dist/guides/index.d.ts.map +1 -0
- package/dist/guides/index.js +5 -0
- package/dist/guides/index.js.map +1 -0
- package/dist/guides/strategies/CloneStrategy.d.ts +7 -0
- package/dist/guides/strategies/CloneStrategy.d.ts.map +1 -0
- package/dist/guides/strategies/CloneStrategy.js +80 -0
- package/dist/guides/strategies/CloneStrategy.js.map +1 -0
- package/dist/guides/strategies/SubmoduleStrategy.d.ts +7 -0
- package/dist/guides/strategies/SubmoduleStrategy.d.ts.map +1 -0
- package/dist/guides/strategies/SubmoduleStrategy.js +74 -0
- package/dist/guides/strategies/SubmoduleStrategy.js.map +1 -0
- package/dist/guides/strategies/TarballStrategy.d.ts +19 -0
- package/dist/guides/strategies/TarballStrategy.d.ts.map +1 -0
- package/dist/guides/strategies/TarballStrategy.js +118 -0
- package/dist/guides/strategies/TarballStrategy.js.map +1 -0
- package/dist/guides/types.d.ts +44 -0
- package/dist/guides/types.d.ts.map +1 -0
- package/dist/guides/types.js +7 -0
- package/dist/guides/types.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -1
- package/dist/introspection/ArtifactIntrospector.d.ts +20 -0
- package/dist/introspection/ArtifactIntrospector.d.ts.map +1 -0
- package/dist/introspection/ArtifactIntrospector.js +140 -0
- package/dist/introspection/ArtifactIntrospector.js.map +1 -0
- package/dist/introspection/FutureWorkCollector.d.ts +7 -0
- package/dist/introspection/FutureWorkCollector.d.ts.map +1 -0
- package/dist/introspection/FutureWorkCollector.js +116 -0
- package/dist/introspection/FutureWorkCollector.js.map +1 -0
- package/dist/introspection/ProjectModelBuilder.d.ts +32 -0
- package/dist/introspection/ProjectModelBuilder.d.ts.map +1 -0
- package/dist/introspection/ProjectModelBuilder.js +321 -0
- package/dist/introspection/ProjectModelBuilder.js.map +1 -0
- package/dist/introspection/index.d.ts +4 -0
- package/dist/introspection/index.d.ts.map +1 -0
- package/dist/introspection/index.js +5 -0
- package/dist/introspection/index.js.map +1 -0
- package/dist/introspection/interfaces.d.ts +18 -0
- package/dist/introspection/interfaces.d.ts.map +1 -0
- package/dist/introspection/interfaces.js +2 -0
- package/dist/introspection/interfaces.js.map +1 -0
- package/dist/introspection/parsers/documentDetector.d.ts +12 -0
- package/dist/introspection/parsers/documentDetector.d.ts.map +1 -0
- package/dist/introspection/parsers/documentDetector.js +66 -0
- package/dist/introspection/parsers/documentDetector.js.map +1 -0
- package/dist/introspection/parsers/frontmatterParser.d.ts +8 -0
- package/dist/introspection/parsers/frontmatterParser.d.ts.map +1 -0
- package/dist/introspection/parsers/frontmatterParser.js +43 -0
- package/dist/introspection/parsers/frontmatterParser.js.map +1 -0
- package/dist/introspection/parsers/futureWorkParser.d.ts +8 -0
- package/dist/introspection/parsers/futureWorkParser.d.ts.map +1 -0
- package/dist/introspection/parsers/futureWorkParser.js +75 -0
- package/dist/introspection/parsers/futureWorkParser.js.map +1 -0
- package/dist/introspection/parsers/slicePlanParser.d.ts +8 -0
- package/dist/introspection/parsers/slicePlanParser.d.ts.map +1 -0
- package/dist/introspection/parsers/slicePlanParser.js +51 -0
- package/dist/introspection/parsers/slicePlanParser.js.map +1 -0
- package/dist/introspection/parsers/statusNormalizer.d.ts +4 -0
- package/dist/introspection/parsers/statusNormalizer.d.ts.map +1 -0
- package/dist/introspection/parsers/statusNormalizer.js +23 -0
- package/dist/introspection/parsers/statusNormalizer.js.map +1 -0
- package/dist/introspection/parsers/taskFileParser.d.ts +13 -0
- package/dist/introspection/parsers/taskFileParser.d.ts.map +1 -0
- package/dist/introspection/parsers/taskFileParser.js +66 -0
- package/dist/introspection/parsers/taskFileParser.js.map +1 -0
- package/dist/introspection/types.d.ts +178 -0
- package/dist/introspection/types.d.ts.map +1 -0
- package/dist/introspection/types.js +2 -0
- package/dist/introspection/types.js.map +1 -0
- package/dist/node.d.ts +10 -0
- package/dist/node.d.ts.map +1 -1
- package/dist/node.js +13 -0
- package/dist/node.js.map +1 -1
- package/dist/schema/projectSchema.d.ts +54 -0
- package/dist/schema/projectSchema.d.ts.map +1 -0
- package/dist/schema/projectSchema.js +127 -0
- package/dist/schema/projectSchema.js.map +1 -0
- package/dist/services/ContextGenerator.d.ts.map +1 -1
- package/dist/services/ContextGenerator.js +3 -5
- package/dist/services/ContextGenerator.js.map +1 -1
- package/dist/services/ContextIntegrator.d.ts.map +1 -1
- package/dist/services/ContextIntegrator.js +10 -14
- package/dist/services/ContextIntegrator.js.map +1 -1
- package/dist/services/ContextTemplateEngine.d.ts.map +1 -1
- package/dist/services/ContextTemplateEngine.js +8 -21
- package/dist/services/ContextTemplateEngine.js.map +1 -1
- package/dist/services/CoreServiceFactory.d.ts +3 -0
- package/dist/services/CoreServiceFactory.d.ts.map +1 -1
- package/dist/services/CoreServiceFactory.js +19 -1
- package/dist/services/CoreServiceFactory.js.map +1 -1
- package/dist/services/ProjectPathService.d.ts +1 -1
- package/dist/services/ProjectPathService.d.ts.map +1 -1
- package/dist/services/ProjectPathService.js +2 -4
- package/dist/services/ProjectPathService.js.map +1 -1
- package/dist/services/SectionBuilder.d.ts +0 -4
- package/dist/services/SectionBuilder.d.ts.map +1 -1
- package/dist/services/SectionBuilder.js +8 -35
- package/dist/services/SectionBuilder.js.map +1 -1
- package/dist/services/SystemPromptParser.d.ts +1 -2
- package/dist/services/SystemPromptParser.d.ts.map +1 -1
- package/dist/services/SystemPromptParser.js +3 -14
- package/dist/services/SystemPromptParser.js.map +1 -1
- package/dist/services/TemplateProcessor.d.ts.map +1 -1
- package/dist/services/TemplateProcessor.js +12 -11
- package/dist/services/TemplateProcessor.js.map +1 -1
- package/dist/services/constants.d.ts.map +1 -1
- package/dist/services/constants.js +0 -6
- package/dist/services/constants.js.map +1 -1
- package/dist/services/interfaces.d.ts +1 -1
- package/dist/services/interfaces.d.ts.map +1 -1
- package/dist/storage/FileProjectStore.d.ts.map +1 -1
- package/dist/storage/FileProjectStore.js +25 -8
- package/dist/storage/FileProjectStore.js.map +1 -1
- package/dist/types/context.d.ts +4 -6
- package/dist/types/context.d.ts.map +1 -1
- package/dist/types/project.d.ts +15 -11
- package/dist/types/project.d.ts.map +1 -1
- package/dist/types/sections.d.ts +0 -1
- package/dist/types/sections.d.ts.map +1 -1
- package/dist/types/sections.js +0 -1
- package/dist/types/sections.js.map +1 -1
- package/package.json +6 -2
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { InstallStrategy, InstallResult, UpdateResult, DetectionResult } from '../types.js';
|
|
2
|
+
export declare class CloneStrategy implements InstallStrategy {
|
|
3
|
+
detect(_projectPath: string, targetDir: string): Promise<DetectionResult | null>;
|
|
4
|
+
install(_projectPath: string, source: string, targetDir: string): Promise<InstallResult>;
|
|
5
|
+
update(_projectPath: string, targetDir: string): Promise<UpdateResult>;
|
|
6
|
+
}
|
|
7
|
+
//# sourceMappingURL=CloneStrategy.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CloneStrategy.d.ts","sourceRoot":"","sources":["../../../src/guides/strategies/CloneStrategy.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,eAAe,EAAE,aAAa,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAGjG,qBAAa,aAAc,YAAW,eAAe;IAC7C,MAAM,CAAC,YAAY,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC;IAsBhF,OAAO,CAAC,YAAY,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC;IAoBxF,MAAM,CAAC,YAAY,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC;CA0C7E"}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
// Clone-based guide installation strategy
|
|
2
|
+
import { existsSync } from 'fs';
|
|
3
|
+
import { join } from 'path';
|
|
4
|
+
import { gitExec, isGitAvailable } from '../gitExec.js';
|
|
5
|
+
export class CloneStrategy {
|
|
6
|
+
async detect(_projectPath, targetDir) {
|
|
7
|
+
if (!existsSync(join(targetDir, '.git')))
|
|
8
|
+
return null;
|
|
9
|
+
let version = null;
|
|
10
|
+
try {
|
|
11
|
+
const { stdout } = await gitExec(['describe', '--tags', '--abbrev=0'], targetDir);
|
|
12
|
+
version = stdout || null;
|
|
13
|
+
}
|
|
14
|
+
catch {
|
|
15
|
+
// No tags
|
|
16
|
+
}
|
|
17
|
+
let source = null;
|
|
18
|
+
try {
|
|
19
|
+
const { stdout } = await gitExec(['remote', 'get-url', 'origin'], targetDir);
|
|
20
|
+
source = stdout || null;
|
|
21
|
+
}
|
|
22
|
+
catch {
|
|
23
|
+
// No remote
|
|
24
|
+
}
|
|
25
|
+
return { method: 'clone', version, source };
|
|
26
|
+
}
|
|
27
|
+
async install(_projectPath, source, targetDir) {
|
|
28
|
+
if (!(await isGitAvailable())) {
|
|
29
|
+
throw new Error('git is not available. Install git or use the "manual" strategy instead.');
|
|
30
|
+
}
|
|
31
|
+
await gitExec(['clone', source, targetDir], process.cwd());
|
|
32
|
+
let version = null;
|
|
33
|
+
try {
|
|
34
|
+
const { stdout } = await gitExec(['describe', '--tags', '--abbrev=0'], targetDir);
|
|
35
|
+
version = stdout || null;
|
|
36
|
+
}
|
|
37
|
+
catch {
|
|
38
|
+
// No tags
|
|
39
|
+
}
|
|
40
|
+
return { success: true, version, method: 'clone', path: targetDir };
|
|
41
|
+
}
|
|
42
|
+
async update(_projectPath, targetDir) {
|
|
43
|
+
let previousVersion = null;
|
|
44
|
+
try {
|
|
45
|
+
const { stdout } = await gitExec(['describe', '--tags', '--abbrev=0'], targetDir);
|
|
46
|
+
previousVersion = stdout || null;
|
|
47
|
+
}
|
|
48
|
+
catch {
|
|
49
|
+
// No previous version
|
|
50
|
+
}
|
|
51
|
+
// Fetch latest from remote, then try pull. If pull fails (e.g. detached HEAD),
|
|
52
|
+
// fetch + checkout the latest tag instead.
|
|
53
|
+
await gitExec(['fetch', '--tags', 'origin'], targetDir);
|
|
54
|
+
try {
|
|
55
|
+
await gitExec(['pull', '--ff-only'], targetDir);
|
|
56
|
+
}
|
|
57
|
+
catch {
|
|
58
|
+
// Detached HEAD or no tracking branch — checkout latest tag
|
|
59
|
+
const { stdout: latestTag } = await gitExec(['describe', '--tags', '--abbrev=0', 'origin/HEAD'], targetDir).catch(async () => {
|
|
60
|
+
// origin/HEAD may not exist; fall back to sorting tags
|
|
61
|
+
const { stdout: tags } = await gitExec(['tag', '--sort=-v:refname'], targetDir);
|
|
62
|
+
const first = tags.split('\n')[0]?.trim();
|
|
63
|
+
if (!first)
|
|
64
|
+
throw new Error('No tags found after fetch');
|
|
65
|
+
return { stdout: first, stderr: '' };
|
|
66
|
+
});
|
|
67
|
+
await gitExec(['checkout', latestTag], targetDir);
|
|
68
|
+
}
|
|
69
|
+
let newVersion = null;
|
|
70
|
+
try {
|
|
71
|
+
const { stdout } = await gitExec(['describe', '--tags', '--abbrev=0'], targetDir);
|
|
72
|
+
newVersion = stdout || null;
|
|
73
|
+
}
|
|
74
|
+
catch {
|
|
75
|
+
// No new version
|
|
76
|
+
}
|
|
77
|
+
return { success: true, previousVersion, newVersion, method: 'clone' };
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
//# sourceMappingURL=CloneStrategy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CloneStrategy.js","sourceRoot":"","sources":["../../../src/guides/strategies/CloneStrategy.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { InstallStrategy, InstallResult, UpdateResult, DetectionResult } from '../types.js';
|
|
2
|
+
export declare class SubmoduleStrategy implements InstallStrategy {
|
|
3
|
+
detect(projectPath: string, targetDir: string): Promise<DetectionResult | null>;
|
|
4
|
+
install(projectPath: string, source: string, targetDir: string): Promise<InstallResult>;
|
|
5
|
+
update(projectPath: string, targetDir: string): Promise<UpdateResult>;
|
|
6
|
+
}
|
|
7
|
+
//# sourceMappingURL=SubmoduleStrategy.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SubmoduleStrategy.d.ts","sourceRoot":"","sources":["../../../src/guides/strategies/SubmoduleStrategy.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,eAAe,EAAE,aAAa,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAIjG,qBAAa,iBAAkB,YAAW,eAAe;IACjD,MAAM,CAAC,WAAW,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC;IA2B/E,OAAO,CAAC,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC;IA0BvF,MAAM,CAAC,WAAW,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC;CAqB5E"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
// Submodule-based guide installation strategy
|
|
2
|
+
import { existsSync, readFileSync } from 'fs';
|
|
3
|
+
import { join } from 'path';
|
|
4
|
+
import { GUIDE_RELATIVE_PATH } from '../types.js';
|
|
5
|
+
import { gitExec, isGitAvailable, isGitRepo } from '../gitExec.js';
|
|
6
|
+
export class SubmoduleStrategy {
|
|
7
|
+
async detect(projectPath, targetDir) {
|
|
8
|
+
const gitmodulesPath = join(projectPath, '.gitmodules');
|
|
9
|
+
if (!existsSync(gitmodulesPath))
|
|
10
|
+
return null;
|
|
11
|
+
try {
|
|
12
|
+
const content = readFileSync(gitmodulesPath, 'utf-8');
|
|
13
|
+
if (!content.includes(GUIDE_RELATIVE_PATH))
|
|
14
|
+
return null;
|
|
15
|
+
let version = null;
|
|
16
|
+
try {
|
|
17
|
+
const { stdout } = await gitExec(['describe', '--tags', '--abbrev=0'], targetDir);
|
|
18
|
+
version = stdout || null;
|
|
19
|
+
}
|
|
20
|
+
catch {
|
|
21
|
+
// No tags or not initialized
|
|
22
|
+
}
|
|
23
|
+
// Extract URL from .gitmodules
|
|
24
|
+
let source = null;
|
|
25
|
+
const urlMatch = /url\s*=\s*(.+)/.exec(content);
|
|
26
|
+
if (urlMatch)
|
|
27
|
+
source = urlMatch[1].trim();
|
|
28
|
+
return { method: 'submodule', version, source };
|
|
29
|
+
}
|
|
30
|
+
catch {
|
|
31
|
+
return null;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
async install(projectPath, source, targetDir) {
|
|
35
|
+
if (!(await isGitAvailable())) {
|
|
36
|
+
throw new Error('git is not available. Install git or use the "manual" strategy instead.');
|
|
37
|
+
}
|
|
38
|
+
if (!(await isGitRepo(projectPath))) {
|
|
39
|
+
throw new Error(`"${projectPath}" is not a git repository. ` +
|
|
40
|
+
'The submodule strategy requires a git repo. Use --strategy clone or --strategy manual instead.');
|
|
41
|
+
}
|
|
42
|
+
await gitExec(['submodule', 'add', source, GUIDE_RELATIVE_PATH], projectPath);
|
|
43
|
+
let version = null;
|
|
44
|
+
try {
|
|
45
|
+
const { stdout } = await gitExec(['describe', '--tags', '--abbrev=0'], targetDir);
|
|
46
|
+
version = stdout || null;
|
|
47
|
+
}
|
|
48
|
+
catch {
|
|
49
|
+
// No tags available
|
|
50
|
+
}
|
|
51
|
+
return { success: true, version, method: 'submodule', path: targetDir };
|
|
52
|
+
}
|
|
53
|
+
async update(projectPath, targetDir) {
|
|
54
|
+
let previousVersion = null;
|
|
55
|
+
try {
|
|
56
|
+
const { stdout } = await gitExec(['describe', '--tags', '--abbrev=0'], targetDir);
|
|
57
|
+
previousVersion = stdout || null;
|
|
58
|
+
}
|
|
59
|
+
catch {
|
|
60
|
+
// No previous version
|
|
61
|
+
}
|
|
62
|
+
await gitExec(['submodule', 'update', '--remote', GUIDE_RELATIVE_PATH], projectPath);
|
|
63
|
+
let newVersion = null;
|
|
64
|
+
try {
|
|
65
|
+
const { stdout } = await gitExec(['describe', '--tags', '--abbrev=0'], targetDir);
|
|
66
|
+
newVersion = stdout || null;
|
|
67
|
+
}
|
|
68
|
+
catch {
|
|
69
|
+
// No new version
|
|
70
|
+
}
|
|
71
|
+
return { success: true, previousVersion, newVersion, method: 'submodule' };
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
//# sourceMappingURL=SubmoduleStrategy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SubmoduleStrategy.js","sourceRoot":"","sources":["../../../src/guides/strategies/SubmoduleStrategy.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { InstallStrategy, InstallResult, UpdateResult, DetectionResult } from '../types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Parse owner/repo from a GitHub source URL.
|
|
4
|
+
* Supports: https://github.com/{owner}/{repo}.git and https://github.com/{owner}/{repo}
|
|
5
|
+
*/
|
|
6
|
+
export declare function parseGitHubOwnerRepo(source: string): {
|
|
7
|
+
owner: string;
|
|
8
|
+
repo: string;
|
|
9
|
+
};
|
|
10
|
+
export declare class TarballStrategy implements InstallStrategy {
|
|
11
|
+
detect(_projectPath: string, targetDir: string): Promise<DetectionResult | null>;
|
|
12
|
+
install(_projectPath: string, source: string, targetDir: string): Promise<InstallResult>;
|
|
13
|
+
update(_projectPath: string, targetDir: string): Promise<UpdateResult>;
|
|
14
|
+
/** Fetch latest tag from remote using git ls-remote */
|
|
15
|
+
private fetchLatestTag;
|
|
16
|
+
/** Download tarball from GitHub API and extract to targetDir */
|
|
17
|
+
private downloadAndExtract;
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=TarballStrategy.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TarballStrategy.d.ts","sourceRoot":"","sources":["../../../src/guides/strategies/TarballStrategy.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,eAAe,EAAE,aAAa,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAIjG;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAMpF;AAED,qBAAa,eAAgB,YAAW,eAAe;IAC/C,MAAM,CAAC,YAAY,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC;IAYhF,OAAO,CAAC,YAAY,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC;IAaxF,MAAM,CAAC,YAAY,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC;IA4B5E,uDAAuD;YACzC,cAAc;IAgC5B,gEAAgE;YAClD,kBAAkB;CAgCjC"}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
// Tarball-based (manual) guide installation strategy
|
|
2
|
+
import { existsSync, readFileSync, writeFileSync, mkdirSync, rmSync } from 'fs';
|
|
3
|
+
import { join } from 'path';
|
|
4
|
+
import { createGunzip } from 'zlib';
|
|
5
|
+
import { Readable } from 'stream';
|
|
6
|
+
import { pipeline } from 'stream/promises';
|
|
7
|
+
import { extract } from 'tar';
|
|
8
|
+
import { VERSION_MARKER_FILE, DEFAULT_SOURCE_GIT } from '../types.js';
|
|
9
|
+
import { gitExec } from '../gitExec.js';
|
|
10
|
+
/**
|
|
11
|
+
* Parse owner/repo from a GitHub source URL.
|
|
12
|
+
* Supports: https://github.com/{owner}/{repo}.git and https://github.com/{owner}/{repo}
|
|
13
|
+
*/
|
|
14
|
+
export function parseGitHubOwnerRepo(source) {
|
|
15
|
+
const match = /github\.com\/([^/]+)\/([^/.]+)/.exec(source);
|
|
16
|
+
if (!match) {
|
|
17
|
+
throw new Error(`Cannot parse GitHub owner/repo from source URL: ${source}`);
|
|
18
|
+
}
|
|
19
|
+
return { owner: match[1], repo: match[2] };
|
|
20
|
+
}
|
|
21
|
+
export class TarballStrategy {
|
|
22
|
+
async detect(_projectPath, targetDir) {
|
|
23
|
+
const markerPath = join(targetDir, VERSION_MARKER_FILE);
|
|
24
|
+
if (!existsSync(markerPath))
|
|
25
|
+
return null;
|
|
26
|
+
try {
|
|
27
|
+
const version = readFileSync(markerPath, 'utf-8').trim() || null;
|
|
28
|
+
return { method: 'manual', version, source: null };
|
|
29
|
+
}
|
|
30
|
+
catch {
|
|
31
|
+
return null;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
async install(_projectPath, source, targetDir) {
|
|
35
|
+
const resolvedSource = source || DEFAULT_SOURCE_GIT;
|
|
36
|
+
const latestTag = await this.fetchLatestTag(resolvedSource);
|
|
37
|
+
if (!latestTag) {
|
|
38
|
+
throw new Error('Could not determine latest version from remote.');
|
|
39
|
+
}
|
|
40
|
+
await this.downloadAndExtract(resolvedSource, latestTag, targetDir);
|
|
41
|
+
writeFileSync(join(targetDir, VERSION_MARKER_FILE), latestTag, 'utf-8');
|
|
42
|
+
return { success: true, version: latestTag, method: 'manual', path: targetDir };
|
|
43
|
+
}
|
|
44
|
+
async update(_projectPath, targetDir) {
|
|
45
|
+
const markerPath = join(targetDir, VERSION_MARKER_FILE);
|
|
46
|
+
let previousVersion = null;
|
|
47
|
+
try {
|
|
48
|
+
previousVersion = readFileSync(markerPath, 'utf-8').trim() || null;
|
|
49
|
+
}
|
|
50
|
+
catch {
|
|
51
|
+
// No previous version
|
|
52
|
+
}
|
|
53
|
+
// Determine source from the default (marker doesn't store it)
|
|
54
|
+
const source = DEFAULT_SOURCE_GIT;
|
|
55
|
+
const latestTag = await this.fetchLatestTag(source);
|
|
56
|
+
if (!latestTag) {
|
|
57
|
+
throw new Error('Could not determine latest version from remote.');
|
|
58
|
+
}
|
|
59
|
+
if (previousVersion === latestTag) {
|
|
60
|
+
return { success: true, previousVersion, newVersion: latestTag, method: 'manual' };
|
|
61
|
+
}
|
|
62
|
+
// Remove existing contents and re-download
|
|
63
|
+
rmSync(targetDir, { recursive: true, force: true });
|
|
64
|
+
await this.downloadAndExtract(source, latestTag, targetDir);
|
|
65
|
+
writeFileSync(join(targetDir, VERSION_MARKER_FILE), latestTag, 'utf-8');
|
|
66
|
+
return { success: true, previousVersion, newVersion: latestTag, method: 'manual' };
|
|
67
|
+
}
|
|
68
|
+
/** Fetch latest tag from remote using git ls-remote */
|
|
69
|
+
async fetchLatestTag(source) {
|
|
70
|
+
try {
|
|
71
|
+
const { stdout } = await gitExec(['ls-remote', '--tags', '--sort=-v:refname', source], process.cwd());
|
|
72
|
+
const tagPattern = /refs\/tags\/(v?\d+\.\d+\.\d+)$/;
|
|
73
|
+
const tags = [];
|
|
74
|
+
for (const line of stdout.split('\n')) {
|
|
75
|
+
const match = tagPattern.exec(line.trim());
|
|
76
|
+
if (match)
|
|
77
|
+
tags.push(match[1]);
|
|
78
|
+
}
|
|
79
|
+
if (tags.length === 0)
|
|
80
|
+
return null;
|
|
81
|
+
// Sort descending
|
|
82
|
+
tags.sort((a, b) => {
|
|
83
|
+
const pa = a.replace(/^v/, '').split('.').map(Number);
|
|
84
|
+
const pb = b.replace(/^v/, '').split('.').map(Number);
|
|
85
|
+
for (let i = 0; i < 3; i++) {
|
|
86
|
+
if (pa[i] !== pb[i])
|
|
87
|
+
return pb[i] - pa[i];
|
|
88
|
+
}
|
|
89
|
+
return 0;
|
|
90
|
+
});
|
|
91
|
+
return tags[0];
|
|
92
|
+
}
|
|
93
|
+
catch {
|
|
94
|
+
return null;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
/** Download tarball from GitHub API and extract to targetDir */
|
|
98
|
+
async downloadAndExtract(source, tag, targetDir) {
|
|
99
|
+
const { owner, repo } = parseGitHubOwnerRepo(source);
|
|
100
|
+
const url = `https://api.github.com/repos/${owner}/${repo}/tarball/${tag}`;
|
|
101
|
+
const response = await fetch(url, {
|
|
102
|
+
headers: { Accept: 'application/vnd.github+json' },
|
|
103
|
+
redirect: 'follow',
|
|
104
|
+
});
|
|
105
|
+
if (!response.ok) {
|
|
106
|
+
throw new Error(`Failed to download tarball: ${response.status} ${response.statusText}`);
|
|
107
|
+
}
|
|
108
|
+
if (!response.body) {
|
|
109
|
+
throw new Error('Empty response body when downloading tarball');
|
|
110
|
+
}
|
|
111
|
+
mkdirSync(targetDir, { recursive: true });
|
|
112
|
+
// GitHub tarballs have a top-level directory like {owner}-{repo}-{hash}/
|
|
113
|
+
// We strip 1 level and extract directly into targetDir
|
|
114
|
+
const nodeStream = Readable.fromWeb(response.body);
|
|
115
|
+
await pipeline(nodeStream, createGunzip(), extract({ cwd: targetDir, strip: 1 }));
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
//# sourceMappingURL=TarballStrategy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TarballStrategy.js","sourceRoot":"","sources":["../../../src/guides/strategies/TarballStrategy.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/** Installation method used for the ai-project-guide */
|
|
2
|
+
export type GuideMethod = 'submodule' | 'clone' | 'manual';
|
|
3
|
+
/** Full status of a guide installation */
|
|
4
|
+
export interface GuideInfo {
|
|
5
|
+
installed: boolean;
|
|
6
|
+
method: GuideMethod | null;
|
|
7
|
+
version: string | null;
|
|
8
|
+
path: string;
|
|
9
|
+
source: string;
|
|
10
|
+
latestVersion: string | null;
|
|
11
|
+
updateAvailable: boolean;
|
|
12
|
+
usingBundledPrompt: boolean;
|
|
13
|
+
}
|
|
14
|
+
/** Result of a guide installation */
|
|
15
|
+
export interface InstallResult {
|
|
16
|
+
success: boolean;
|
|
17
|
+
version: string | null;
|
|
18
|
+
method: GuideMethod;
|
|
19
|
+
path: string;
|
|
20
|
+
}
|
|
21
|
+
/** Result of a guide update */
|
|
22
|
+
export interface UpdateResult {
|
|
23
|
+
success: boolean;
|
|
24
|
+
previousVersion: string | null;
|
|
25
|
+
newVersion: string | null;
|
|
26
|
+
method: GuideMethod;
|
|
27
|
+
}
|
|
28
|
+
/** Detection result returned by a strategy's detect() method */
|
|
29
|
+
export interface DetectionResult {
|
|
30
|
+
method: GuideMethod;
|
|
31
|
+
version: string | null;
|
|
32
|
+
source: string | null;
|
|
33
|
+
}
|
|
34
|
+
/** Strategy interface for guide installation methods */
|
|
35
|
+
export interface InstallStrategy {
|
|
36
|
+
install(projectPath: string, source: string, targetDir: string): Promise<InstallResult>;
|
|
37
|
+
update(projectPath: string, targetDir: string): Promise<UpdateResult>;
|
|
38
|
+
detect(projectPath: string, targetDir: string): Promise<DetectionResult | null>;
|
|
39
|
+
}
|
|
40
|
+
export declare const DEFAULT_SOURCE_GIT = "https://github.com/ecorkran/ai-project-guide.git";
|
|
41
|
+
export declare const DEFAULT_SOURCE_API = "https://api.github.com/repos/ecorkran/ai-project-guide";
|
|
42
|
+
export declare const GUIDE_RELATIVE_PATH = "project-documents/ai-project-guide";
|
|
43
|
+
export declare const VERSION_MARKER_FILE = ".context-forge-guide-version";
|
|
44
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/guides/types.ts"],"names":[],"mappings":"AAEA,wDAAwD;AACxD,MAAM,MAAM,WAAW,GAAG,WAAW,GAAG,OAAO,GAAG,QAAQ,CAAC;AAE3D,0CAA0C;AAC1C,MAAM,WAAW,SAAS;IACxB,SAAS,EAAE,OAAO,CAAC;IACnB,MAAM,EAAE,WAAW,GAAG,IAAI,CAAC;IAC3B,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,eAAe,EAAE,OAAO,CAAC;IACzB,kBAAkB,EAAE,OAAO,CAAC;CAC7B;AAED,qCAAqC;AACrC,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,MAAM,EAAE,WAAW,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,+BAA+B;AAC/B,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,OAAO,CAAC;IACjB,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,MAAM,EAAE,WAAW,CAAC;CACrB;AAED,gEAAgE;AAChE,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,WAAW,CAAC;IACpB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;CACvB;AAED,wDAAwD;AACxD,MAAM,WAAW,eAAe;IAC9B,OAAO,CAAC,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC;IACxF,MAAM,CAAC,WAAW,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;IACtE,MAAM,CAAC,WAAW,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC,CAAC;CACjF;AAGD,eAAO,MAAM,kBAAkB,qDAAqD,CAAC;AACrF,eAAO,MAAM,kBAAkB,2DAA2D,CAAC;AAC3F,eAAO,MAAM,mBAAmB,uCAAuC,CAAC;AACxE,eAAO,MAAM,mBAAmB,iCAAiC,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
// Guide management types and strategy interface
|
|
2
|
+
// Constants
|
|
3
|
+
export const DEFAULT_SOURCE_GIT = 'https://github.com/ecorkran/ai-project-guide.git';
|
|
4
|
+
export const DEFAULT_SOURCE_API = 'https://api.github.com/repos/ecorkran/ai-project-guide';
|
|
5
|
+
export const GUIDE_RELATIVE_PATH = 'project-documents/ai-project-guide';
|
|
6
|
+
export const VERSION_MARKER_FILE = '.context-forge-guide-version';
|
|
7
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/guides/types.ts"],"names":[],"mappings":"AAAA,gDAAgD;AA+ChD,YAAY;AACZ,MAAM,CAAC,MAAM,kBAAkB,GAAG,kDAAkD,CAAC;AACrF,MAAM,CAAC,MAAM,kBAAkB,GAAG,wDAAwD,CAAC;AAC3F,MAAM,CAAC,MAAM,mBAAmB,GAAG,oCAAoC,CAAC;AACxE,MAAM,CAAC,MAAM,mBAAmB,GAAG,8BAA8B,CAAC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
export * from './types/index.js';
|
|
2
2
|
export * from './services/index.js';
|
|
3
3
|
export type { IProjectStore, IStorageService, StorageReadResult } from './storage/interfaces.js';
|
|
4
|
+
export * from './introspection/index.js';
|
|
5
|
+
export type { GuideInfo, GuideMethod, InstallResult, UpdateResult } from './guides/types.js';
|
|
6
|
+
export * from './schema/projectSchema.js';
|
|
4
7
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,cAAc,kBAAkB,CAAC;AACjC,cAAc,qBAAqB,CAAC;AAGpC,YAAY,EAAE,aAAa,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,cAAc,kBAAkB,CAAC;AACjC,cAAc,qBAAqB,CAAC;AAGpC,YAAY,EAAE,aAAa,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAGjG,cAAc,0BAA0B,CAAC;AAGzC,YAAY,EAAE,SAAS,EAAE,WAAW,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAG7F,cAAc,2BAA2B,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,8 @@
|
|
|
1
1
|
// @context-forge/core — context assembly engine
|
|
2
2
|
export * from './types/index.js';
|
|
3
3
|
export * from './services/index.js';
|
|
4
|
+
// Introspection types and interfaces (browser-safe — no fs dependencies)
|
|
5
|
+
export * from './introspection/index.js';
|
|
6
|
+
// Project schema (field metadata, aliases, phase maps)
|
|
7
|
+
export * from './schema/projectSchema.js';
|
|
4
8
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,gDAAgD;AAChD,cAAc,kBAAkB,CAAC;AACjC,cAAc,qBAAqB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,gDAAgD;AAChD,cAAc,kBAAkB,CAAC;AACjC,cAAc,qBAAqB,CAAC;AAKpC,yEAAyE;AACzE,cAAc,0BAA0B,CAAC;AAKzC,uDAAuD;AACvD,cAAc,2BAA2B,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { ProjectData } from '../types/project.js';
|
|
2
|
+
import type { IArtifactIntrospector } from './interfaces.js';
|
|
3
|
+
import type { SlicePlanResult, TaskFileResult, FrontmatterResult, FutureWorkResult, DocumentDetectionResult, IntrospectionSummary } from './types.js';
|
|
4
|
+
/**
|
|
5
|
+
* Orchestrator that delegates to individual parser functions.
|
|
6
|
+
* Each method resolves file paths from projectPath as needed.
|
|
7
|
+
*/
|
|
8
|
+
export declare class ArtifactIntrospector implements IArtifactIntrospector {
|
|
9
|
+
parseSlicePlan(slicePlanPath: string): Promise<SlicePlanResult>;
|
|
10
|
+
parseTaskFile(taskFilePaths: string | string[]): Promise<TaskFileResult>;
|
|
11
|
+
parseFrontmatter(filePath: string): Promise<FrontmatterResult>;
|
|
12
|
+
parseFutureWork(slicePlanPath: string, nextIndex?: number): Promise<FutureWorkResult>;
|
|
13
|
+
detectDocuments(projectPath: string, sliceIndex: number): Promise<DocumentDetectionResult>;
|
|
14
|
+
/**
|
|
15
|
+
* Generate an introspection summary for a project.
|
|
16
|
+
* Each operation is individually try/caught — failure in one doesn't prevent others.
|
|
17
|
+
*/
|
|
18
|
+
summarize(project: ProjectData): Promise<IntrospectionSummary>;
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=ArtifactIntrospector.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ArtifactIntrospector.d.ts","sourceRoot":"","sources":["../../src/introspection/ArtifactIntrospector.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAC7D,OAAO,KAAK,EACV,eAAe,EACf,cAAc,EACd,iBAAiB,EACjB,gBAAgB,EAChB,uBAAuB,EACvB,oBAAoB,EACrB,MAAM,YAAY,CAAC;AAOpB;;;GAGG;AACH,qBAAa,oBAAqB,YAAW,qBAAqB;IAC1D,cAAc,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC;IAI/D,aAAa,CAAC,aAAa,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,OAAO,CAAC,cAAc,CAAC;IAIxE,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAI9D,eAAe,CAAC,aAAa,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAIrF,eAAe,CAAC,WAAW,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,uBAAuB,CAAC;IAIhG;;;OAGG;IACG,SAAS,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,oBAAoB,CAAC;CAsGrE"}
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import { join } from 'node:path';
|
|
2
|
+
import { parseSlicePlan } from './parsers/slicePlanParser.js';
|
|
3
|
+
import { parseTaskFile } from './parsers/taskFileParser.js';
|
|
4
|
+
import { parseFrontmatter } from './parsers/frontmatterParser.js';
|
|
5
|
+
import { parseFutureWork } from './parsers/futureWorkParser.js';
|
|
6
|
+
import { detectDocuments, checkFileExists } from './parsers/documentDetector.js';
|
|
7
|
+
/**
|
|
8
|
+
* Orchestrator that delegates to individual parser functions.
|
|
9
|
+
* Each method resolves file paths from projectPath as needed.
|
|
10
|
+
*/
|
|
11
|
+
export class ArtifactIntrospector {
|
|
12
|
+
async parseSlicePlan(slicePlanPath) {
|
|
13
|
+
return parseSlicePlan(slicePlanPath);
|
|
14
|
+
}
|
|
15
|
+
async parseTaskFile(taskFilePaths) {
|
|
16
|
+
return parseTaskFile(taskFilePaths);
|
|
17
|
+
}
|
|
18
|
+
async parseFrontmatter(filePath) {
|
|
19
|
+
return parseFrontmatter(filePath);
|
|
20
|
+
}
|
|
21
|
+
async parseFutureWork(slicePlanPath, nextIndex) {
|
|
22
|
+
return parseFutureWork(slicePlanPath, nextIndex);
|
|
23
|
+
}
|
|
24
|
+
async detectDocuments(projectPath, sliceIndex) {
|
|
25
|
+
return detectDocuments(projectPath, sliceIndex);
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Generate an introspection summary for a project.
|
|
29
|
+
* Each operation is individually try/caught — failure in one doesn't prevent others.
|
|
30
|
+
*/
|
|
31
|
+
async summarize(project) {
|
|
32
|
+
const summary = {
|
|
33
|
+
artifacts: {
|
|
34
|
+
hasSlicePlan: false,
|
|
35
|
+
hasHLD: false,
|
|
36
|
+
hasArch: false,
|
|
37
|
+
hasSpec: false,
|
|
38
|
+
hasCurrentSliceDesign: false,
|
|
39
|
+
hasCurrentTaskFile: false,
|
|
40
|
+
},
|
|
41
|
+
};
|
|
42
|
+
const projectPath = project.projectPath;
|
|
43
|
+
if (!projectPath)
|
|
44
|
+
return summary;
|
|
45
|
+
// Parse slice plan if available
|
|
46
|
+
try {
|
|
47
|
+
if (project.fileSlicePlan) {
|
|
48
|
+
const planPath = join(projectPath, project.fileSlicePlan);
|
|
49
|
+
const planResult = await parseSlicePlan(planPath);
|
|
50
|
+
if (planResult.totalSlices > 0) {
|
|
51
|
+
summary.slicePlan = {
|
|
52
|
+
totalSlices: planResult.totalSlices,
|
|
53
|
+
completedSlices: planResult.completedSlices,
|
|
54
|
+
summary: `${planResult.completedSlices} of ${planResult.totalSlices} slices complete`,
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
catch {
|
|
60
|
+
// Slice plan parsing failed — continue with other operations
|
|
61
|
+
}
|
|
62
|
+
// Parse task file if available
|
|
63
|
+
try {
|
|
64
|
+
if (project.fileTasks) {
|
|
65
|
+
// Detect actual task file(s) using the slice index
|
|
66
|
+
const sliceIndex = extractSliceIndex(project.fileSlice);
|
|
67
|
+
let taskPaths = [];
|
|
68
|
+
if (sliceIndex !== null) {
|
|
69
|
+
const docs = await detectDocuments(projectPath, sliceIndex);
|
|
70
|
+
if (docs.taskFile) {
|
|
71
|
+
taskPaths = docs.taskFile.map((p) => join(projectPath, p));
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
// Fall back to direct path if detection found nothing
|
|
75
|
+
if (taskPaths.length === 0) {
|
|
76
|
+
taskPaths = [join(projectPath, 'project-documents/user/tasks', project.fileTasks)];
|
|
77
|
+
}
|
|
78
|
+
const taskResult = await parseTaskFile(taskPaths);
|
|
79
|
+
if (taskResult.totalTasks > 0) {
|
|
80
|
+
summary.currentTasks = {
|
|
81
|
+
totalTasks: taskResult.totalTasks,
|
|
82
|
+
completedTasks: taskResult.completedTasks,
|
|
83
|
+
inferredStatus: taskResult.inferredStatus,
|
|
84
|
+
summary: `${taskResult.completedTasks} of ${taskResult.totalTasks} tasks done`,
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
catch {
|
|
90
|
+
// Task parsing failed — continue with other operations
|
|
91
|
+
}
|
|
92
|
+
// Check artifact existence
|
|
93
|
+
try {
|
|
94
|
+
if (project.fileSlicePlan) {
|
|
95
|
+
summary.artifacts.hasSlicePlan = await checkFileExists(projectPath, project.fileSlicePlan);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
catch { /* continue */ }
|
|
99
|
+
try {
|
|
100
|
+
if (project.fileHLD) {
|
|
101
|
+
summary.artifacts.hasHLD = await checkFileExists(projectPath, project.fileHLD);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
catch { /* continue */ }
|
|
105
|
+
try {
|
|
106
|
+
if (project.fileArch) {
|
|
107
|
+
summary.artifacts.hasArch = await checkFileExists(projectPath, project.fileArch);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
catch { /* continue */ }
|
|
111
|
+
try {
|
|
112
|
+
if (project.fileSpec) {
|
|
113
|
+
summary.artifacts.hasSpec = await checkFileExists(projectPath, project.fileSpec);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
catch { /* continue */ }
|
|
117
|
+
// Check current slice design and task file existence
|
|
118
|
+
try {
|
|
119
|
+
const sliceIndex = extractSliceIndex(project.fileSlice);
|
|
120
|
+
if (sliceIndex !== null) {
|
|
121
|
+
const docs = await detectDocuments(projectPath, sliceIndex);
|
|
122
|
+
summary.artifacts.hasCurrentSliceDesign = docs.sliceDesign !== null;
|
|
123
|
+
summary.artifacts.hasCurrentTaskFile = docs.taskFile !== null;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
catch { /* continue */ }
|
|
127
|
+
return summary;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Extract the numeric slice index from a fileSlice value like "163-slice.artifact-introspection.md".
|
|
132
|
+
* Returns null if no leading number found.
|
|
133
|
+
*/
|
|
134
|
+
function extractSliceIndex(fileSlice) {
|
|
135
|
+
if (!fileSlice)
|
|
136
|
+
return null;
|
|
137
|
+
const match = /^(\d+)-/.exec(fileSlice);
|
|
138
|
+
return match ? parseInt(match[1], 10) : null;
|
|
139
|
+
}
|
|
140
|
+
//# sourceMappingURL=ArtifactIntrospector.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ArtifactIntrospector.js","sourceRoot":"","sources":["../../src/introspection/ArtifactIntrospector.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { FutureWorkCollectorResult } from './types.js';
|
|
2
|
+
type StatusFilter = 'all' | 'pending' | 'completed';
|
|
3
|
+
export declare class FutureWorkCollector {
|
|
4
|
+
collect(projectPath: string, statusFilter?: StatusFilter): Promise<FutureWorkCollectorResult>;
|
|
5
|
+
}
|
|
6
|
+
export {};
|
|
7
|
+
//# sourceMappingURL=FutureWorkCollector.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FutureWorkCollector.d.ts","sourceRoot":"","sources":["../../src/introspection/FutureWorkCollector.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAEV,yBAAyB,EAG1B,MAAM,YAAY,CAAC;AAEpB,KAAK,YAAY,GAAG,KAAK,GAAG,SAAS,GAAG,WAAW,CAAC;AAoCpD,qBAAa,mBAAmB;IACxB,OAAO,CACX,WAAW,EAAE,MAAM,EACnB,YAAY,GAAE,YAAoB,GACjC,OAAO,CAAC,yBAAyB,CAAC;CA+FtC"}
|