sdlc-agent-4-enterprise-server 1.2.0 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* IDE Adapters — Strategy pattern for injecting pre-converted agents into target IDE folder structures.
|
|
3
|
+
*
|
|
4
|
+
* Pre-converted files live in resources/conversions/{ide}/.
|
|
5
|
+
* Each adapter copies the correct pre-built files to the target workspace.
|
|
6
|
+
* NO runtime conversion — files are crafted offline with proper format per IDE.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import * as fs from "fs";
|
|
10
|
+
import * as path from "path";
|
|
11
|
+
import { copyDirRecursive } from "./file-utils";
|
|
12
|
+
|
|
13
|
+
export type IdeTarget = "kiro" | "vscode" | "claude" | "codex";
|
|
14
|
+
|
|
15
|
+
export interface IdeTargetInfo {
|
|
16
|
+
id: IdeTarget;
|
|
17
|
+
label: string;
|
|
18
|
+
description: string;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export const IDE_TARGETS: IdeTargetInfo[] = [
|
|
22
|
+
{ id: "kiro", label: "Kiro (default)", description: ".kiro/agents/, .kiro/steering/, .kiro/hooks/" },
|
|
23
|
+
{ id: "vscode", label: "VSCode (GitHub Copilot)", description: ".github/agents/, .github/copilot-instructions.md" },
|
|
24
|
+
{ id: "claude", label: "Claude Code", description: ".claude/agents/, .claude/rules/, CLAUDE.md" },
|
|
25
|
+
{ id: "codex", label: "Codex (OpenAI)", description: "AGENTS.md, agents/ subdirectory" },
|
|
26
|
+
];
|
|
27
|
+
|
|
28
|
+
/** Strategy interface — each IDE adapter knows how to inject pre-converted files. */
|
|
29
|
+
export interface IdeAdapter {
|
|
30
|
+
readonly target: IdeTarget;
|
|
31
|
+
inject(root: string, extensionPath: string): boolean;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// --- Kiro Adapter (copies .kiro/ resources directly) ---
|
|
35
|
+
|
|
36
|
+
export class KiroAdapter implements IdeAdapter {
|
|
37
|
+
readonly target: IdeTarget = "kiro";
|
|
38
|
+
|
|
39
|
+
inject(root: string, extensionPath: string): boolean {
|
|
40
|
+
const resourcesDir = path.join(extensionPath, "resources", ".kiro");
|
|
41
|
+
if (!fs.existsSync(resourcesDir)) { return false; }
|
|
42
|
+
const targetDir = path.join(root, ".kiro");
|
|
43
|
+
copyDirRecursive(resourcesDir, targetDir);
|
|
44
|
+
return true;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// --- Pre-Converted Adapter (shared logic for Claude, Copilot, Codex) ---
|
|
49
|
+
|
|
50
|
+
class PreConvertedAdapter implements IdeAdapter {
|
|
51
|
+
constructor(readonly target: IdeTarget, private readonly conversionId: string) {}
|
|
52
|
+
|
|
53
|
+
inject(root: string, extensionPath: string): boolean {
|
|
54
|
+
const sourceDir = path.join(extensionPath, "resources", "conversions", this.conversionId);
|
|
55
|
+
if (!fs.existsSync(sourceDir)) { return false; }
|
|
56
|
+
copyDirRecursive(sourceDir, root);
|
|
57
|
+
return true;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// --- Factory ---
|
|
62
|
+
|
|
63
|
+
const ADAPTER_MAP: Record<IdeTarget, () => IdeAdapter> = {
|
|
64
|
+
kiro: () => new KiroAdapter(),
|
|
65
|
+
vscode: () => new PreConvertedAdapter("vscode", "github-copilot"),
|
|
66
|
+
claude: () => new PreConvertedAdapter("claude", "claude-code"),
|
|
67
|
+
codex: () => new PreConvertedAdapter("codex", "codex-openai"),
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
export function createAdapter(target: IdeTarget): IdeAdapter {
|
|
71
|
+
return ADAPTER_MAP[target]();
|
|
72
|
+
}
|
|
@@ -7,37 +7,72 @@ import * as fs from "fs";
|
|
|
7
7
|
import * as path from "path";
|
|
8
8
|
import { Component, CORE_COMPONENTS } from "./config";
|
|
9
9
|
import { detectModifiedFiles, loadBundledManifest, buildManifestAfterInject, getFileStatuses, migrateLegacyVersion, FileStatus } from "./checksum";
|
|
10
|
-
import { injectMcpConfig, migrateLegacyScripts, hasMcpConfig } from "./mcp-injector";
|
|
10
|
+
import { injectMcpConfig, migrateLegacyScripts, hasMcpConfig, writeBundledMcpConfig } from "./mcp-injector";
|
|
11
11
|
import { forceUpdate, updateSkipModified, updateWithBackup, injectComponent, promptUpdateWithDetails } from "./injector-helpers";
|
|
12
|
+
import { IdeTarget, IDE_TARGETS, createAdapter } from "./ide-adapters";
|
|
12
13
|
|
|
13
14
|
export { migrateLegacyScripts, injectMcpConfig } from "./mcp-injector";
|
|
14
15
|
|
|
15
16
|
export async function injectAll(root: string, extensionPath: string): Promise<string[]> {
|
|
16
17
|
migrateLegacyVersion(root, extensionPath);
|
|
18
|
+
|
|
19
|
+
const ideTarget = await showIdePicker();
|
|
20
|
+
if (!ideTarget) { return []; }
|
|
21
|
+
|
|
17
22
|
const injected: string[] = [];
|
|
18
|
-
|
|
19
|
-
|
|
23
|
+
|
|
24
|
+
if (ideTarget === "kiro") {
|
|
25
|
+
// Default Kiro behavior — unchanged
|
|
26
|
+
for (const component of CORE_COMPONENTS) {
|
|
27
|
+
if (injectComponent(component, root, extensionPath)) { injected.push(component.id); }
|
|
28
|
+
}
|
|
29
|
+
writeBundledMcpConfig(root, 9181);
|
|
30
|
+
injected.push("mcp-bundled");
|
|
31
|
+
} else {
|
|
32
|
+
// Use IDE-specific adapter — copy pre-converted files
|
|
33
|
+
const adapter = createAdapter(ideTarget);
|
|
34
|
+
if (adapter.inject(root, extensionPath)) {
|
|
35
|
+
injected.push(`ide:${ideTarget}`);
|
|
36
|
+
}
|
|
20
37
|
}
|
|
21
|
-
|
|
22
|
-
if (variantId) { injected.push(`mcp-${variantId}`); }
|
|
38
|
+
|
|
23
39
|
buildManifestAfterInject(root, extensionPath);
|
|
24
40
|
return injected;
|
|
25
41
|
}
|
|
26
42
|
|
|
27
43
|
export async function injectSelective(root: string, extensionPath: string): Promise<string[]> {
|
|
28
44
|
migrateLegacyVersion(root, extensionPath);
|
|
45
|
+
|
|
46
|
+
const ideTarget = await showIdePicker();
|
|
47
|
+
if (!ideTarget) { return []; }
|
|
48
|
+
|
|
49
|
+
if (ideTarget !== "kiro") {
|
|
50
|
+
// Non-Kiro IDEs: inject all pre-converted files (no component picking — it's a flat copy)
|
|
51
|
+
const adapter = createAdapter(ideTarget);
|
|
52
|
+
const injected: string[] = [];
|
|
53
|
+
if (adapter.inject(root, extensionPath)) { injected.push(`ide:${ideTarget}`); }
|
|
54
|
+
// Templates always go to documents/templates regardless of IDE
|
|
55
|
+
const tplComponent = CORE_COMPONENTS.find(c => c.id === "templates");
|
|
56
|
+
if (tplComponent && injectComponent(tplComponent, root, extensionPath)) { injected.push("templates"); }
|
|
57
|
+
buildManifestAfterInject(root, extensionPath);
|
|
58
|
+
return injected;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// Kiro: component-level selection
|
|
29
62
|
const selected = await showComponentPicker();
|
|
30
63
|
if (!selected || selected.length === 0) { return []; }
|
|
64
|
+
|
|
31
65
|
const injected: string[] = [];
|
|
32
66
|
for (const pick of selected) {
|
|
33
67
|
if (pick.id === "mcp-config") {
|
|
34
|
-
|
|
35
|
-
|
|
68
|
+
writeBundledMcpConfig(root, 9181);
|
|
69
|
+
injected.push("mcp-bundled");
|
|
36
70
|
} else {
|
|
37
71
|
const component = CORE_COMPONENTS.find(c => c.id === pick.id);
|
|
38
72
|
if (component && injectComponent(component, root, extensionPath)) { injected.push(component.id); }
|
|
39
73
|
}
|
|
40
74
|
}
|
|
75
|
+
|
|
41
76
|
buildManifestAfterInject(root, extensionPath);
|
|
42
77
|
return injected;
|
|
43
78
|
}
|
|
@@ -79,8 +114,17 @@ export function getVersionReport(root: string, extensionPath: string): string {
|
|
|
79
114
|
return lines.join("\n");
|
|
80
115
|
}
|
|
81
116
|
|
|
117
|
+
async function showIdePicker(): Promise<IdeTarget | undefined> {
|
|
118
|
+
const picks = IDE_TARGETS.map(t => ({ label: t.label, description: t.description, id: t.id }));
|
|
119
|
+
const selected = await vscode.window.showQuickPick(picks, {
|
|
120
|
+
placeHolder: "Select target IDE for agent injection",
|
|
121
|
+
title: "IDE Target"
|
|
122
|
+
});
|
|
123
|
+
return selected?.id;
|
|
124
|
+
}
|
|
125
|
+
|
|
82
126
|
async function showComponentPicker() {
|
|
83
127
|
const corePicks = CORE_COMPONENTS.map(c => ({ label: c.label, description: c.description, id: c.id, picked: true }));
|
|
84
|
-
const mcpPick = { label: "Code Intelligence MCP Server", description: "
|
|
128
|
+
const mcpPick = { label: "Code Intelligence MCP Server", description: "Bundled backend (HTTP Streamable)", id: "mcp-config", picked: true };
|
|
85
129
|
return vscode.window.showQuickPick([...corePicks, mcpPick], { canPickMany: true, placeHolder: "Select components to inject" });
|
|
86
130
|
}
|
package/package.json
CHANGED