sxn 0.2.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.
- checksums.yaml +7 -0
- data/.gem_rbs_collection/addressable/2.8/.rbs_meta.yaml +9 -0
- data/.gem_rbs_collection/addressable/2.8/addressable.rbs +62 -0
- data/.gem_rbs_collection/async/2.12/.rbs_meta.yaml +9 -0
- data/.gem_rbs_collection/async/2.12/async.rbs +119 -0
- data/.gem_rbs_collection/async/2.12/kernel.rbs +5 -0
- data/.gem_rbs_collection/async/2.12/manifest.yaml +7 -0
- data/.gem_rbs_collection/bcrypt/3.1/.rbs_meta.yaml +9 -0
- data/.gem_rbs_collection/bcrypt/3.1/bcrypt.rbs +47 -0
- data/.gem_rbs_collection/bcrypt/3.1/manifest.yaml +2 -0
- data/.gem_rbs_collection/bigdecimal/3.1/.rbs_meta.yaml +9 -0
- data/.gem_rbs_collection/bigdecimal/3.1/bigdecimal-math.rbs +119 -0
- data/.gem_rbs_collection/bigdecimal/3.1/bigdecimal.rbs +1630 -0
- data/.gem_rbs_collection/concurrent-ruby/1.1/.rbs_meta.yaml +9 -0
- data/.gem_rbs_collection/concurrent-ruby/1.1/array.rbs +4 -0
- data/.gem_rbs_collection/concurrent-ruby/1.1/executor.rbs +26 -0
- data/.gem_rbs_collection/concurrent-ruby/1.1/hash.rbs +4 -0
- data/.gem_rbs_collection/concurrent-ruby/1.1/map.rbs +65 -0
- data/.gem_rbs_collection/concurrent-ruby/1.1/promises.rbs +249 -0
- data/.gem_rbs_collection/concurrent-ruby/1.1/utility/processor_counter.rbs +5 -0
- data/.gem_rbs_collection/diff-lcs/1.5/.rbs_meta.yaml +9 -0
- data/.gem_rbs_collection/diff-lcs/1.5/diff-lcs.rbs +11 -0
- data/.gem_rbs_collection/listen/3.9/.rbs_meta.yaml +9 -0
- data/.gem_rbs_collection/listen/3.9/listen.rbs +25 -0
- data/.gem_rbs_collection/listen/3.9/listener.rbs +24 -0
- data/.gem_rbs_collection/mini_mime/0.1/.rbs_meta.yaml +9 -0
- data/.gem_rbs_collection/mini_mime/0.1/mini_mime.rbs +14 -0
- data/.gem_rbs_collection/parallel/1.20/.rbs_meta.yaml +9 -0
- data/.gem_rbs_collection/parallel/1.20/parallel.rbs +86 -0
- data/.gem_rbs_collection/rake/13.0/.rbs_meta.yaml +9 -0
- data/.gem_rbs_collection/rake/13.0/manifest.yaml +2 -0
- data/.gem_rbs_collection/rake/13.0/rake.rbs +39 -0
- data/.gem_rbs_collection/rubocop-ast/1.46/.rbs_meta.yaml +9 -0
- data/.gem_rbs_collection/rubocop-ast/1.46/rubocop-ast.rbs +822 -0
- data/.gem_rbs_collection/sqlite3/2.0/.rbs_meta.yaml +9 -0
- data/.gem_rbs_collection/sqlite3/2.0/database.rbs +20 -0
- data/.gem_rbs_collection/sqlite3/2.0/pragmas.rbs +5 -0
- data/.rspec +4 -0
- data/.rubocop.yml +121 -0
- data/.simplecov +51 -0
- data/CHANGELOG.md +49 -0
- data/Gemfile +24 -0
- data/Gemfile.lock +329 -0
- data/LICENSE.txt +21 -0
- data/README.md +225 -0
- data/Rakefile +54 -0
- data/Steepfile +50 -0
- data/bin/sxn +6 -0
- data/lib/sxn/CLI.rb +275 -0
- data/lib/sxn/commands/init.rb +137 -0
- data/lib/sxn/commands/projects.rb +350 -0
- data/lib/sxn/commands/rules.rb +435 -0
- data/lib/sxn/commands/sessions.rb +300 -0
- data/lib/sxn/commands/worktrees.rb +416 -0
- data/lib/sxn/commands.rb +13 -0
- data/lib/sxn/config/config_cache.rb +295 -0
- data/lib/sxn/config/config_discovery.rb +242 -0
- data/lib/sxn/config/config_validator.rb +562 -0
- data/lib/sxn/config.rb +259 -0
- data/lib/sxn/core/config_manager.rb +290 -0
- data/lib/sxn/core/project_manager.rb +307 -0
- data/lib/sxn/core/rules_manager.rb +306 -0
- data/lib/sxn/core/session_manager.rb +336 -0
- data/lib/sxn/core/worktree_manager.rb +281 -0
- data/lib/sxn/core.rb +13 -0
- data/lib/sxn/database/errors.rb +29 -0
- data/lib/sxn/database/session_database.rb +691 -0
- data/lib/sxn/database.rb +24 -0
- data/lib/sxn/errors.rb +76 -0
- data/lib/sxn/rules/base_rule.rb +367 -0
- data/lib/sxn/rules/copy_files_rule.rb +346 -0
- data/lib/sxn/rules/errors.rb +28 -0
- data/lib/sxn/rules/project_detector.rb +871 -0
- data/lib/sxn/rules/rules_engine.rb +485 -0
- data/lib/sxn/rules/setup_commands_rule.rb +307 -0
- data/lib/sxn/rules/template_rule.rb +262 -0
- data/lib/sxn/rules.rb +148 -0
- data/lib/sxn/runtime_validations.rb +96 -0
- data/lib/sxn/security/secure_command_executor.rb +364 -0
- data/lib/sxn/security/secure_file_copier.rb +478 -0
- data/lib/sxn/security/secure_path_validator.rb +258 -0
- data/lib/sxn/security.rb +15 -0
- data/lib/sxn/templates/common/gitignore.liquid +99 -0
- data/lib/sxn/templates/common/session-info.md.liquid +58 -0
- data/lib/sxn/templates/errors.rb +36 -0
- data/lib/sxn/templates/javascript/README.md.liquid +59 -0
- data/lib/sxn/templates/javascript/session-info.md.liquid +206 -0
- data/lib/sxn/templates/rails/CLAUDE.md.liquid +78 -0
- data/lib/sxn/templates/rails/database.yml.liquid +31 -0
- data/lib/sxn/templates/rails/session-info.md.liquid +144 -0
- data/lib/sxn/templates/template_engine.rb +346 -0
- data/lib/sxn/templates/template_processor.rb +279 -0
- data/lib/sxn/templates/template_security.rb +410 -0
- data/lib/sxn/templates/template_variables.rb +713 -0
- data/lib/sxn/templates.rb +28 -0
- data/lib/sxn/ui/output.rb +103 -0
- data/lib/sxn/ui/progress_bar.rb +91 -0
- data/lib/sxn/ui/prompt.rb +116 -0
- data/lib/sxn/ui/table.rb +183 -0
- data/lib/sxn/ui.rb +12 -0
- data/lib/sxn/version.rb +5 -0
- data/lib/sxn.rb +63 -0
- data/rbs_collection.lock.yaml +180 -0
- data/rbs_collection.yaml +39 -0
- data/scripts/test.sh +31 -0
- data/sig/external/liquid.rbs +116 -0
- data/sig/external/thor.rbs +99 -0
- data/sig/external/tty.rbs +71 -0
- data/sig/sxn/cli.rbs +46 -0
- data/sig/sxn/commands/init.rbs +38 -0
- data/sig/sxn/commands/projects.rbs +72 -0
- data/sig/sxn/commands/rules.rbs +95 -0
- data/sig/sxn/commands/sessions.rbs +62 -0
- data/sig/sxn/commands/worktrees.rbs +82 -0
- data/sig/sxn/commands.rbs +6 -0
- data/sig/sxn/config/config_cache.rbs +67 -0
- data/sig/sxn/config/config_discovery.rbs +64 -0
- data/sig/sxn/config/config_validator.rbs +64 -0
- data/sig/sxn/config.rbs +74 -0
- data/sig/sxn/core/config_manager.rbs +67 -0
- data/sig/sxn/core/project_manager.rbs +52 -0
- data/sig/sxn/core/rules_manager.rbs +54 -0
- data/sig/sxn/core/session_manager.rbs +59 -0
- data/sig/sxn/core/worktree_manager.rbs +50 -0
- data/sig/sxn/core.rbs +87 -0
- data/sig/sxn/database/errors.rbs +37 -0
- data/sig/sxn/database/session_database.rbs +151 -0
- data/sig/sxn/database.rbs +83 -0
- data/sig/sxn/errors.rbs +89 -0
- data/sig/sxn/rules/base_rule.rbs +137 -0
- data/sig/sxn/rules/copy_files_rule.rbs +65 -0
- data/sig/sxn/rules/errors.rbs +33 -0
- data/sig/sxn/rules/project_detector.rbs +115 -0
- data/sig/sxn/rules/rules_engine.rbs +118 -0
- data/sig/sxn/rules/setup_commands_rule.rbs +60 -0
- data/sig/sxn/rules/template_rule.rbs +44 -0
- data/sig/sxn/rules.rbs +287 -0
- data/sig/sxn/runtime_validations.rbs +16 -0
- data/sig/sxn/security/secure_command_executor.rbs +63 -0
- data/sig/sxn/security/secure_file_copier.rbs +79 -0
- data/sig/sxn/security/secure_path_validator.rbs +30 -0
- data/sig/sxn/security.rbs +128 -0
- data/sig/sxn/templates/errors.rbs +43 -0
- data/sig/sxn/templates/template_engine.rbs +50 -0
- data/sig/sxn/templates/template_processor.rbs +44 -0
- data/sig/sxn/templates/template_security.rbs +62 -0
- data/sig/sxn/templates/template_variables.rbs +103 -0
- data/sig/sxn/templates.rbs +104 -0
- data/sig/sxn/ui/output.rbs +50 -0
- data/sig/sxn/ui/progress_bar.rbs +39 -0
- data/sig/sxn/ui/prompt.rbs +38 -0
- data/sig/sxn/ui/table.rbs +43 -0
- data/sig/sxn/ui.rbs +63 -0
- data/sig/sxn/version.rbs +5 -0
- data/sig/sxn.rbs +29 -0
- metadata +635 -0
@@ -0,0 +1,95 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Sxn
|
4
|
+
module Commands
|
5
|
+
# Manage project setup rules
|
6
|
+
class Rules < Thor
|
7
|
+
include Thor::Actions
|
8
|
+
|
9
|
+
@ui: Sxn::UI::Output
|
10
|
+
@prompt: Sxn::UI::Prompt
|
11
|
+
@table: Sxn::UI::Table
|
12
|
+
@config_manager: Sxn::Core::ConfigManager
|
13
|
+
@project_manager: Sxn::Core::ProjectManager
|
14
|
+
@rules_manager: Sxn::Core::RulesManager
|
15
|
+
|
16
|
+
# Initialize the command with Thor arguments
|
17
|
+
def initialize: (?Array[String] args, ?Hash[Symbol, untyped] local_options, ?Hash[Symbol, untyped] config) -> void
|
18
|
+
|
19
|
+
# Add a setup rule for project
|
20
|
+
# @param project_name Project name
|
21
|
+
# @param rule_type Type of rule
|
22
|
+
# @param rule_config Rule configuration
|
23
|
+
def add: (?String? project_name, ?String? rule_type, ?String? rule_config) -> void
|
24
|
+
|
25
|
+
# Remove a rule
|
26
|
+
# @param project_name Project name
|
27
|
+
# @param rule_type Rule type
|
28
|
+
# @param rule_index Rule index
|
29
|
+
def remove: (?String? project_name, ?String? rule_type, ?String? rule_index) -> void
|
30
|
+
|
31
|
+
# List all rules or rules for specific project
|
32
|
+
# @param project_name Project name (optional)
|
33
|
+
def list: (?String? project_name) -> void
|
34
|
+
|
35
|
+
# Apply rules to current session
|
36
|
+
# @param project_name Project name (optional)
|
37
|
+
def apply: (?String? project_name) -> void
|
38
|
+
|
39
|
+
# Validate rules for a project
|
40
|
+
# @param project_name Project name
|
41
|
+
def validate: (?String? project_name) -> void
|
42
|
+
|
43
|
+
# Generate rule template
|
44
|
+
# @param rule_type Type of rule
|
45
|
+
# @param project_type Type of project (optional)
|
46
|
+
def template: (?String? rule_type, ?String? project_type) -> void
|
47
|
+
|
48
|
+
# List available rule types
|
49
|
+
def types: () -> void
|
50
|
+
|
51
|
+
private
|
52
|
+
|
53
|
+
# Ensure the project is initialized, exit if not
|
54
|
+
def ensure_initialized!: () -> void
|
55
|
+
|
56
|
+
# Select a project interactively
|
57
|
+
# @param message Prompt message
|
58
|
+
# @return Project name or nil
|
59
|
+
def select_project: (String message) -> String?
|
60
|
+
|
61
|
+
# Prompt for rule configuration based on rule type
|
62
|
+
# @param rule_type Type of rule
|
63
|
+
# @return Configuration hash
|
64
|
+
def prompt_rule_config: (String rule_type) -> Hash[String, untyped]
|
65
|
+
|
66
|
+
# Prompt for copy files rule configuration
|
67
|
+
# @return Configuration hash
|
68
|
+
def prompt_copy_files_config: () -> Hash[String, untyped]
|
69
|
+
|
70
|
+
# Prompt for setup commands rule configuration
|
71
|
+
# @return Configuration hash
|
72
|
+
def prompt_setup_commands_config: () -> Hash[String, untyped]
|
73
|
+
|
74
|
+
# Prompt for template rule configuration
|
75
|
+
# @return Configuration hash
|
76
|
+
def prompt_template_config: () -> Hash[String, untyped]
|
77
|
+
|
78
|
+
# Display rule information
|
79
|
+
# @param rule Rule configuration
|
80
|
+
def display_rule_info: (Hash[Symbol, untyped]? rule) -> void
|
81
|
+
|
82
|
+
# List rules with validation
|
83
|
+
# @param rules Array of rules
|
84
|
+
# @param project_name Project name (optional)
|
85
|
+
def list_with_validation: (Array[Hash[Symbol, untyped]] rules, String? project_name) -> void
|
86
|
+
|
87
|
+
# Show rules preview for dry run
|
88
|
+
# @param project_name Project name
|
89
|
+
def show_rules_preview: (String project_name) -> void
|
90
|
+
|
91
|
+
# Suggest adding a rule
|
92
|
+
def suggest_add_rule: () -> void
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Sxn
|
4
|
+
module Commands
|
5
|
+
# Manage development sessions
|
6
|
+
class Sessions < Thor
|
7
|
+
include Thor::Actions
|
8
|
+
|
9
|
+
@ui: Sxn::UI::Output
|
10
|
+
@prompt: Sxn::UI::Prompt
|
11
|
+
@table: Sxn::UI::Table
|
12
|
+
@config_manager: Sxn::Core::ConfigManager
|
13
|
+
@session_manager: Sxn::Core::SessionManager
|
14
|
+
|
15
|
+
# Initialize the command with Thor arguments
|
16
|
+
def initialize: (?Array[String] args, ?Hash[Symbol, untyped] local_options, ?Hash[Symbol, untyped] config) -> void
|
17
|
+
|
18
|
+
# Create a new session
|
19
|
+
# @param name Session name
|
20
|
+
def add: (?String? name) -> void
|
21
|
+
|
22
|
+
# Remove a session
|
23
|
+
# @param name Session name
|
24
|
+
def remove: (?String? name) -> void
|
25
|
+
|
26
|
+
# List all sessions
|
27
|
+
def list: () -> void
|
28
|
+
|
29
|
+
# Switch to a session
|
30
|
+
# @param name Session name
|
31
|
+
def use: (?String? name) -> void
|
32
|
+
|
33
|
+
# Show current session
|
34
|
+
def current: () -> void
|
35
|
+
|
36
|
+
# Archive a session
|
37
|
+
# @param name Session name
|
38
|
+
def archive: (?String? name) -> void
|
39
|
+
|
40
|
+
# Activate an archived session
|
41
|
+
# @param name Session name
|
42
|
+
def activate: (?String? name) -> void
|
43
|
+
|
44
|
+
private
|
45
|
+
|
46
|
+
# Ensure the project is initialized, exit if not
|
47
|
+
def ensure_initialized!: () -> void
|
48
|
+
|
49
|
+
# Display session information
|
50
|
+
# @param session Session configuration hash
|
51
|
+
# @param verbose Whether to show verbose information
|
52
|
+
def display_session_info: (Hash[Symbol, untyped]? session, ?verbose: bool) -> void
|
53
|
+
|
54
|
+
# Display available commands for a session
|
55
|
+
# @param session_name Session name
|
56
|
+
def display_session_commands: (String session_name) -> void
|
57
|
+
|
58
|
+
# Suggest creating a session
|
59
|
+
def suggest_create_session: () -> void
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Sxn
|
4
|
+
module Commands
|
5
|
+
# Manage git worktrees
|
6
|
+
class Worktrees < Thor
|
7
|
+
include Thor::Actions
|
8
|
+
|
9
|
+
@ui: Sxn::UI::Output
|
10
|
+
@prompt: Sxn::UI::Prompt
|
11
|
+
@table: Sxn::UI::Table
|
12
|
+
@config_manager: Sxn::Core::ConfigManager
|
13
|
+
@project_manager: Sxn::Core::ProjectManager
|
14
|
+
@session_manager: Sxn::Core::SessionManager
|
15
|
+
@worktree_manager: Sxn::Core::WorktreeManager
|
16
|
+
|
17
|
+
# Initialize the command with Thor arguments
|
18
|
+
def initialize: (?Array[String] args, ?Hash[Symbol, untyped] local_options, ?Hash[Symbol, untyped] config) -> void
|
19
|
+
|
20
|
+
# Add worktree to current session
|
21
|
+
# @param project_name Project name
|
22
|
+
# @param branch Branch name (optional)
|
23
|
+
def add: (?String? project_name, ?String? branch) -> void
|
24
|
+
|
25
|
+
# Remove worktree from current session
|
26
|
+
# @param project_name Project name
|
27
|
+
def remove: (?String? project_name) -> void
|
28
|
+
|
29
|
+
# List worktrees in current session
|
30
|
+
def list: () -> void
|
31
|
+
|
32
|
+
# Validate a worktree
|
33
|
+
# @param project_name Project name
|
34
|
+
def validate: (?String? project_name) -> void
|
35
|
+
|
36
|
+
# Show status of all worktrees in current session
|
37
|
+
def status: () -> void
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
# Ensure the project is initialized, exit if not
|
42
|
+
def ensure_initialized!: () -> void
|
43
|
+
|
44
|
+
# Select a project interactively
|
45
|
+
# @param message Prompt message
|
46
|
+
# @return Project name or nil
|
47
|
+
def select_project: (String message) -> String?
|
48
|
+
|
49
|
+
# List worktrees for current session
|
50
|
+
def list_session_worktrees: () -> void
|
51
|
+
|
52
|
+
# List worktrees from all sessions
|
53
|
+
def list_all_worktrees: () -> void
|
54
|
+
|
55
|
+
# List worktrees with validation
|
56
|
+
# @param worktrees Array of worktrees
|
57
|
+
# @param session_name Session name
|
58
|
+
def list_with_validation: (Array[Hash[Symbol, untyped]] worktrees, String session_name) -> void
|
59
|
+
|
60
|
+
# Display worktree information
|
61
|
+
# @param worktree Worktree configuration hash
|
62
|
+
# @param detailed Whether to show detailed information
|
63
|
+
def display_worktree_info: (Hash[Symbol, untyped] worktree, ?detailed: bool) -> void
|
64
|
+
|
65
|
+
# Display available commands for a worktree
|
66
|
+
# @param worktree Worktree configuration hash
|
67
|
+
def display_worktree_commands: (Hash[Symbol, untyped] worktree) -> void
|
68
|
+
|
69
|
+
# Display status summary for worktrees
|
70
|
+
# @param worktrees Array of worktrees
|
71
|
+
def display_worktree_status: (Array[Hash[Symbol, untyped]] worktrees) -> void
|
72
|
+
|
73
|
+
# Apply project rules to a worktree
|
74
|
+
# @param project_name Project name
|
75
|
+
# @param session_name Session name
|
76
|
+
def apply_project_rules: (String project_name, String session_name) -> void
|
77
|
+
|
78
|
+
# Suggest adding a worktree
|
79
|
+
def suggest_add_worktree: () -> void
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Sxn
|
4
|
+
module Config
|
5
|
+
# Caches discovered configurations with TTL and file change invalidation
|
6
|
+
class ConfigCache
|
7
|
+
CACHE_DIR: String
|
8
|
+
CACHE_FILE: String
|
9
|
+
DEFAULT_TTL: Integer
|
10
|
+
|
11
|
+
@cache_dir: String
|
12
|
+
@cache_file_path: String
|
13
|
+
@ttl: Integer
|
14
|
+
@write_mutex: Mutex
|
15
|
+
|
16
|
+
attr_reader cache_dir: String
|
17
|
+
attr_reader cache_file_path: String
|
18
|
+
attr_reader ttl: Integer
|
19
|
+
|
20
|
+
def initialize: (?cache_dir: String?, ?ttl: Integer) -> void
|
21
|
+
|
22
|
+
# Get cached configuration or nil if invalid/missing
|
23
|
+
def get: (Array[String] config_files) -> Hash[untyped, untyped]?
|
24
|
+
|
25
|
+
# Store configuration in cache
|
26
|
+
def set: (Hash[untyped, untyped] config, Array[String] config_files) -> bool
|
27
|
+
|
28
|
+
# Invalidate the cache by removing the cache file
|
29
|
+
def invalidate: () -> bool
|
30
|
+
|
31
|
+
# Check if cache is valid without loading the full configuration
|
32
|
+
def valid?: (Array[String] config_files) -> bool
|
33
|
+
|
34
|
+
# Get cache statistics
|
35
|
+
def stats: (?Array[String] config_files) -> Hash[Symbol, untyped]
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
# Ensure cache directory exists
|
40
|
+
def ensure_cache_directory: () -> void
|
41
|
+
|
42
|
+
# Check if cache file exists
|
43
|
+
def cache_exists?: () -> bool
|
44
|
+
|
45
|
+
# Load cache data from file
|
46
|
+
def load_cache: () -> Hash[String, untyped]?
|
47
|
+
|
48
|
+
# Save cache data to file atomically
|
49
|
+
def save_cache: (Hash[String, untyped] cache_data) -> bool
|
50
|
+
|
51
|
+
# Check if cache is still valid
|
52
|
+
def cache_valid?: (Hash[String, untyped] cache_data, Array[String] config_files) -> bool
|
53
|
+
|
54
|
+
# Check if cache has expired based on TTL
|
55
|
+
def ttl_expired?: (Hash[String, untyped] cache_data) -> bool
|
56
|
+
|
57
|
+
# Check if any config files have changed
|
58
|
+
def files_changed?: (Hash[String, untyped] cache_data, Array[String] config_files) -> bool
|
59
|
+
|
60
|
+
# Build metadata for config files
|
61
|
+
def build_file_metadata: (Array[String] config_files) -> Hash[String, Hash[String, untyped]]
|
62
|
+
|
63
|
+
# Calculate file checksum for additional validation
|
64
|
+
def file_checksum: (String file_path) -> String
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Sxn
|
4
|
+
module Config
|
5
|
+
# Handles hierarchical configuration discovery and loading
|
6
|
+
class ConfigDiscovery
|
7
|
+
CONFIG_FILE_NAME: String
|
8
|
+
LOCAL_CONFIG_DIR: String
|
9
|
+
WORKSPACE_CONFIG_DIR: String
|
10
|
+
GLOBAL_CONFIG_DIR: String
|
11
|
+
ENV_PREFIX: String
|
12
|
+
|
13
|
+
@start_directory: Pathname
|
14
|
+
|
15
|
+
attr_reader start_directory: Pathname
|
16
|
+
|
17
|
+
def initialize: (?String start_directory) -> void
|
18
|
+
|
19
|
+
# Discover and load configuration from all sources
|
20
|
+
def discover_config: (?Hash[untyped, untyped] cli_options) -> Hash[untyped, untyped]
|
21
|
+
|
22
|
+
# Find all configuration files in the hierarchy
|
23
|
+
def find_config_files: () -> Array[String]
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
# Load configurations from all sources
|
28
|
+
def load_all_configs: () -> Hash[Symbol, Hash[untyped, untyped]]
|
29
|
+
|
30
|
+
# Find local project config by walking up directory tree
|
31
|
+
def find_local_config: () -> String?
|
32
|
+
|
33
|
+
# Find workspace config by walking up directory tree
|
34
|
+
def find_workspace_config: () -> String?
|
35
|
+
|
36
|
+
# Find global user config
|
37
|
+
def find_global_config: () -> String?
|
38
|
+
|
39
|
+
# Load system default configuration
|
40
|
+
def load_system_defaults: () -> Hash[String, untyped]
|
41
|
+
|
42
|
+
# Load global user configuration
|
43
|
+
def load_global_config: () -> Hash[untyped, untyped]
|
44
|
+
|
45
|
+
# Load workspace configuration
|
46
|
+
def load_workspace_config: () -> Hash[untyped, untyped]
|
47
|
+
|
48
|
+
# Load local project configuration
|
49
|
+
def load_local_config: () -> Hash[untyped, untyped]
|
50
|
+
|
51
|
+
# Load environment variable configuration
|
52
|
+
def load_env_config: () -> Hash[String, untyped]
|
53
|
+
|
54
|
+
# Load and parse YAML file safely
|
55
|
+
def load_yaml_file: (String file_path) -> Hash[untyped, untyped]
|
56
|
+
|
57
|
+
# Merge configurations with proper precedence
|
58
|
+
def merge_configs: (Hash[Symbol, Hash[untyped, untyped]?] configs, Hash[untyped, untyped] cli_options) -> Hash[untyped, untyped]
|
59
|
+
|
60
|
+
# Deep merge configuration hashes
|
61
|
+
def deep_merge!: (Hash[untyped, untyped] target, Hash[untyped, untyped] source) -> Hash[untyped, untyped]
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Sxn
|
4
|
+
module Config
|
5
|
+
# Validates configuration structure and values
|
6
|
+
class ConfigValidator
|
7
|
+
# Current schema version
|
8
|
+
CURRENT_VERSION: Integer
|
9
|
+
|
10
|
+
# Configuration schema definition
|
11
|
+
SCHEMA: Hash[String, Hash[Symbol, untyped]]
|
12
|
+
|
13
|
+
@errors: Array[String]
|
14
|
+
|
15
|
+
attr_reader errors: Array[String]
|
16
|
+
|
17
|
+
def initialize: () -> void
|
18
|
+
|
19
|
+
# Validate configuration against schema
|
20
|
+
def valid?: (untyped config) -> bool
|
21
|
+
|
22
|
+
# Validate and migrate configuration if needed
|
23
|
+
def validate_and_migrate: (Hash[untyped, untyped] config) -> Hash[untyped, untyped]
|
24
|
+
|
25
|
+
# Get formatted error messages
|
26
|
+
def format_errors: () -> String
|
27
|
+
|
28
|
+
# Migrate configuration from older versions
|
29
|
+
def migrate_config: (Hash[untyped, untyped] config) -> Hash[untyped, untyped]
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
# Check if config needs v0 to v1 migration based on structure
|
34
|
+
def needs_v0_to_v1_migration?: (Hash[untyped, untyped] config) -> bool
|
35
|
+
|
36
|
+
# Validate configuration against schema recursively
|
37
|
+
def validate_against_schema: (Hash[untyped, untyped] config, Hash[String, Hash[Symbol, untyped]] schema, String path) -> void
|
38
|
+
|
39
|
+
# Check if value has the correct type according to schema
|
40
|
+
def value_has_correct_type?: (untyped value, Hash[Symbol, untyped] schema) -> bool
|
41
|
+
|
42
|
+
# Validate field type
|
43
|
+
def validate_field_type: (untyped value, Hash[Symbol, untyped] schema, String path) -> void
|
44
|
+
|
45
|
+
# Validate field constraints
|
46
|
+
def validate_field_constraints: (untyped value, Hash[Symbol, untyped] schema, String path) -> void
|
47
|
+
|
48
|
+
# Validate nested schemas
|
49
|
+
def validate_nested_schema: (untyped value, Hash[Symbol, untyped] schema, String path) -> void
|
50
|
+
|
51
|
+
# Apply default values to configuration
|
52
|
+
def apply_defaults: (Hash[untyped, untyped] config) -> Hash[untyped, untyped]
|
53
|
+
|
54
|
+
# Apply defaults recursively
|
55
|
+
def apply_defaults_recursive: (Hash[untyped, untyped] config, Hash[String, Hash[Symbol, untyped]] schema, Hash[untyped, untyped] root_config) -> Hash[untyped, untyped]
|
56
|
+
|
57
|
+
# Migrate from version 0 (unversioned) to version 1
|
58
|
+
def migrate_v0_to_v1: (Hash[untyped, untyped] config) -> Hash[untyped, untyped]
|
59
|
+
|
60
|
+
# Migrate rules from version 0 to version 1
|
61
|
+
def migrate_rules_v0_to_v1: (Hash[untyped, untyped]? rules) -> void
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
data/sig/sxn/config.rbs
ADDED
@@ -0,0 +1,74 @@
|
|
1
|
+
module Sxn
|
2
|
+
module Config
|
3
|
+
DEFAULT_CONFIG_FILENAME: String
|
4
|
+
|
5
|
+
class ConfigManager
|
6
|
+
@config_path: Pathname
|
7
|
+
@config: Hash[String, untyped]
|
8
|
+
@discovery: ConfigDiscovery
|
9
|
+
@validator: ConfigValidator
|
10
|
+
@cache: ConfigCache
|
11
|
+
|
12
|
+
def initialize: (?config_path: String?) -> void
|
13
|
+
def load: () -> Hash[String, untyped]
|
14
|
+
def save: (Hash[String, untyped] config) -> void
|
15
|
+
def get: (String key, ?untyped default) -> untyped
|
16
|
+
def set: (String key, untyped value) -> void
|
17
|
+
def delete: (String key) -> void
|
18
|
+
def exists?: () -> bool
|
19
|
+
def reload: () -> Hash[String, untyped]
|
20
|
+
def validate!: () -> void
|
21
|
+
def backup: () -> String
|
22
|
+
def restore: (String backup_path) -> void
|
23
|
+
|
24
|
+
private
|
25
|
+
def load_config_file: () -> Hash[String, untyped]
|
26
|
+
def save_config_file: (Hash[String, untyped] config) -> void
|
27
|
+
def deep_get: (Hash[String, untyped] hash, String key) -> untyped
|
28
|
+
def deep_set: (Hash[String, untyped] hash, String key, untyped value) -> void
|
29
|
+
def deep_delete: (Hash[String, untyped] hash, String key) -> void
|
30
|
+
end
|
31
|
+
|
32
|
+
class ConfigDiscovery
|
33
|
+
DEFAULT_SEARCH_PATHS: Array[String]
|
34
|
+
|
35
|
+
def find_config: (?from: String?) -> Pathname?
|
36
|
+
def search_paths: (String from) -> Array[Pathname]
|
37
|
+
def config_in_directory?: (Pathname dir) -> bool
|
38
|
+
|
39
|
+
private
|
40
|
+
def expand_search_paths: (Pathname from) -> Array[Pathname]
|
41
|
+
def check_directory: (Pathname dir) -> Pathname?
|
42
|
+
end
|
43
|
+
|
44
|
+
class ConfigValidator
|
45
|
+
REQUIRED_KEYS: Array[String]
|
46
|
+
VALID_LOG_LEVELS: Array[Symbol]
|
47
|
+
|
48
|
+
def validate: (Hash[String, untyped] config) -> bool
|
49
|
+
def validate!: (Hash[String, untyped] config) -> void
|
50
|
+
def errors: () -> Array[String]
|
51
|
+
|
52
|
+
private
|
53
|
+
def validate_required_keys: (Hash[String, untyped] config) -> void
|
54
|
+
def validate_types: (Hash[String, untyped] config) -> void
|
55
|
+
def validate_values: (Hash[String, untyped] config) -> void
|
56
|
+
end
|
57
|
+
|
58
|
+
class ConfigCache
|
59
|
+
@cache: Hash[String, untyped]
|
60
|
+
@ttl: Integer
|
61
|
+
@timestamps: Hash[String, Time]
|
62
|
+
|
63
|
+
def initialize: (?ttl: Integer) -> void
|
64
|
+
def get: (String key) -> untyped
|
65
|
+
def set: (String key, untyped value) -> void
|
66
|
+
def delete: (String key) -> void
|
67
|
+
def clear: () -> void
|
68
|
+
def expired?: (String key) -> bool
|
69
|
+
|
70
|
+
private
|
71
|
+
def cleanup_expired: () -> void
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Sxn
|
4
|
+
module Core
|
5
|
+
# Manages configuration initialization and access
|
6
|
+
class ConfigManager
|
7
|
+
@base_path: String
|
8
|
+
@config_path: String
|
9
|
+
@sessions_folder: String?
|
10
|
+
|
11
|
+
attr_reader config_path: String
|
12
|
+
attr_reader sessions_folder: String?
|
13
|
+
|
14
|
+
def initialize: (?String base_path) -> void
|
15
|
+
|
16
|
+
def initialized?: () -> bool
|
17
|
+
|
18
|
+
def initialize_project: (String sessions_folder, ?force: bool) -> String
|
19
|
+
|
20
|
+
def get_config: () -> Hash[untyped, untyped]
|
21
|
+
|
22
|
+
def update_current_session: (String? session_name) -> void
|
23
|
+
|
24
|
+
def current_session: () -> String?
|
25
|
+
|
26
|
+
def sessions_folder_path: () -> String?
|
27
|
+
|
28
|
+
def add_project: (String name, String path, ?type: String?, ?default_branch: String?) -> void
|
29
|
+
|
30
|
+
def remove_project: (String name) -> void
|
31
|
+
|
32
|
+
def list_projects: () -> Array[Hash[Symbol, untyped]]
|
33
|
+
|
34
|
+
def get_project: (String name) -> Hash[Symbol, untyped]?
|
35
|
+
|
36
|
+
def update_project: (String name, Hash[Symbol, untyped] updates) -> bool
|
37
|
+
|
38
|
+
def update_project_config: (String name, Hash[Symbol, untyped] updates) -> bool
|
39
|
+
|
40
|
+
def detect_projects: () -> Array[Hash[Symbol, String]]
|
41
|
+
|
42
|
+
# Updates .gitignore to include SXN-related entries if not already present
|
43
|
+
def update_gitignore: () -> bool
|
44
|
+
|
45
|
+
# Public method to save configuration (expected by tests)
|
46
|
+
def save_config: () -> bool
|
47
|
+
|
48
|
+
private
|
49
|
+
|
50
|
+
def sessions_folder_relative_path: () -> String
|
51
|
+
|
52
|
+
def has_gitignore_entry?: (Array[String] lines, String entry) -> bool
|
53
|
+
|
54
|
+
def load_config: () -> void
|
55
|
+
|
56
|
+
def load_config_file: () -> Hash[untyped, untyped]
|
57
|
+
|
58
|
+
def save_config_file: (Hash[untyped, untyped] config) -> void
|
59
|
+
|
60
|
+
def create_directories: () -> void
|
61
|
+
|
62
|
+
def create_config_file: () -> void
|
63
|
+
|
64
|
+
def setup_database: () -> Sxn::Database::SessionDatabase
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Sxn
|
4
|
+
module Core
|
5
|
+
# Manages project registration and configuration
|
6
|
+
class ProjectManager
|
7
|
+
@config_manager: ConfigManager
|
8
|
+
|
9
|
+
def initialize: (?ConfigManager? config_manager) -> void
|
10
|
+
|
11
|
+
def add_project: (String name, String path, ?type: String?, ?default_branch: String?) -> Hash[Symbol, untyped]
|
12
|
+
|
13
|
+
def remove_project: (String name) -> bool
|
14
|
+
|
15
|
+
def list_projects: () -> Array[Hash[Symbol, untyped]]
|
16
|
+
|
17
|
+
def get_project: (String name) -> Hash[Symbol, untyped]
|
18
|
+
|
19
|
+
def project_exists?: (String name) -> bool
|
20
|
+
|
21
|
+
def scan_projects: (?String? base_path) -> Array[Hash[Symbol, String]]
|
22
|
+
|
23
|
+
def detect_projects: (?String? base_path) -> Array[Hash[Symbol, String]]
|
24
|
+
|
25
|
+
def detect_project_type: (String path) -> String
|
26
|
+
|
27
|
+
def update_project: (String name, ?Hash[Symbol, untyped] updates) -> Hash[Symbol, untyped]
|
28
|
+
|
29
|
+
def validate_projects: () -> Array[Hash[Symbol, untyped]]
|
30
|
+
|
31
|
+
def auto_register_projects: (Array[Hash[Symbol, String]] detected_projects) -> Array[Hash[Symbol, untyped]]
|
32
|
+
|
33
|
+
def validate_project: (String name) -> Hash[Symbol, untyped]
|
34
|
+
|
35
|
+
def get_project_rules: (String name) -> Hash[String, untyped]
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
def validate_project_name!: (String name) -> void
|
40
|
+
|
41
|
+
def validate_project_path!: (String path) -> void
|
42
|
+
|
43
|
+
def detect_default_branch: (String path) -> String
|
44
|
+
|
45
|
+
def git_repository?: (String path) -> bool
|
46
|
+
|
47
|
+
def get_default_rules_for_type: (String type) -> Hash[String, untyped]
|
48
|
+
|
49
|
+
def merge_rules: (Hash[String, untyped] default_rules, Hash[String, untyped] custom_rules) -> Hash[String, untyped]
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Sxn
|
4
|
+
module Core
|
5
|
+
# Manages project rules and their application
|
6
|
+
class RulesManager
|
7
|
+
@config_manager: ConfigManager
|
8
|
+
@project_manager: ProjectManager
|
9
|
+
@rules_engine: Sxn::Rules::RulesEngine
|
10
|
+
|
11
|
+
def initialize: (?ConfigManager? config_manager, ?ProjectManager? project_manager) -> void
|
12
|
+
|
13
|
+
def add_rule: (String project_name, String rule_type, Hash[String, untyped] rule_config) -> Hash[Symbol, untyped]
|
14
|
+
|
15
|
+
def remove_rule: (String project_name, String rule_type, ?Integer? rule_index) -> untyped
|
16
|
+
|
17
|
+
def list_rules: (?String? project_name) -> Array[Hash[Symbol, untyped]]
|
18
|
+
|
19
|
+
def apply_rules: (String project_name, ?String? session_name) -> void
|
20
|
+
|
21
|
+
def validate_rules: (String project_name) -> Array[Hash[Symbol, untyped]]
|
22
|
+
|
23
|
+
def generate_rule_template: (String rule_type, ?String? project_type) -> Array[Hash[String, untyped]]
|
24
|
+
|
25
|
+
def get_available_rule_types: () -> Array[Hash[Symbol, untyped]]
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def validate_rule_type!: (String rule_type) -> void
|
30
|
+
|
31
|
+
def validate_rule_config!: (String rule_type, Hash[String, untyped] rule_config) -> void
|
32
|
+
|
33
|
+
def validate_copy_files_config!: (Hash[String, untyped] config) -> void
|
34
|
+
|
35
|
+
def validate_setup_commands_config!: (Hash[String, untyped] config) -> void
|
36
|
+
|
37
|
+
def validate_template_config!: (Hash[String, untyped] config) -> void
|
38
|
+
|
39
|
+
def list_project_rules: (String project_name) -> Array[Hash[Symbol, untyped]]
|
40
|
+
|
41
|
+
def list_all_rules: () -> Array[Hash[Symbol, untyped]]
|
42
|
+
|
43
|
+
def format_rules_for_display: (String project_name, Hash[String, untyped] rules) -> Array[Hash[Symbol, untyped]]
|
44
|
+
|
45
|
+
def save_project_config: (String project_name, Hash[String, untyped] project_config) -> void
|
46
|
+
|
47
|
+
def generate_copy_files_template: (String? project_type) -> Array[Hash[String, untyped]]
|
48
|
+
|
49
|
+
def generate_setup_commands_template: (String? project_type) -> Array[Hash[String, untyped]]
|
50
|
+
|
51
|
+
def generate_template_rule_template: (String? project_type) -> Array[Hash[String, untyped]]
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|