@intoinside/praxis 1.0.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.
Files changed (61) hide show
  1. package/CODE_OF_CONDUCT.md +99 -0
  2. package/CONTRIBUTING.md +108 -0
  3. package/LICENSE +21 -0
  4. package/MAINTAINERS.md +9 -0
  5. package/README.md +319 -0
  6. package/intoinside-praxis-1.0.0.tgz +0 -0
  7. package/last_error.txt +42 -0
  8. package/package.json +40 -0
  9. package/src/commands/init.d.ts +1 -0
  10. package/src/commands/init.js +42 -0
  11. package/src/commands/init.ts +47 -0
  12. package/src/commands/integration/generate.d.ts +4 -0
  13. package/src/commands/integration/generate.js +69 -0
  14. package/src/commands/integration/generate.ts +85 -0
  15. package/src/commands/intent/create.d.ts +4 -0
  16. package/src/commands/intent/create.js +55 -0
  17. package/src/commands/intent/create.ts +61 -0
  18. package/src/commands/intent/list.d.ts +4 -0
  19. package/src/commands/intent/list.js +52 -0
  20. package/src/commands/intent/list.ts +63 -0
  21. package/src/commands/spec/apply.d.ts +4 -0
  22. package/src/commands/spec/apply.js +99 -0
  23. package/src/commands/spec/apply.ts +109 -0
  24. package/src/commands/spec/archive.d.ts +4 -0
  25. package/src/commands/spec/archive.js +114 -0
  26. package/src/commands/spec/archive.ts +121 -0
  27. package/src/commands/spec/delete.d.ts +4 -0
  28. package/src/commands/spec/delete.js +70 -0
  29. package/src/commands/spec/delete.ts +75 -0
  30. package/src/commands/spec/derive.d.ts +6 -0
  31. package/src/commands/spec/derive.js +107 -0
  32. package/src/commands/spec/derive.ts +117 -0
  33. package/src/core/command-generation/adapters/antigravity.d.ts +12 -0
  34. package/src/core/command-generation/adapters/antigravity.js +25 -0
  35. package/src/core/command-generation/adapters/antigravity.ts +30 -0
  36. package/src/core/command-generation/adapters/index.d.ts +6 -0
  37. package/src/core/command-generation/adapters/index.js +26 -0
  38. package/src/core/command-generation/adapters/index.ts +27 -0
  39. package/src/core/command-generation/generator.d.ts +20 -0
  40. package/src/core/command-generation/generator.js +26 -0
  41. package/src/core/command-generation/generator.ts +36 -0
  42. package/src/core/command-generation/index.d.ts +20 -0
  43. package/src/core/command-generation/index.js +23 -0
  44. package/src/core/command-generation/index.ts +33 -0
  45. package/src/core/command-generation/registry.d.ts +35 -0
  46. package/src/core/command-generation/registry.js +87 -0
  47. package/src/core/command-generation/registry.ts +95 -0
  48. package/src/core/command-generation/types.d.ts +54 -0
  49. package/src/core/command-generation/types.js +7 -0
  50. package/src/core/command-generation/types.ts +57 -0
  51. package/src/index.d.ts +2 -0
  52. package/src/index.js +95 -0
  53. package/src/index.ts +97 -0
  54. package/src/manifest.d.ts +21 -0
  55. package/src/manifest.js +170 -0
  56. package/src/manifest.ts +188 -0
  57. package/templates/checklist-template.md +42 -0
  58. package/templates/intent-template.md +290 -0
  59. package/templates/spec-template.md +114 -0
  60. package/test_output.txt +0 -0
  61. package/tsconfig.json +20 -0
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Command Adapters Index
3
+ *
4
+ * Re-exports all tool command adapters.
5
+ */
6
+ export { antigravityAdapter } from './antigravity.js';
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Command Adapters Index
3
+ *
4
+ * Re-exports all tool command adapters.
5
+ */
6
+ // export { amazonQAdapter } from './amazon-q.js';
7
+ export { antigravityAdapter } from './antigravity.js';
8
+ // export { auggieAdapter } from './auggie.js';
9
+ // export { claudeAdapter } from './claude.js';
10
+ // export { clineAdapter } from './cline.js';
11
+ // export { codexAdapter } from './codex.js';
12
+ // export { codebuddyAdapter } from './codebuddy.js';
13
+ // export { continueAdapter } from './continue.js';
14
+ // export { costrictAdapter } from './costrict.js';
15
+ // export { crushAdapter } from './crush.js';
16
+ // export { cursorAdapter } from './cursor.js';
17
+ // export { factoryAdapter } from './factory.js';
18
+ // export { geminiAdapter } from './gemini.js';
19
+ // export { githubCopilotAdapter } from './github-copilot.js';
20
+ // export { iflowAdapter } from './iflow.js';
21
+ // export { kilocodeAdapter } from './kilocode.js';
22
+ // export { opencodeAdapter } from './opencode.js';
23
+ // export { qoderAdapter } from './qoder.js';
24
+ // export { qwenAdapter } from './qwen.js';
25
+ // export { roocodeAdapter } from './roocode.js';
26
+ // export { windsurfAdapter } from './windsurf.js';
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Command Adapters Index
3
+ *
4
+ * Re-exports all tool command adapters.
5
+ */
6
+
7
+ // export { amazonQAdapter } from './amazon-q.js';
8
+ export { antigravityAdapter } from './antigravity.js';
9
+ // export { auggieAdapter } from './auggie.js';
10
+ // export { claudeAdapter } from './claude.js';
11
+ // export { clineAdapter } from './cline.js';
12
+ // export { codexAdapter } from './codex.js';
13
+ // export { codebuddyAdapter } from './codebuddy.js';
14
+ // export { continueAdapter } from './continue.js';
15
+ // export { costrictAdapter } from './costrict.js';
16
+ // export { crushAdapter } from './crush.js';
17
+ // export { cursorAdapter } from './cursor.js';
18
+ // export { factoryAdapter } from './factory.js';
19
+ // export { geminiAdapter } from './gemini.js';
20
+ // export { githubCopilotAdapter } from './github-copilot.js';
21
+ // export { iflowAdapter } from './iflow.js';
22
+ // export { kilocodeAdapter } from './kilocode.js';
23
+ // export { opencodeAdapter } from './opencode.js';
24
+ // export { qoderAdapter } from './qoder.js';
25
+ // export { qwenAdapter } from './qwen.js';
26
+ // export { roocodeAdapter } from './roocode.js';
27
+ // export { windsurfAdapter } from './windsurf.js';
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Command Generator
3
+ *
4
+ * Functions for generating command files using tool adapters.
5
+ */
6
+ import type { CommandContent, ToolCommandAdapter, GeneratedCommand } from './types.js';
7
+ /**
8
+ * Generate a single command file using the provided adapter.
9
+ * @param content - The tool-agnostic command content
10
+ * @param adapter - The tool-specific adapter
11
+ * @returns Generated command with path and file content
12
+ */
13
+ export declare function generateCommand(content: CommandContent, adapter: ToolCommandAdapter): GeneratedCommand;
14
+ /**
15
+ * Generate multiple command files using the provided adapter.
16
+ * @param contents - Array of tool-agnostic command contents
17
+ * @param adapter - The tool-specific adapter
18
+ * @returns Array of generated commands with paths and file contents
19
+ */
20
+ export declare function generateCommands(contents: CommandContent[], adapter: ToolCommandAdapter): GeneratedCommand[];
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Command Generator
3
+ *
4
+ * Functions for generating command files using tool adapters.
5
+ */
6
+ /**
7
+ * Generate a single command file using the provided adapter.
8
+ * @param content - The tool-agnostic command content
9
+ * @param adapter - The tool-specific adapter
10
+ * @returns Generated command with path and file content
11
+ */
12
+ export function generateCommand(content, adapter) {
13
+ return {
14
+ path: adapter.getFilePath(content.id),
15
+ fileContent: adapter.formatFile(content),
16
+ };
17
+ }
18
+ /**
19
+ * Generate multiple command files using the provided adapter.
20
+ * @param contents - Array of tool-agnostic command contents
21
+ * @param adapter - The tool-specific adapter
22
+ * @returns Array of generated commands with paths and file contents
23
+ */
24
+ export function generateCommands(contents, adapter) {
25
+ return contents.map((content) => generateCommand(content, adapter));
26
+ }
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Command Generator
3
+ *
4
+ * Functions for generating command files using tool adapters.
5
+ */
6
+
7
+ import type { CommandContent, ToolCommandAdapter, GeneratedCommand } from './types.js';
8
+
9
+ /**
10
+ * Generate a single command file using the provided adapter.
11
+ * @param content - The tool-agnostic command content
12
+ * @param adapter - The tool-specific adapter
13
+ * @returns Generated command with path and file content
14
+ */
15
+ export function generateCommand(
16
+ content: CommandContent,
17
+ adapter: ToolCommandAdapter
18
+ ): GeneratedCommand {
19
+ return {
20
+ path: adapter.getFilePath(content.id),
21
+ fileContent: adapter.formatFile(content),
22
+ };
23
+ }
24
+
25
+ /**
26
+ * Generate multiple command files using the provided adapter.
27
+ * @param contents - Array of tool-agnostic command contents
28
+ * @param adapter - The tool-specific adapter
29
+ * @returns Array of generated commands with paths and file contents
30
+ */
31
+ export function generateCommands(
32
+ contents: CommandContent[],
33
+ adapter: ToolCommandAdapter
34
+ ): GeneratedCommand[] {
35
+ return contents.map((content) => generateCommand(content, adapter));
36
+ }
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Command Generation Module
3
+ *
4
+ * Generic command generation system with tool-specific adapters.
5
+ *
6
+ * Usage:
7
+ * ```typescript
8
+ * import { generateCommands, CommandAdapterRegistry, type CommandContent } from './command-generation/index.js';
9
+ *
10
+ * const contents: CommandContent[] = [...];
11
+ * const adapter = CommandAdapterRegistry.get('cursor');
12
+ * if (adapter) {
13
+ * const commands = generateCommands(contents, adapter);
14
+ * // Write commands to disk
15
+ * }
16
+ * ```
17
+ */
18
+ export type { CommandContent, ToolCommandAdapter, GeneratedCommand, } from './types.js';
19
+ export { CommandAdapterRegistry } from './registry.js';
20
+ export { generateCommand, generateCommands } from './generator.js';
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Command Generation Module
3
+ *
4
+ * Generic command generation system with tool-specific adapters.
5
+ *
6
+ * Usage:
7
+ * ```typescript
8
+ * import { generateCommands, CommandAdapterRegistry, type CommandContent } from './command-generation/index.js';
9
+ *
10
+ * const contents: CommandContent[] = [...];
11
+ * const adapter = CommandAdapterRegistry.get('cursor');
12
+ * if (adapter) {
13
+ * const commands = generateCommands(contents, adapter);
14
+ * // Write commands to disk
15
+ * }
16
+ * ```
17
+ */
18
+ // Registry
19
+ export { CommandAdapterRegistry } from './registry.js';
20
+ // Generator functions
21
+ export { generateCommand, generateCommands } from './generator.js';
22
+ // Adapters (for direct access if needed)
23
+ // export { claudeAdapter, cursorAdapter, windsurfAdapter } from './adapters/index.js';
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Command Generation Module
3
+ *
4
+ * Generic command generation system with tool-specific adapters.
5
+ *
6
+ * Usage:
7
+ * ```typescript
8
+ * import { generateCommands, CommandAdapterRegistry, type CommandContent } from './command-generation/index.js';
9
+ *
10
+ * const contents: CommandContent[] = [...];
11
+ * const adapter = CommandAdapterRegistry.get('cursor');
12
+ * if (adapter) {
13
+ * const commands = generateCommands(contents, adapter);
14
+ * // Write commands to disk
15
+ * }
16
+ * ```
17
+ */
18
+
19
+ // Types
20
+ export type {
21
+ CommandContent,
22
+ ToolCommandAdapter,
23
+ GeneratedCommand,
24
+ } from './types.js';
25
+
26
+ // Registry
27
+ export { CommandAdapterRegistry } from './registry.js';
28
+
29
+ // Generator functions
30
+ export { generateCommand, generateCommands } from './generator.js';
31
+
32
+ // Adapters (for direct access if needed)
33
+ // export { claudeAdapter, cursorAdapter, windsurfAdapter } from './adapters/index.js';
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Command Adapter Registry
3
+ *
4
+ * Centralized registry for tool command adapters.
5
+ * Similar pattern to existing SlashCommandRegistry in the codebase.
6
+ */
7
+ import type { ToolCommandAdapter } from './types.js';
8
+ /**
9
+ * Registry for looking up tool command adapters.
10
+ */
11
+ export declare class CommandAdapterRegistry {
12
+ private static adapters;
13
+ /**
14
+ * Register a tool command adapter.
15
+ * @param adapter - The adapter to register
16
+ */
17
+ static register(adapter: ToolCommandAdapter): void;
18
+ /**
19
+ * Get an adapter by tool ID.
20
+ * @param toolId - The tool identifier (e.g., 'claude', 'cursor')
21
+ * @returns The adapter or undefined if not registered
22
+ */
23
+ static get(toolId: string): ToolCommandAdapter | undefined;
24
+ /**
25
+ * Get all registered adapters.
26
+ * @returns Array of all registered adapters
27
+ */
28
+ static getAll(): ToolCommandAdapter[];
29
+ /**
30
+ * Check if an adapter is registered for a tool.
31
+ * @param toolId - The tool identifier
32
+ * @returns True if an adapter exists
33
+ */
34
+ static has(toolId: string): boolean;
35
+ }
@@ -0,0 +1,87 @@
1
+ /**
2
+ * Command Adapter Registry
3
+ *
4
+ * Centralized registry for tool command adapters.
5
+ * Similar pattern to existing SlashCommandRegistry in the codebase.
6
+ */
7
+ // import { amazonQAdapter } from './adapters/amazon-q.js';
8
+ import { antigravityAdapter } from './adapters/antigravity.js';
9
+ // import { auggieAdapter } from './adapters/auggie.js';
10
+ // import { claudeAdapter } from './adapters/claude.js';
11
+ // import { clineAdapter } from './adapters/cline.js';
12
+ // import { codexAdapter } from './adapters/codex.js';
13
+ // import { codebuddyAdapter } from './adapters/codebuddy.js';
14
+ // import { continueAdapter } from './adapters/continue.js';
15
+ // import { costrictAdapter } from './adapters/costrict.js';
16
+ // import { crushAdapter } from './adapters/crush.js';
17
+ // import { cursorAdapter } from './adapters/cursor.js';
18
+ // import { factoryAdapter } from './adapters/factory.js';
19
+ // import { geminiAdapter } from './adapters/gemini.js';
20
+ // import { githubCopilotAdapter } from './adapters/github-copilot.js';
21
+ // import { iflowAdapter } from './adapters/iflow.js';
22
+ // import { kilocodeAdapter } from './adapters/kilocode.js';
23
+ // import { opencodeAdapter } from './adapters/opencode.js';
24
+ // import { qoderAdapter } from './adapters/qoder.js';
25
+ // import { qwenAdapter } from './adapters/qwen.js';
26
+ // import { roocodeAdapter } from './adapters/roocode.js';
27
+ // import { windsurfAdapter } from './adapters/windsurf.js';
28
+ /**
29
+ * Registry for looking up tool command adapters.
30
+ */
31
+ export class CommandAdapterRegistry {
32
+ static adapters = new Map();
33
+ // Static initializer - register built-in adapters
34
+ static {
35
+ // CommandAdapterRegistry.register(amazonQAdapter);
36
+ CommandAdapterRegistry.register(antigravityAdapter);
37
+ // CommandAdapterRegistry.register(auggieAdapter);
38
+ // CommandAdapterRegistry.register(claudeAdapter);
39
+ // CommandAdapterRegistry.register(clineAdapter);
40
+ // CommandAdapterRegistry.register(codexAdapter);
41
+ // CommandAdapterRegistry.register(codebuddyAdapter);
42
+ // CommandAdapterRegistry.register(continueAdapter);
43
+ // CommandAdapterRegistry.register(costrictAdapter);
44
+ // CommandAdapterRegistry.register(crushAdapter);
45
+ // CommandAdapterRegistry.register(cursorAdapter);
46
+ // CommandAdapterRegistry.register(factoryAdapter);
47
+ // CommandAdapterRegistry.register(geminiAdapter);
48
+ // CommandAdapterRegistry.register(githubCopilotAdapter);
49
+ // CommandAdapterRegistry.register(iflowAdapter);
50
+ // CommandAdapterRegistry.register(kilocodeAdapter);
51
+ // CommandAdapterRegistry.register(opencodeAdapter);
52
+ // CommandAdapterRegistry.register(qoderAdapter);
53
+ // CommandAdapterRegistry.register(qwenAdapter);
54
+ // CommandAdapterRegistry.register(roocodeAdapter);
55
+ // CommandAdapterRegistry.register(windsurfAdapter);
56
+ }
57
+ /**
58
+ * Register a tool command adapter.
59
+ * @param adapter - The adapter to register
60
+ */
61
+ static register(adapter) {
62
+ CommandAdapterRegistry.adapters.set(adapter.toolId, adapter);
63
+ }
64
+ /**
65
+ * Get an adapter by tool ID.
66
+ * @param toolId - The tool identifier (e.g., 'claude', 'cursor')
67
+ * @returns The adapter or undefined if not registered
68
+ */
69
+ static get(toolId) {
70
+ return CommandAdapterRegistry.adapters.get(toolId);
71
+ }
72
+ /**
73
+ * Get all registered adapters.
74
+ * @returns Array of all registered adapters
75
+ */
76
+ static getAll() {
77
+ return Array.from(CommandAdapterRegistry.adapters.values());
78
+ }
79
+ /**
80
+ * Check if an adapter is registered for a tool.
81
+ * @param toolId - The tool identifier
82
+ * @returns True if an adapter exists
83
+ */
84
+ static has(toolId) {
85
+ return CommandAdapterRegistry.adapters.has(toolId);
86
+ }
87
+ }
@@ -0,0 +1,95 @@
1
+ /**
2
+ * Command Adapter Registry
3
+ *
4
+ * Centralized registry for tool command adapters.
5
+ * Similar pattern to existing SlashCommandRegistry in the codebase.
6
+ */
7
+
8
+ import type { ToolCommandAdapter } from './types.js';
9
+ // import { amazonQAdapter } from './adapters/amazon-q.js';
10
+ import { antigravityAdapter } from './adapters/antigravity.js';
11
+ // import { auggieAdapter } from './adapters/auggie.js';
12
+ // import { claudeAdapter } from './adapters/claude.js';
13
+ // import { clineAdapter } from './adapters/cline.js';
14
+ // import { codexAdapter } from './adapters/codex.js';
15
+ // import { codebuddyAdapter } from './adapters/codebuddy.js';
16
+ // import { continueAdapter } from './adapters/continue.js';
17
+ // import { costrictAdapter } from './adapters/costrict.js';
18
+ // import { crushAdapter } from './adapters/crush.js';
19
+ // import { cursorAdapter } from './adapters/cursor.js';
20
+ // import { factoryAdapter } from './adapters/factory.js';
21
+ // import { geminiAdapter } from './adapters/gemini.js';
22
+ // import { githubCopilotAdapter } from './adapters/github-copilot.js';
23
+ // import { iflowAdapter } from './adapters/iflow.js';
24
+ // import { kilocodeAdapter } from './adapters/kilocode.js';
25
+ // import { opencodeAdapter } from './adapters/opencode.js';
26
+ // import { qoderAdapter } from './adapters/qoder.js';
27
+ // import { qwenAdapter } from './adapters/qwen.js';
28
+ // import { roocodeAdapter } from './adapters/roocode.js';
29
+ // import { windsurfAdapter } from './adapters/windsurf.js';
30
+
31
+ /**
32
+ * Registry for looking up tool command adapters.
33
+ */
34
+ export class CommandAdapterRegistry {
35
+ private static adapters: Map<string, ToolCommandAdapter> = new Map();
36
+
37
+ // Static initializer - register built-in adapters
38
+ static {
39
+ // CommandAdapterRegistry.register(amazonQAdapter);
40
+ CommandAdapterRegistry.register(antigravityAdapter);
41
+ // CommandAdapterRegistry.register(auggieAdapter);
42
+ // CommandAdapterRegistry.register(claudeAdapter);
43
+ // CommandAdapterRegistry.register(clineAdapter);
44
+ // CommandAdapterRegistry.register(codexAdapter);
45
+ // CommandAdapterRegistry.register(codebuddyAdapter);
46
+ // CommandAdapterRegistry.register(continueAdapter);
47
+ // CommandAdapterRegistry.register(costrictAdapter);
48
+ // CommandAdapterRegistry.register(crushAdapter);
49
+ // CommandAdapterRegistry.register(cursorAdapter);
50
+ // CommandAdapterRegistry.register(factoryAdapter);
51
+ // CommandAdapterRegistry.register(geminiAdapter);
52
+ // CommandAdapterRegistry.register(githubCopilotAdapter);
53
+ // CommandAdapterRegistry.register(iflowAdapter);
54
+ // CommandAdapterRegistry.register(kilocodeAdapter);
55
+ // CommandAdapterRegistry.register(opencodeAdapter);
56
+ // CommandAdapterRegistry.register(qoderAdapter);
57
+ // CommandAdapterRegistry.register(qwenAdapter);
58
+ // CommandAdapterRegistry.register(roocodeAdapter);
59
+ // CommandAdapterRegistry.register(windsurfAdapter);
60
+ }
61
+
62
+ /**
63
+ * Register a tool command adapter.
64
+ * @param adapter - The adapter to register
65
+ */
66
+ static register(adapter: ToolCommandAdapter): void {
67
+ CommandAdapterRegistry.adapters.set(adapter.toolId, adapter);
68
+ }
69
+
70
+ /**
71
+ * Get an adapter by tool ID.
72
+ * @param toolId - The tool identifier (e.g., 'claude', 'cursor')
73
+ * @returns The adapter or undefined if not registered
74
+ */
75
+ static get(toolId: string): ToolCommandAdapter | undefined {
76
+ return CommandAdapterRegistry.adapters.get(toolId);
77
+ }
78
+
79
+ /**
80
+ * Get all registered adapters.
81
+ * @returns Array of all registered adapters
82
+ */
83
+ static getAll(): ToolCommandAdapter[] {
84
+ return Array.from(CommandAdapterRegistry.adapters.values());
85
+ }
86
+
87
+ /**
88
+ * Check if an adapter is registered for a tool.
89
+ * @param toolId - The tool identifier
90
+ * @returns True if an adapter exists
91
+ */
92
+ static has(toolId: string): boolean {
93
+ return CommandAdapterRegistry.adapters.has(toolId);
94
+ }
95
+ }
@@ -0,0 +1,54 @@
1
+ /**
2
+ * Command Generation Types
3
+ *
4
+ * Tool-agnostic interfaces for command generation.
5
+ * These types separate "what to generate" from "how to format it".
6
+ */
7
+ /**
8
+ * Tool-agnostic command data.
9
+ * Represents the content of a command without any tool-specific formatting.
10
+ */
11
+ export interface CommandContent {
12
+ /** Command identifier (e.g., 'explore', 'apply', 'new') */
13
+ id: string;
14
+ /** Human-readable name (e.g., 'OpenSpec Explore') */
15
+ name: string;
16
+ /** Brief description of command purpose */
17
+ description: string;
18
+ /** Grouping category (e.g., 'Workflow') */
19
+ category: string;
20
+ /** Array of tag strings */
21
+ tags: string[];
22
+ /** The command instruction content (body text) */
23
+ body: string;
24
+ }
25
+ /**
26
+ * Per-tool formatting strategy.
27
+ * Each AI tool implements this interface to handle its specific file path
28
+ * and frontmatter format requirements.
29
+ */
30
+ export interface ToolCommandAdapter {
31
+ /** Tool identifier matching AIToolOption.value (e.g., 'claude', 'cursor') */
32
+ toolId: string;
33
+ /**
34
+ * Returns the relative file path for a command.
35
+ * @param commandId - The command identifier (e.g., 'explore')
36
+ * @returns Relative path from project root (e.g., '.claude/commands/praxis/explore.md')
37
+ */
38
+ getFilePath(commandId: string): string;
39
+ /**
40
+ * Formats the complete file content including frontmatter.
41
+ * @param content - The tool-agnostic command content
42
+ * @returns Complete file content ready to write
43
+ */
44
+ formatFile(content: CommandContent): string;
45
+ }
46
+ /**
47
+ * Result of generating a command file.
48
+ */
49
+ export interface GeneratedCommand {
50
+ /** Relative file path from project root */
51
+ path: string;
52
+ /** Complete file content (frontmatter + body) */
53
+ fileContent: string;
54
+ }
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Command Generation Types
3
+ *
4
+ * Tool-agnostic interfaces for command generation.
5
+ * These types separate "what to generate" from "how to format it".
6
+ */
7
+ export {};
@@ -0,0 +1,57 @@
1
+ /**
2
+ * Command Generation Types
3
+ *
4
+ * Tool-agnostic interfaces for command generation.
5
+ * These types separate "what to generate" from "how to format it".
6
+ */
7
+
8
+ /**
9
+ * Tool-agnostic command data.
10
+ * Represents the content of a command without any tool-specific formatting.
11
+ */
12
+ export interface CommandContent {
13
+ /** Command identifier (e.g., 'explore', 'apply', 'new') */
14
+ id: string;
15
+ /** Human-readable name (e.g., 'OpenSpec Explore') */
16
+ name: string;
17
+ /** Brief description of command purpose */
18
+ description: string;
19
+ /** Grouping category (e.g., 'Workflow') */
20
+ category: string;
21
+ /** Array of tag strings */
22
+ tags: string[];
23
+ /** The command instruction content (body text) */
24
+ body: string;
25
+ }
26
+
27
+ /**
28
+ * Per-tool formatting strategy.
29
+ * Each AI tool implements this interface to handle its specific file path
30
+ * and frontmatter format requirements.
31
+ */
32
+ export interface ToolCommandAdapter {
33
+ /** Tool identifier matching AIToolOption.value (e.g., 'claude', 'cursor') */
34
+ toolId: string;
35
+ /**
36
+ * Returns the relative file path for a command.
37
+ * @param commandId - The command identifier (e.g., 'explore')
38
+ * @returns Relative path from project root (e.g., '.claude/commands/praxis/explore.md')
39
+ */
40
+ getFilePath(commandId: string): string;
41
+ /**
42
+ * Formats the complete file content including frontmatter.
43
+ * @param content - The tool-agnostic command content
44
+ * @returns Complete file content ready to write
45
+ */
46
+ formatFile(content: CommandContent): string;
47
+ }
48
+
49
+ /**
50
+ * Result of generating a command file.
51
+ */
52
+ export interface GeneratedCommand {
53
+ /** Relative file path from project root */
54
+ path: string;
55
+ /** Complete file content (frontmatter + body) */
56
+ fileContent: string;
57
+ }
package/src/index.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
package/src/index.js ADDED
@@ -0,0 +1,95 @@
1
+ #!/usr/bin/env node
2
+ import { Command } from 'commander';
3
+ import { manifest } from './manifest.js';
4
+ import { initCommand } from './commands/init.js';
5
+ import { intentCreateAction } from './commands/intent/create.js';
6
+ import { intentListAction } from './commands/intent/list.js';
7
+ import { generateSlashCommandsAction } from './commands/integration/generate.js';
8
+ import { specDeriveAction } from './commands/spec/derive.js';
9
+ import { specDeleteAction } from './commands/spec/delete.js';
10
+ import { specApplyAction } from './commands/spec/apply.js';
11
+ import { specArchiveAction } from './commands/spec/archive.js';
12
+ const program = new Command();
13
+ program
14
+ .name('praxis')
15
+ .description('Praxis: Intent-First Development Framework')
16
+ .version('1.0.0');
17
+ // Dynamically build commands from manifest
18
+ manifest.forEach((cmdDef) => {
19
+ const cmd = program.command(cmdDef.name).description(cmdDef.description);
20
+ if (cmdDef.subcommands) {
21
+ cmdDef.subcommands.forEach((subCmdDef) => {
22
+ const subCmd = cmd.command(subCmdDef.name).description(subCmdDef.description);
23
+ if (subCmdDef.arguments) {
24
+ subCmdDef.arguments.forEach(arg => {
25
+ const argStr = arg.required ? `<${arg.name}>` : `[${arg.name}]`;
26
+ subCmd.argument(argStr, arg.description);
27
+ });
28
+ }
29
+ if (subCmdDef.options) {
30
+ subCmdDef.options.forEach(opt => {
31
+ const flag = opt.required ? `<${opt.name}>` : `[${opt.name}]`;
32
+ subCmd.option(opt.alias ? `-${opt.alias}, --${opt.name} ${flag}` : `--${opt.name} ${flag}`, opt.description);
33
+ });
34
+ }
35
+ subCmd.action(async (...args) => {
36
+ if (cmdDef.name === 'intent' && subCmdDef.name === 'create') {
37
+ const [description] = args;
38
+ await intentCreateAction(description);
39
+ }
40
+ else if (cmdDef.name === 'intent' && subCmdDef.name === 'list') {
41
+ await intentListAction();
42
+ }
43
+ else if (cmdDef.name === 'integration' && subCmdDef.name === 'generate-slash-commands') {
44
+ const [tool] = args;
45
+ await generateSlashCommandsAction(tool);
46
+ }
47
+ else if (cmdDef.name === 'spec' && subCmdDef.name === 'derive') {
48
+ const [options] = args;
49
+ await specDeriveAction(options);
50
+ }
51
+ else if (cmdDef.name === 'spec' && subCmdDef.name === 'delete') {
52
+ const [specId] = args;
53
+ await specDeleteAction(specId);
54
+ }
55
+ else if (cmdDef.name === 'spec' && subCmdDef.name === 'apply') {
56
+ const [specId] = args;
57
+ await specApplyAction(specId);
58
+ }
59
+ else if (cmdDef.name === 'spec' && subCmdDef.name === 'archive') {
60
+ const [specId] = args;
61
+ await specArchiveAction(specId);
62
+ }
63
+ else {
64
+ console.log(`Executing ${cmdDef.name} ${subCmdDef.name}...`);
65
+ // Implementation will go here
66
+ }
67
+ });
68
+ });
69
+ }
70
+ else {
71
+ // Top-level command with no subcommands
72
+ if (cmdDef.arguments) {
73
+ cmdDef.arguments.forEach(arg => {
74
+ const argStr = arg.required ? `<${arg.name}>` : `[${arg.name}]`;
75
+ cmd.argument(argStr, arg.description);
76
+ });
77
+ }
78
+ if (cmdDef.options) {
79
+ cmdDef.options.forEach(opt => {
80
+ const flag = opt.required ? `<${opt.name}>` : `[${opt.name}]`;
81
+ cmd.option(opt.alias ? `-${opt.alias}, --${opt.name} ${flag}` : `--${opt.name} ${flag}`, opt.description);
82
+ });
83
+ }
84
+ cmd.action(async () => {
85
+ if (cmdDef.name === 'init') {
86
+ await initCommand();
87
+ }
88
+ else {
89
+ console.log(`Executing ${cmdDef.name}...`);
90
+ // Implementation will go here
91
+ }
92
+ });
93
+ }
94
+ });
95
+ program.parse();