lightspec 0.1.1
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/LICENSE +22 -0
- package/README.md +435 -0
- package/bin/lightspec.js +3 -0
- package/dist/cli/index.d.ts +2 -0
- package/dist/cli/index.js +361 -0
- package/dist/commands/change.d.ts +35 -0
- package/dist/commands/change.js +277 -0
- package/dist/commands/completion.d.ts +72 -0
- package/dist/commands/completion.js +257 -0
- package/dist/commands/config.d.ts +8 -0
- package/dist/commands/config.js +198 -0
- package/dist/commands/feedback.d.ts +9 -0
- package/dist/commands/feedback.js +183 -0
- package/dist/commands/show.d.ts +14 -0
- package/dist/commands/show.js +132 -0
- package/dist/commands/spec.d.ts +15 -0
- package/dist/commands/spec.js +225 -0
- package/dist/commands/validate.d.ts +24 -0
- package/dist/commands/validate.js +294 -0
- package/dist/core/archive.d.ts +11 -0
- package/dist/core/archive.js +280 -0
- package/dist/core/completions/command-registry.d.ts +7 -0
- package/dist/core/completions/command-registry.js +456 -0
- package/dist/core/completions/completion-provider.d.ts +60 -0
- package/dist/core/completions/completion-provider.js +102 -0
- package/dist/core/completions/factory.d.ts +64 -0
- package/dist/core/completions/factory.js +75 -0
- package/dist/core/completions/generators/bash-generator.d.ts +32 -0
- package/dist/core/completions/generators/bash-generator.js +174 -0
- package/dist/core/completions/generators/fish-generator.d.ts +32 -0
- package/dist/core/completions/generators/fish-generator.js +157 -0
- package/dist/core/completions/generators/powershell-generator.d.ts +33 -0
- package/dist/core/completions/generators/powershell-generator.js +207 -0
- package/dist/core/completions/generators/zsh-generator.d.ts +44 -0
- package/dist/core/completions/generators/zsh-generator.js +250 -0
- package/dist/core/completions/installers/bash-installer.d.ts +87 -0
- package/dist/core/completions/installers/bash-installer.js +318 -0
- package/dist/core/completions/installers/fish-installer.d.ts +43 -0
- package/dist/core/completions/installers/fish-installer.js +143 -0
- package/dist/core/completions/installers/powershell-installer.d.ts +88 -0
- package/dist/core/completions/installers/powershell-installer.js +327 -0
- package/dist/core/completions/installers/zsh-installer.d.ts +125 -0
- package/dist/core/completions/installers/zsh-installer.js +449 -0
- package/dist/core/completions/templates/bash-templates.d.ts +6 -0
- package/dist/core/completions/templates/bash-templates.js +24 -0
- package/dist/core/completions/templates/fish-templates.d.ts +7 -0
- package/dist/core/completions/templates/fish-templates.js +39 -0
- package/dist/core/completions/templates/powershell-templates.d.ts +6 -0
- package/dist/core/completions/templates/powershell-templates.js +25 -0
- package/dist/core/completions/templates/zsh-templates.d.ts +6 -0
- package/dist/core/completions/templates/zsh-templates.js +36 -0
- package/dist/core/completions/types.d.ts +79 -0
- package/dist/core/completions/types.js +2 -0
- package/dist/core/config-prompts.d.ts +9 -0
- package/dist/core/config-prompts.js +34 -0
- package/dist/core/config-schema.d.ts +76 -0
- package/dist/core/config-schema.js +200 -0
- package/dist/core/config.d.ts +16 -0
- package/dist/core/config.js +30 -0
- package/dist/core/configurators/agents.d.ts +8 -0
- package/dist/core/configurators/agents.js +15 -0
- package/dist/core/configurators/base.d.ts +7 -0
- package/dist/core/configurators/base.js +2 -0
- package/dist/core/configurators/claude.d.ts +8 -0
- package/dist/core/configurators/claude.js +15 -0
- package/dist/core/configurators/cline.d.ts +8 -0
- package/dist/core/configurators/cline.js +15 -0
- package/dist/core/configurators/codebuddy.d.ts +8 -0
- package/dist/core/configurators/codebuddy.js +15 -0
- package/dist/core/configurators/costrict.d.ts +8 -0
- package/dist/core/configurators/costrict.js +15 -0
- package/dist/core/configurators/iflow.d.ts +8 -0
- package/dist/core/configurators/iflow.js +15 -0
- package/dist/core/configurators/qoder.d.ts +30 -0
- package/dist/core/configurators/qoder.js +42 -0
- package/dist/core/configurators/qwen.d.ts +24 -0
- package/dist/core/configurators/qwen.js +37 -0
- package/dist/core/configurators/registry.d.ts +9 -0
- package/dist/core/configurators/registry.js +43 -0
- package/dist/core/configurators/slash/amazon-q.d.ts +9 -0
- package/dist/core/configurators/slash/amazon-q.js +46 -0
- package/dist/core/configurators/slash/antigravity.d.ts +9 -0
- package/dist/core/configurators/slash/antigravity.js +23 -0
- package/dist/core/configurators/slash/auggie.d.ts +9 -0
- package/dist/core/configurators/slash/auggie.js +31 -0
- package/dist/core/configurators/slash/base.d.ts +19 -0
- package/dist/core/configurators/slash/base.js +69 -0
- package/dist/core/configurators/slash/claude.d.ts +9 -0
- package/dist/core/configurators/slash/claude.js +37 -0
- package/dist/core/configurators/slash/cline.d.ts +9 -0
- package/dist/core/configurators/slash/cline.js +23 -0
- package/dist/core/configurators/slash/codebuddy.d.ts +9 -0
- package/dist/core/configurators/slash/codebuddy.js +34 -0
- package/dist/core/configurators/slash/codex.d.ts +14 -0
- package/dist/core/configurators/slash/codex.js +109 -0
- package/dist/core/configurators/slash/continue.d.ts +9 -0
- package/dist/core/configurators/slash/continue.js +46 -0
- package/dist/core/configurators/slash/costrict.d.ts +9 -0
- package/dist/core/configurators/slash/costrict.js +31 -0
- package/dist/core/configurators/slash/crush.d.ts +9 -0
- package/dist/core/configurators/slash/crush.js +37 -0
- package/dist/core/configurators/slash/cursor.d.ts +9 -0
- package/dist/core/configurators/slash/cursor.js +37 -0
- package/dist/core/configurators/slash/factory.d.ts +10 -0
- package/dist/core/configurators/slash/factory.js +35 -0
- package/dist/core/configurators/slash/gemini.d.ts +9 -0
- package/dist/core/configurators/slash/gemini.js +22 -0
- package/dist/core/configurators/slash/github-copilot.d.ts +9 -0
- package/dist/core/configurators/slash/github-copilot.js +34 -0
- package/dist/core/configurators/slash/iflow.d.ts +9 -0
- package/dist/core/configurators/slash/iflow.js +37 -0
- package/dist/core/configurators/slash/kilocode.d.ts +9 -0
- package/dist/core/configurators/slash/kilocode.js +17 -0
- package/dist/core/configurators/slash/opencode.d.ts +12 -0
- package/dist/core/configurators/slash/opencode.js +72 -0
- package/dist/core/configurators/slash/qoder.d.ts +35 -0
- package/dist/core/configurators/slash/qoder.js +76 -0
- package/dist/core/configurators/slash/qwen.d.ts +32 -0
- package/dist/core/configurators/slash/qwen.js +49 -0
- package/dist/core/configurators/slash/registry.d.ts +8 -0
- package/dist/core/configurators/slash/registry.js +78 -0
- package/dist/core/configurators/slash/roocode.d.ts +9 -0
- package/dist/core/configurators/slash/roocode.js +23 -0
- package/dist/core/configurators/slash/toml-base.d.ts +10 -0
- package/dist/core/configurators/slash/toml-base.js +53 -0
- package/dist/core/configurators/slash/windsurf.d.ts +9 -0
- package/dist/core/configurators/slash/windsurf.js +23 -0
- package/dist/core/converters/json-converter.d.ts +6 -0
- package/dist/core/converters/json-converter.js +51 -0
- package/dist/core/global-config.d.ts +39 -0
- package/dist/core/global-config.js +115 -0
- package/dist/core/index.d.ts +2 -0
- package/dist/core/index.js +3 -0
- package/dist/core/init.d.ts +52 -0
- package/dist/core/init.js +644 -0
- package/dist/core/list.d.ts +9 -0
- package/dist/core/list.js +171 -0
- package/dist/core/parsers/change-parser.d.ts +13 -0
- package/dist/core/parsers/change-parser.js +193 -0
- package/dist/core/parsers/markdown-parser.d.ts +22 -0
- package/dist/core/parsers/markdown-parser.js +187 -0
- package/dist/core/parsers/requirement-blocks.d.ts +37 -0
- package/dist/core/parsers/requirement-blocks.js +201 -0
- package/dist/core/project-config.d.ts +64 -0
- package/dist/core/project-config.js +223 -0
- package/dist/core/schemas/base.schema.d.ts +13 -0
- package/dist/core/schemas/base.schema.js +13 -0
- package/dist/core/schemas/change.schema.d.ts +73 -0
- package/dist/core/schemas/change.schema.js +31 -0
- package/dist/core/schemas/index.d.ts +4 -0
- package/dist/core/schemas/index.js +4 -0
- package/dist/core/schemas/spec.schema.d.ts +18 -0
- package/dist/core/schemas/spec.schema.js +15 -0
- package/dist/core/specs-apply.d.ts +73 -0
- package/dist/core/specs-apply.js +384 -0
- package/dist/core/styles/palette.d.ts +7 -0
- package/dist/core/styles/palette.js +8 -0
- package/dist/core/templates/agents-root-stub.d.ts +2 -0
- package/dist/core/templates/agents-root-stub.js +17 -0
- package/dist/core/templates/agents-template.d.ts +2 -0
- package/dist/core/templates/agents-template.js +458 -0
- package/dist/core/templates/claude-template.d.ts +2 -0
- package/dist/core/templates/claude-template.js +2 -0
- package/dist/core/templates/cline-template.d.ts +2 -0
- package/dist/core/templates/cline-template.js +2 -0
- package/dist/core/templates/costrict-template.d.ts +2 -0
- package/dist/core/templates/costrict-template.js +2 -0
- package/dist/core/templates/index.d.ts +17 -0
- package/dist/core/templates/index.js +37 -0
- package/dist/core/templates/project-template.d.ts +8 -0
- package/dist/core/templates/project-template.js +32 -0
- package/dist/core/templates/slash-command-templates.d.ts +4 -0
- package/dist/core/templates/slash-command-templates.js +49 -0
- package/dist/core/update.d.ts +4 -0
- package/dist/core/update.js +88 -0
- package/dist/core/validation/constants.d.ts +34 -0
- package/dist/core/validation/constants.js +40 -0
- package/dist/core/validation/types.d.ts +18 -0
- package/dist/core/validation/types.js +2 -0
- package/dist/core/validation/validator.d.ts +33 -0
- package/dist/core/validation/validator.js +409 -0
- package/dist/core/view.d.ts +8 -0
- package/dist/core/view.js +168 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +3 -0
- package/dist/telemetry/config.d.ts +32 -0
- package/dist/telemetry/config.js +68 -0
- package/dist/telemetry/index.d.ts +31 -0
- package/dist/telemetry/index.js +103 -0
- package/dist/utils/file-system.d.ts +25 -0
- package/dist/utils/file-system.js +218 -0
- package/dist/utils/interactive.d.ts +18 -0
- package/dist/utils/interactive.js +21 -0
- package/dist/utils/item-discovery.d.ts +4 -0
- package/dist/utils/item-discovery.js +72 -0
- package/dist/utils/match.d.ts +3 -0
- package/dist/utils/match.js +22 -0
- package/dist/utils/shell-detection.d.ts +20 -0
- package/dist/utils/shell-detection.js +41 -0
- package/dist/utils/task-progress.d.ts +8 -0
- package/dist/utils/task-progress.js +36 -0
- package/package.json +82 -0
- package/scripts/postinstall.js +147 -0
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { ClaudeSlashCommandConfigurator } from './claude.js';
|
|
2
|
+
import { CodeBuddySlashCommandConfigurator } from './codebuddy.js';
|
|
3
|
+
import { QoderSlashCommandConfigurator } from './qoder.js';
|
|
4
|
+
import { CursorSlashCommandConfigurator } from './cursor.js';
|
|
5
|
+
import { WindsurfSlashCommandConfigurator } from './windsurf.js';
|
|
6
|
+
import { KiloCodeSlashCommandConfigurator } from './kilocode.js';
|
|
7
|
+
import { OpenCodeSlashCommandConfigurator } from './opencode.js';
|
|
8
|
+
import { CodexSlashCommandConfigurator } from './codex.js';
|
|
9
|
+
import { GitHubCopilotSlashCommandConfigurator } from './github-copilot.js';
|
|
10
|
+
import { AmazonQSlashCommandConfigurator } from './amazon-q.js';
|
|
11
|
+
import { FactorySlashCommandConfigurator } from './factory.js';
|
|
12
|
+
import { GeminiSlashCommandConfigurator } from './gemini.js';
|
|
13
|
+
import { AuggieSlashCommandConfigurator } from './auggie.js';
|
|
14
|
+
import { ClineSlashCommandConfigurator } from './cline.js';
|
|
15
|
+
import { CrushSlashCommandConfigurator } from './crush.js';
|
|
16
|
+
import { CostrictSlashCommandConfigurator } from './costrict.js';
|
|
17
|
+
import { QwenSlashCommandConfigurator } from './qwen.js';
|
|
18
|
+
import { RooCodeSlashCommandConfigurator } from './roocode.js';
|
|
19
|
+
import { AntigravitySlashCommandConfigurator } from './antigravity.js';
|
|
20
|
+
import { IflowSlashCommandConfigurator } from './iflow.js';
|
|
21
|
+
import { ContinueSlashCommandConfigurator } from './continue.js';
|
|
22
|
+
export class SlashCommandRegistry {
|
|
23
|
+
static configurators = new Map();
|
|
24
|
+
static {
|
|
25
|
+
const claude = new ClaudeSlashCommandConfigurator();
|
|
26
|
+
const codeBuddy = new CodeBuddySlashCommandConfigurator();
|
|
27
|
+
const qoder = new QoderSlashCommandConfigurator();
|
|
28
|
+
const cursor = new CursorSlashCommandConfigurator();
|
|
29
|
+
const windsurf = new WindsurfSlashCommandConfigurator();
|
|
30
|
+
const kilocode = new KiloCodeSlashCommandConfigurator();
|
|
31
|
+
const opencode = new OpenCodeSlashCommandConfigurator();
|
|
32
|
+
const codex = new CodexSlashCommandConfigurator();
|
|
33
|
+
const githubCopilot = new GitHubCopilotSlashCommandConfigurator();
|
|
34
|
+
const amazonQ = new AmazonQSlashCommandConfigurator();
|
|
35
|
+
const factory = new FactorySlashCommandConfigurator();
|
|
36
|
+
const gemini = new GeminiSlashCommandConfigurator();
|
|
37
|
+
const auggie = new AuggieSlashCommandConfigurator();
|
|
38
|
+
const cline = new ClineSlashCommandConfigurator();
|
|
39
|
+
const crush = new CrushSlashCommandConfigurator();
|
|
40
|
+
const costrict = new CostrictSlashCommandConfigurator();
|
|
41
|
+
const qwen = new QwenSlashCommandConfigurator();
|
|
42
|
+
const roocode = new RooCodeSlashCommandConfigurator();
|
|
43
|
+
const antigravity = new AntigravitySlashCommandConfigurator();
|
|
44
|
+
const iflow = new IflowSlashCommandConfigurator();
|
|
45
|
+
const continueTool = new ContinueSlashCommandConfigurator();
|
|
46
|
+
this.configurators.set(claude.toolId, claude);
|
|
47
|
+
this.configurators.set(codeBuddy.toolId, codeBuddy);
|
|
48
|
+
this.configurators.set(qoder.toolId, qoder);
|
|
49
|
+
this.configurators.set(cursor.toolId, cursor);
|
|
50
|
+
this.configurators.set(windsurf.toolId, windsurf);
|
|
51
|
+
this.configurators.set(kilocode.toolId, kilocode);
|
|
52
|
+
this.configurators.set(opencode.toolId, opencode);
|
|
53
|
+
this.configurators.set(codex.toolId, codex);
|
|
54
|
+
this.configurators.set(githubCopilot.toolId, githubCopilot);
|
|
55
|
+
this.configurators.set(amazonQ.toolId, amazonQ);
|
|
56
|
+
this.configurators.set(factory.toolId, factory);
|
|
57
|
+
this.configurators.set(gemini.toolId, gemini);
|
|
58
|
+
this.configurators.set(auggie.toolId, auggie);
|
|
59
|
+
this.configurators.set(cline.toolId, cline);
|
|
60
|
+
this.configurators.set(crush.toolId, crush);
|
|
61
|
+
this.configurators.set(costrict.toolId, costrict);
|
|
62
|
+
this.configurators.set(qwen.toolId, qwen);
|
|
63
|
+
this.configurators.set(roocode.toolId, roocode);
|
|
64
|
+
this.configurators.set(antigravity.toolId, antigravity);
|
|
65
|
+
this.configurators.set(iflow.toolId, iflow);
|
|
66
|
+
this.configurators.set(continueTool.toolId, continueTool);
|
|
67
|
+
}
|
|
68
|
+
static register(configurator) {
|
|
69
|
+
this.configurators.set(configurator.toolId, configurator);
|
|
70
|
+
}
|
|
71
|
+
static get(toolId) {
|
|
72
|
+
return this.configurators.get(toolId);
|
|
73
|
+
}
|
|
74
|
+
static getAll() {
|
|
75
|
+
return Array.from(this.configurators.values());
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
//# sourceMappingURL=registry.js.map
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { SlashCommandConfigurator } from './base.js';
|
|
2
|
+
import { SlashCommandId } from '../../templates/index.js';
|
|
3
|
+
export declare class RooCodeSlashCommandConfigurator extends SlashCommandConfigurator {
|
|
4
|
+
readonly toolId = "roocode";
|
|
5
|
+
readonly isAvailable = true;
|
|
6
|
+
protected getRelativePath(id: SlashCommandId): string;
|
|
7
|
+
protected getFrontmatter(id: SlashCommandId): string | undefined;
|
|
8
|
+
}
|
|
9
|
+
//# sourceMappingURL=roocode.d.ts.map
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { SlashCommandConfigurator } from './base.js';
|
|
2
|
+
const NEW_FILE_PATHS = {
|
|
3
|
+
proposal: '.roo/commands/lightspec-proposal.md',
|
|
4
|
+
apply: '.roo/commands/lightspec-apply.md',
|
|
5
|
+
archive: '.roo/commands/lightspec-archive.md'
|
|
6
|
+
};
|
|
7
|
+
export class RooCodeSlashCommandConfigurator extends SlashCommandConfigurator {
|
|
8
|
+
toolId = 'roocode';
|
|
9
|
+
isAvailable = true;
|
|
10
|
+
getRelativePath(id) {
|
|
11
|
+
return NEW_FILE_PATHS[id];
|
|
12
|
+
}
|
|
13
|
+
getFrontmatter(id) {
|
|
14
|
+
const descriptions = {
|
|
15
|
+
proposal: 'Scaffold a new LightSpec change and validate strictly.',
|
|
16
|
+
apply: 'Implement an approved LightSpec change and keep tasks in sync.',
|
|
17
|
+
archive: 'Archive a deployed LightSpec change and update specs.'
|
|
18
|
+
};
|
|
19
|
+
const description = descriptions[id];
|
|
20
|
+
return `# LightSpec: ${id.charAt(0).toUpperCase() + id.slice(1)}\n\n${description}`;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=roocode.js.map
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { SlashCommandConfigurator } from './base.js';
|
|
2
|
+
import { SlashCommandId } from '../../templates/index.js';
|
|
3
|
+
export declare abstract class TomlSlashCommandConfigurator extends SlashCommandConfigurator {
|
|
4
|
+
protected getFrontmatter(_id: SlashCommandId): string | undefined;
|
|
5
|
+
protected abstract getDescription(id: SlashCommandId): string;
|
|
6
|
+
generateAll(projectPath: string, _lightspecDir: string): Promise<string[]>;
|
|
7
|
+
private generateTOML;
|
|
8
|
+
protected updateBody(filePath: string, body: string): Promise<void>;
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=toml-base.d.ts.map
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { FileSystemUtils } from '../../../utils/file-system.js';
|
|
2
|
+
import { SlashCommandConfigurator } from './base.js';
|
|
3
|
+
import { LIGHTSPEC_MARKERS } from '../../config.js';
|
|
4
|
+
export class TomlSlashCommandConfigurator extends SlashCommandConfigurator {
|
|
5
|
+
getFrontmatter(_id) {
|
|
6
|
+
// TOML doesn't use separate frontmatter - it's all in one structure
|
|
7
|
+
return undefined;
|
|
8
|
+
}
|
|
9
|
+
// Override to generate TOML format with markers inside the prompt field
|
|
10
|
+
async generateAll(projectPath, _lightspecDir) {
|
|
11
|
+
const createdOrUpdated = [];
|
|
12
|
+
for (const target of this.getTargets()) {
|
|
13
|
+
const body = this.getBody(target.id);
|
|
14
|
+
const filePath = FileSystemUtils.joinPath(projectPath, target.path);
|
|
15
|
+
if (await FileSystemUtils.fileExists(filePath)) {
|
|
16
|
+
await this.updateBody(filePath, body);
|
|
17
|
+
}
|
|
18
|
+
else {
|
|
19
|
+
const tomlContent = this.generateTOML(target.id, body);
|
|
20
|
+
await FileSystemUtils.writeFile(filePath, tomlContent);
|
|
21
|
+
}
|
|
22
|
+
createdOrUpdated.push(target.path);
|
|
23
|
+
}
|
|
24
|
+
return createdOrUpdated;
|
|
25
|
+
}
|
|
26
|
+
generateTOML(id, body) {
|
|
27
|
+
const description = this.getDescription(id);
|
|
28
|
+
// TOML format with triple-quoted string for multi-line prompt
|
|
29
|
+
// Markers are inside the prompt value
|
|
30
|
+
return `description = "${description}"
|
|
31
|
+
|
|
32
|
+
prompt = """
|
|
33
|
+
${LIGHTSPEC_MARKERS.start}
|
|
34
|
+
${body}
|
|
35
|
+
${LIGHTSPEC_MARKERS.end}
|
|
36
|
+
"""
|
|
37
|
+
`;
|
|
38
|
+
}
|
|
39
|
+
// Override updateBody to handle TOML format
|
|
40
|
+
async updateBody(filePath, body) {
|
|
41
|
+
const content = await FileSystemUtils.readFile(filePath);
|
|
42
|
+
const startIndex = content.indexOf(LIGHTSPEC_MARKERS.start);
|
|
43
|
+
const endIndex = content.indexOf(LIGHTSPEC_MARKERS.end);
|
|
44
|
+
if (startIndex === -1 || endIndex === -1 || endIndex <= startIndex) {
|
|
45
|
+
throw new Error(`Missing LightSpec markers in ${filePath}`);
|
|
46
|
+
}
|
|
47
|
+
const before = content.slice(0, startIndex + LIGHTSPEC_MARKERS.start.length);
|
|
48
|
+
const after = content.slice(endIndex);
|
|
49
|
+
const updatedContent = `${before}\n${body}\n${after}`;
|
|
50
|
+
await FileSystemUtils.writeFile(filePath, updatedContent);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=toml-base.js.map
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { SlashCommandConfigurator } from './base.js';
|
|
2
|
+
import { SlashCommandId } from '../../templates/index.js';
|
|
3
|
+
export declare class WindsurfSlashCommandConfigurator extends SlashCommandConfigurator {
|
|
4
|
+
readonly toolId = "windsurf";
|
|
5
|
+
readonly isAvailable = true;
|
|
6
|
+
protected getRelativePath(id: SlashCommandId): string;
|
|
7
|
+
protected getFrontmatter(id: SlashCommandId): string | undefined;
|
|
8
|
+
}
|
|
9
|
+
//# sourceMappingURL=windsurf.d.ts.map
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { SlashCommandConfigurator } from './base.js';
|
|
2
|
+
const FILE_PATHS = {
|
|
3
|
+
proposal: '.windsurf/workflows/lightspec-proposal.md',
|
|
4
|
+
apply: '.windsurf/workflows/lightspec-apply.md',
|
|
5
|
+
archive: '.windsurf/workflows/lightspec-archive.md'
|
|
6
|
+
};
|
|
7
|
+
export class WindsurfSlashCommandConfigurator extends SlashCommandConfigurator {
|
|
8
|
+
toolId = 'windsurf';
|
|
9
|
+
isAvailable = true;
|
|
10
|
+
getRelativePath(id) {
|
|
11
|
+
return FILE_PATHS[id];
|
|
12
|
+
}
|
|
13
|
+
getFrontmatter(id) {
|
|
14
|
+
const descriptions = {
|
|
15
|
+
proposal: 'Scaffold a new LightSpec change and validate strictly.',
|
|
16
|
+
apply: 'Implement an approved LightSpec change and keep tasks in sync.',
|
|
17
|
+
archive: 'Archive a deployed LightSpec change and update specs.'
|
|
18
|
+
};
|
|
19
|
+
const description = descriptions[id];
|
|
20
|
+
return `---\ndescription: ${description}\nauto_execution_mode: 3\n---`;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=windsurf.js.map
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { readFileSync } from 'fs';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import { MarkdownParser } from '../parsers/markdown-parser.js';
|
|
4
|
+
import { ChangeParser } from '../parsers/change-parser.js';
|
|
5
|
+
import { FileSystemUtils } from '../../utils/file-system.js';
|
|
6
|
+
export class JsonConverter {
|
|
7
|
+
convertSpecToJson(filePath) {
|
|
8
|
+
const content = readFileSync(filePath, 'utf-8');
|
|
9
|
+
const parser = new MarkdownParser(content);
|
|
10
|
+
const specName = this.extractNameFromPath(filePath);
|
|
11
|
+
const spec = parser.parseSpec(specName);
|
|
12
|
+
const jsonSpec = {
|
|
13
|
+
...spec,
|
|
14
|
+
metadata: {
|
|
15
|
+
...spec.metadata,
|
|
16
|
+
sourcePath: filePath,
|
|
17
|
+
},
|
|
18
|
+
};
|
|
19
|
+
return JSON.stringify(jsonSpec, null, 2);
|
|
20
|
+
}
|
|
21
|
+
async convertChangeToJson(filePath) {
|
|
22
|
+
const content = readFileSync(filePath, 'utf-8');
|
|
23
|
+
const changeName = this.extractNameFromPath(filePath);
|
|
24
|
+
const changeDir = path.dirname(filePath);
|
|
25
|
+
const parser = new ChangeParser(content, changeDir);
|
|
26
|
+
const change = await parser.parseChangeWithDeltas(changeName);
|
|
27
|
+
const jsonChange = {
|
|
28
|
+
...change,
|
|
29
|
+
metadata: {
|
|
30
|
+
...change.metadata,
|
|
31
|
+
sourcePath: filePath,
|
|
32
|
+
},
|
|
33
|
+
};
|
|
34
|
+
return JSON.stringify(jsonChange, null, 2);
|
|
35
|
+
}
|
|
36
|
+
extractNameFromPath(filePath) {
|
|
37
|
+
const normalizedPath = FileSystemUtils.toPosixPath(filePath);
|
|
38
|
+
const parts = normalizedPath.split('/');
|
|
39
|
+
for (let i = parts.length - 1; i >= 0; i--) {
|
|
40
|
+
if (parts[i] === 'specs' || parts[i] === 'changes') {
|
|
41
|
+
if (i < parts.length - 1) {
|
|
42
|
+
return parts[i + 1];
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
const fileName = parts[parts.length - 1] ?? '';
|
|
47
|
+
const dotIndex = fileName.lastIndexOf('.');
|
|
48
|
+
return dotIndex > 0 ? fileName.slice(0, dotIndex) : fileName;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=json-converter.js.map
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
export declare const GLOBAL_CONFIG_DIR_NAME = "lightspec";
|
|
2
|
+
export declare const GLOBAL_CONFIG_FILE_NAME = "config.json";
|
|
3
|
+
export declare const GLOBAL_DATA_DIR_NAME = "lightspec";
|
|
4
|
+
export interface GlobalConfig {
|
|
5
|
+
featureFlags?: Record<string, boolean>;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Gets the global configuration directory path following XDG Base Directory Specification.
|
|
9
|
+
*
|
|
10
|
+
* - All platforms: $XDG_CONFIG_HOME/lightspec/ if XDG_CONFIG_HOME is set
|
|
11
|
+
* - Unix/macOS fallback: ~/.config/lightspec/
|
|
12
|
+
* - Windows fallback: %APPDATA%/lightspec/
|
|
13
|
+
*/
|
|
14
|
+
export declare function getGlobalConfigDir(): string;
|
|
15
|
+
/**
|
|
16
|
+
* Gets the global data directory path following XDG Base Directory Specification.
|
|
17
|
+
* Used for user data like schema overrides.
|
|
18
|
+
*
|
|
19
|
+
* - All platforms: $XDG_DATA_HOME/lightspec/ if XDG_DATA_HOME is set
|
|
20
|
+
* - Unix/macOS fallback: ~/.local/share/lightspec/
|
|
21
|
+
* - Windows fallback: %LOCALAPPDATA%/lightspec/
|
|
22
|
+
*/
|
|
23
|
+
export declare function getGlobalDataDir(): string;
|
|
24
|
+
/**
|
|
25
|
+
* Gets the path to the global config file.
|
|
26
|
+
*/
|
|
27
|
+
export declare function getGlobalConfigPath(): string;
|
|
28
|
+
/**
|
|
29
|
+
* Loads the global configuration from disk.
|
|
30
|
+
* Returns default configuration if file doesn't exist or is invalid.
|
|
31
|
+
* Merges loaded config with defaults to ensure new fields are available.
|
|
32
|
+
*/
|
|
33
|
+
export declare function getGlobalConfig(): GlobalConfig;
|
|
34
|
+
/**
|
|
35
|
+
* Saves the global configuration to disk.
|
|
36
|
+
* Creates the config directory if it doesn't exist.
|
|
37
|
+
*/
|
|
38
|
+
export declare function saveGlobalConfig(config: GlobalConfig): void;
|
|
39
|
+
//# sourceMappingURL=global-config.d.ts.map
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import * as fs from 'node:fs';
|
|
2
|
+
import * as path from 'node:path';
|
|
3
|
+
import * as os from 'node:os';
|
|
4
|
+
// Constants
|
|
5
|
+
export const GLOBAL_CONFIG_DIR_NAME = 'lightspec';
|
|
6
|
+
export const GLOBAL_CONFIG_FILE_NAME = 'config.json';
|
|
7
|
+
export const GLOBAL_DATA_DIR_NAME = 'lightspec';
|
|
8
|
+
const DEFAULT_CONFIG = {
|
|
9
|
+
featureFlags: {}
|
|
10
|
+
};
|
|
11
|
+
/**
|
|
12
|
+
* Gets the global configuration directory path following XDG Base Directory Specification.
|
|
13
|
+
*
|
|
14
|
+
* - All platforms: $XDG_CONFIG_HOME/lightspec/ if XDG_CONFIG_HOME is set
|
|
15
|
+
* - Unix/macOS fallback: ~/.config/lightspec/
|
|
16
|
+
* - Windows fallback: %APPDATA%/lightspec/
|
|
17
|
+
*/
|
|
18
|
+
export function getGlobalConfigDir() {
|
|
19
|
+
// XDG_CONFIG_HOME takes precedence on all platforms when explicitly set
|
|
20
|
+
const xdgConfigHome = process.env.XDG_CONFIG_HOME;
|
|
21
|
+
if (xdgConfigHome) {
|
|
22
|
+
return path.join(xdgConfigHome, GLOBAL_CONFIG_DIR_NAME);
|
|
23
|
+
}
|
|
24
|
+
const platform = os.platform();
|
|
25
|
+
if (platform === 'win32') {
|
|
26
|
+
// Windows: use %APPDATA%
|
|
27
|
+
const appData = process.env.APPDATA;
|
|
28
|
+
if (appData) {
|
|
29
|
+
return path.join(appData, GLOBAL_CONFIG_DIR_NAME);
|
|
30
|
+
}
|
|
31
|
+
// Fallback for Windows if APPDATA is not set
|
|
32
|
+
return path.join(os.homedir(), 'AppData', 'Roaming', GLOBAL_CONFIG_DIR_NAME);
|
|
33
|
+
}
|
|
34
|
+
// Unix/macOS fallback: ~/.config
|
|
35
|
+
return path.join(os.homedir(), '.config', GLOBAL_CONFIG_DIR_NAME);
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Gets the global data directory path following XDG Base Directory Specification.
|
|
39
|
+
* Used for user data like schema overrides.
|
|
40
|
+
*
|
|
41
|
+
* - All platforms: $XDG_DATA_HOME/lightspec/ if XDG_DATA_HOME is set
|
|
42
|
+
* - Unix/macOS fallback: ~/.local/share/lightspec/
|
|
43
|
+
* - Windows fallback: %LOCALAPPDATA%/lightspec/
|
|
44
|
+
*/
|
|
45
|
+
export function getGlobalDataDir() {
|
|
46
|
+
// XDG_DATA_HOME takes precedence on all platforms when explicitly set
|
|
47
|
+
const xdgDataHome = process.env.XDG_DATA_HOME;
|
|
48
|
+
if (xdgDataHome) {
|
|
49
|
+
return path.join(xdgDataHome, GLOBAL_DATA_DIR_NAME);
|
|
50
|
+
}
|
|
51
|
+
const platform = os.platform();
|
|
52
|
+
if (platform === 'win32') {
|
|
53
|
+
// Windows: use %LOCALAPPDATA%
|
|
54
|
+
const localAppData = process.env.LOCALAPPDATA;
|
|
55
|
+
if (localAppData) {
|
|
56
|
+
return path.join(localAppData, GLOBAL_DATA_DIR_NAME);
|
|
57
|
+
}
|
|
58
|
+
// Fallback for Windows if LOCALAPPDATA is not set
|
|
59
|
+
return path.join(os.homedir(), 'AppData', 'Local', GLOBAL_DATA_DIR_NAME);
|
|
60
|
+
}
|
|
61
|
+
// Unix/macOS fallback: ~/.local/share
|
|
62
|
+
return path.join(os.homedir(), '.local', 'share', GLOBAL_DATA_DIR_NAME);
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Gets the path to the global config file.
|
|
66
|
+
*/
|
|
67
|
+
export function getGlobalConfigPath() {
|
|
68
|
+
return path.join(getGlobalConfigDir(), GLOBAL_CONFIG_FILE_NAME);
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Loads the global configuration from disk.
|
|
72
|
+
* Returns default configuration if file doesn't exist or is invalid.
|
|
73
|
+
* Merges loaded config with defaults to ensure new fields are available.
|
|
74
|
+
*/
|
|
75
|
+
export function getGlobalConfig() {
|
|
76
|
+
const configPath = getGlobalConfigPath();
|
|
77
|
+
try {
|
|
78
|
+
if (!fs.existsSync(configPath)) {
|
|
79
|
+
return { ...DEFAULT_CONFIG };
|
|
80
|
+
}
|
|
81
|
+
const content = fs.readFileSync(configPath, 'utf-8');
|
|
82
|
+
const parsed = JSON.parse(content);
|
|
83
|
+
// Merge with defaults (loaded values take precedence)
|
|
84
|
+
return {
|
|
85
|
+
...DEFAULT_CONFIG,
|
|
86
|
+
...parsed,
|
|
87
|
+
// Deep merge featureFlags
|
|
88
|
+
featureFlags: {
|
|
89
|
+
...DEFAULT_CONFIG.featureFlags,
|
|
90
|
+
...(parsed.featureFlags || {})
|
|
91
|
+
}
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
catch (error) {
|
|
95
|
+
// Log warning for parse errors, but not for missing files
|
|
96
|
+
if (error instanceof SyntaxError) {
|
|
97
|
+
console.error(`Warning: Invalid JSON in ${configPath}, using defaults`);
|
|
98
|
+
}
|
|
99
|
+
return { ...DEFAULT_CONFIG };
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Saves the global configuration to disk.
|
|
104
|
+
* Creates the config directory if it doesn't exist.
|
|
105
|
+
*/
|
|
106
|
+
export function saveGlobalConfig(config) {
|
|
107
|
+
const configDir = getGlobalConfigDir();
|
|
108
|
+
const configPath = getGlobalConfigPath();
|
|
109
|
+
// Create directory if it doesn't exist
|
|
110
|
+
if (!fs.existsSync(configDir)) {
|
|
111
|
+
fs.mkdirSync(configDir, { recursive: true });
|
|
112
|
+
}
|
|
113
|
+
fs.writeFileSync(configPath, JSON.stringify(config, null, 2) + '\n', 'utf-8');
|
|
114
|
+
}
|
|
115
|
+
//# sourceMappingURL=global-config.js.map
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
// Core LightSpec logic will be implemented here
|
|
2
|
+
export { GLOBAL_CONFIG_DIR_NAME, GLOBAL_CONFIG_FILE_NAME, GLOBAL_DATA_DIR_NAME, getGlobalConfigDir, getGlobalConfigPath, getGlobalConfig, saveGlobalConfig, getGlobalDataDir } from './global-config.js';
|
|
3
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
type ToolLabel = {
|
|
2
|
+
primary: string;
|
|
3
|
+
annotation?: string;
|
|
4
|
+
};
|
|
5
|
+
type ToolWizardChoice = {
|
|
6
|
+
kind: 'heading' | 'info';
|
|
7
|
+
value: string;
|
|
8
|
+
label: ToolLabel;
|
|
9
|
+
selectable: false;
|
|
10
|
+
} | {
|
|
11
|
+
kind: 'option';
|
|
12
|
+
value: string;
|
|
13
|
+
label: ToolLabel;
|
|
14
|
+
configured: boolean;
|
|
15
|
+
selectable: true;
|
|
16
|
+
};
|
|
17
|
+
type ToolWizardConfig = {
|
|
18
|
+
extendMode: boolean;
|
|
19
|
+
baseMessage: string;
|
|
20
|
+
choices: ToolWizardChoice[];
|
|
21
|
+
initialSelected?: string[];
|
|
22
|
+
};
|
|
23
|
+
type ToolSelectionPrompt = (config: ToolWizardConfig) => Promise<string[]>;
|
|
24
|
+
type InitCommandOptions = {
|
|
25
|
+
prompt?: ToolSelectionPrompt;
|
|
26
|
+
tools?: string;
|
|
27
|
+
};
|
|
28
|
+
export declare class InitCommand {
|
|
29
|
+
private readonly prompt;
|
|
30
|
+
private readonly toolsArg?;
|
|
31
|
+
constructor(options?: InitCommandOptions);
|
|
32
|
+
execute(targetPath: string): Promise<void>;
|
|
33
|
+
private validate;
|
|
34
|
+
private getConfiguration;
|
|
35
|
+
private getSelectedTools;
|
|
36
|
+
private resolveToolsArg;
|
|
37
|
+
private promptForAITools;
|
|
38
|
+
private getExistingToolStates;
|
|
39
|
+
private isToolConfigured;
|
|
40
|
+
private createDirectoryStructure;
|
|
41
|
+
private generateFiles;
|
|
42
|
+
private ensureTemplateFiles;
|
|
43
|
+
private writeTemplateFiles;
|
|
44
|
+
private configureAITools;
|
|
45
|
+
private configureRootAgentsStub;
|
|
46
|
+
private displaySuccessMessage;
|
|
47
|
+
private formatToolNames;
|
|
48
|
+
private renderBanner;
|
|
49
|
+
private startSpinner;
|
|
50
|
+
}
|
|
51
|
+
export {};
|
|
52
|
+
//# sourceMappingURL=init.d.ts.map
|