fantasy-cli 1.2.6

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 (112) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +21 -0
  3. data/README.md +456 -0
  4. data/bin/gsd +8 -0
  5. data/bin/gsd-core-darwin-amd64 +0 -0
  6. data/bin/gsd-core-darwin-arm64 +0 -0
  7. data/bin/gsd-core-linux-amd64 +0 -0
  8. data/bin/gsd-core-linux-arm64 +0 -0
  9. data/bin/gsd-core-windows-amd64.exe +0 -0
  10. data/bin/gsd-core-windows-arm64.exe +0 -0
  11. data/bin/gsd-core.exe +0 -0
  12. data/lib/gsd/agents/coordinator.rb +195 -0
  13. data/lib/gsd/agents/task_manager.rb +158 -0
  14. data/lib/gsd/agents/worker.rb +162 -0
  15. data/lib/gsd/agents.rb +30 -0
  16. data/lib/gsd/ai/chat.rb +486 -0
  17. data/lib/gsd/ai/cli.rb +248 -0
  18. data/lib/gsd/ai/command_parser.rb +97 -0
  19. data/lib/gsd/ai/commands/base.rb +42 -0
  20. data/lib/gsd/ai/commands/clear.rb +20 -0
  21. data/lib/gsd/ai/commands/context.rb +30 -0
  22. data/lib/gsd/ai/commands/cost.rb +30 -0
  23. data/lib/gsd/ai/commands/export.rb +42 -0
  24. data/lib/gsd/ai/commands/help.rb +61 -0
  25. data/lib/gsd/ai/commands/model.rb +67 -0
  26. data/lib/gsd/ai/commands/reset.rb +22 -0
  27. data/lib/gsd/ai/config.rb +256 -0
  28. data/lib/gsd/ai/context.rb +324 -0
  29. data/lib/gsd/ai/cost_tracker.rb +361 -0
  30. data/lib/gsd/ai/git_context.rb +169 -0
  31. data/lib/gsd/ai/history.rb +384 -0
  32. data/lib/gsd/ai/providers/anthropic.rb +429 -0
  33. data/lib/gsd/ai/providers/base.rb +282 -0
  34. data/lib/gsd/ai/providers/lmstudio.rb +279 -0
  35. data/lib/gsd/ai/providers/ollama.rb +336 -0
  36. data/lib/gsd/ai/providers/openai.rb +396 -0
  37. data/lib/gsd/ai/providers/openrouter.rb +429 -0
  38. data/lib/gsd/ai/reference_resolver.rb +225 -0
  39. data/lib/gsd/ai/repl.rb +349 -0
  40. data/lib/gsd/ai/streaming.rb +438 -0
  41. data/lib/gsd/ai/ui.rb +429 -0
  42. data/lib/gsd/buddy/cli.rb +284 -0
  43. data/lib/gsd/buddy/gacha.rb +148 -0
  44. data/lib/gsd/buddy/renderer.rb +108 -0
  45. data/lib/gsd/buddy/species.rb +190 -0
  46. data/lib/gsd/buddy/stats.rb +156 -0
  47. data/lib/gsd/buddy.rb +28 -0
  48. data/lib/gsd/cli.rb +455 -0
  49. data/lib/gsd/commands.rb +198 -0
  50. data/lib/gsd/config.rb +183 -0
  51. data/lib/gsd/error.rb +188 -0
  52. data/lib/gsd/frontmatter.rb +123 -0
  53. data/lib/gsd/go/bridge.rb +173 -0
  54. data/lib/gsd/history.rb +76 -0
  55. data/lib/gsd/milestone.rb +75 -0
  56. data/lib/gsd/output.rb +184 -0
  57. data/lib/gsd/phase.rb +102 -0
  58. data/lib/gsd/plugins/base.rb +92 -0
  59. data/lib/gsd/plugins/cli.rb +330 -0
  60. data/lib/gsd/plugins/config.rb +164 -0
  61. data/lib/gsd/plugins/hooks.rb +132 -0
  62. data/lib/gsd/plugins/installer.rb +158 -0
  63. data/lib/gsd/plugins/loader.rb +122 -0
  64. data/lib/gsd/plugins/manager.rb +187 -0
  65. data/lib/gsd/plugins/marketplace.rb +142 -0
  66. data/lib/gsd/plugins/sandbox.rb +114 -0
  67. data/lib/gsd/plugins/search.rb +131 -0
  68. data/lib/gsd/plugins/validator.rb +157 -0
  69. data/lib/gsd/plugins.rb +48 -0
  70. data/lib/gsd/profile.rb +127 -0
  71. data/lib/gsd/research.rb +85 -0
  72. data/lib/gsd/roadmap.rb +90 -0
  73. data/lib/gsd/skills/bundled/commit.md +58 -0
  74. data/lib/gsd/skills/bundled/debug.md +28 -0
  75. data/lib/gsd/skills/bundled/explain.md +41 -0
  76. data/lib/gsd/skills/bundled/plan.md +42 -0
  77. data/lib/gsd/skills/bundled/verify.md +26 -0
  78. data/lib/gsd/skills/loader.rb +189 -0
  79. data/lib/gsd/state.rb +102 -0
  80. data/lib/gsd/template.rb +106 -0
  81. data/lib/gsd/tools/ask_user_question.rb +179 -0
  82. data/lib/gsd/tools/base.rb +204 -0
  83. data/lib/gsd/tools/bash.rb +246 -0
  84. data/lib/gsd/tools/file_edit.rb +297 -0
  85. data/lib/gsd/tools/file_read.rb +199 -0
  86. data/lib/gsd/tools/file_write.rb +153 -0
  87. data/lib/gsd/tools/glob.rb +202 -0
  88. data/lib/gsd/tools/grep.rb +227 -0
  89. data/lib/gsd/tools/gsd_frontmatter.rb +165 -0
  90. data/lib/gsd/tools/gsd_phase.rb +140 -0
  91. data/lib/gsd/tools/gsd_roadmap.rb +108 -0
  92. data/lib/gsd/tools/gsd_state.rb +143 -0
  93. data/lib/gsd/tools/gsd_template.rb +157 -0
  94. data/lib/gsd/tools/gsd_verify.rb +159 -0
  95. data/lib/gsd/tools/registry.rb +103 -0
  96. data/lib/gsd/tools/task.rb +235 -0
  97. data/lib/gsd/tools/todo_write.rb +290 -0
  98. data/lib/gsd/tools/web.rb +260 -0
  99. data/lib/gsd/tui/app.rb +366 -0
  100. data/lib/gsd/tui/auto_complete.rb +79 -0
  101. data/lib/gsd/tui/colors.rb +111 -0
  102. data/lib/gsd/tui/command_palette.rb +126 -0
  103. data/lib/gsd/tui/header.rb +38 -0
  104. data/lib/gsd/tui/input_box.rb +199 -0
  105. data/lib/gsd/tui/spinner.rb +40 -0
  106. data/lib/gsd/tui/status_bar.rb +51 -0
  107. data/lib/gsd/tui.rb +17 -0
  108. data/lib/gsd/validator.rb +216 -0
  109. data/lib/gsd/verify.rb +175 -0
  110. data/lib/gsd/version.rb +5 -0
  111. data/lib/gsd/workstream.rb +91 -0
  112. metadata +231 -0
@@ -0,0 +1,140 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'gsd/tools/base'
4
+ require 'gsd/go/bridge'
5
+
6
+ module Gsd
7
+ module Tools
8
+ # GsdPhaseTool - Operações de Phases via Go bridge
9
+ #
10
+ # Uso:
11
+ # tool = GsdPhaseTool.new(cwd: '/path')
12
+ # result = tool.execute(operation: 'find', phase: '1')
13
+ class GsdPhaseTool < Base
14
+ class << self
15
+ tool_name('gsd_phase')
16
+ tool_description('GSD Phase operations: find, list, next-decimal, add')
17
+ tool_input_schema({
18
+ type: 'object',
19
+ properties: {
20
+ operation: {
21
+ type: 'string',
22
+ description: 'Operation: find, list, next_decimal, add',
23
+ enum: ['find', 'list', 'next_decimal', 'add']
24
+ },
25
+ phase: {
26
+ type: 'string',
27
+ description: 'Phase number (for find/next_decimal operations)'
28
+ },
29
+ description: {
30
+ type: 'string',
31
+ description: 'Phase description (for add operation)'
32
+ },
33
+ id: {
34
+ type: 'string',
35
+ description: 'Phase ID (for add operation)'
36
+ }
37
+ },
38
+ required: ['operation']
39
+ })
40
+ end
41
+
42
+ # Executa operação de Phase
43
+ #
44
+ # @param args [Hash] Argumentos
45
+ # @return [Hash] Resultado da operação
46
+ def execute(args)
47
+ operation = args[:operation] || args['operation']
48
+ phase = args[:phase] || args['phase']
49
+ description = args[:description] || args['description']
50
+ phase_id = args[:id] || args['id']
51
+
52
+ raise ArgumentError, 'Operation is required' unless operation
53
+
54
+ log_debug("Phase operation: #{operation}")
55
+
56
+ # Chama Go bridge
57
+ result = case operation
58
+ when 'find'
59
+ raise ArgumentError, 'Phase number required' unless phase
60
+ Gsd::Go::Bridge.call('phase', {
61
+ 'find' => true,
62
+ 'phase' => phase
63
+ }, cwd: @cwd)
64
+ when 'list'
65
+ Gsd::Go::Bridge.call('phase', { 'list' => true }, cwd: @cwd)
66
+ when 'next_decimal'
67
+ raise ArgumentError, 'Phase number required' unless phase
68
+ Gsd::Go::Bridge.call('phase', {
69
+ 'next_decimal' => true,
70
+ 'phase' => phase
71
+ }, cwd: @cwd)
72
+ when 'add'
73
+ raise ArgumentError, 'Description required for add' unless description
74
+ params = {
75
+ 'add' => true,
76
+ 'description' => description
77
+ }
78
+ params['id'] = phase_id if phase_id
79
+ Gsd::Go::Bridge.call('phase', params, cwd: @cwd)
80
+ else
81
+ { 'success' => false, 'error' => "Invalid operation: #{operation}" }
82
+ end
83
+
84
+ # Parseia resultado
85
+ if result['success']
86
+ {
87
+ success: true,
88
+ operation: operation,
89
+ data: result['data'],
90
+ cwd: @cwd
91
+ }
92
+ else
93
+ {
94
+ success: false,
95
+ error: result['error'] || 'unknown_error',
96
+ message: result['message'],
97
+ operation: operation
98
+ }
99
+ end
100
+ rescue => e
101
+ log_debug("Error: #{e.message}")
102
+ {
103
+ success: false,
104
+ error: 'bridge_error',
105
+ message: e.message,
106
+ operation: operation
107
+ }
108
+ end
109
+
110
+ # Verifica se é safe
111
+ #
112
+ # @param args [Hash] Argumentos
113
+ # @return [Boolean] true apenas para find/list
114
+ def self.safe?(args)
115
+ operation = args[:operation] || args['operation']
116
+ ['find', 'list'].include?(operation)
117
+ end
118
+
119
+ # Verifica se é read-only
120
+ #
121
+ # @param args [Hash] Argumentos
122
+ # @return [Boolean] true apenas para find/list
123
+ def self.read_only?(args)
124
+ safe?(args)
125
+ end
126
+
127
+ # Verifica se é destrutivo
128
+ #
129
+ # @param args [Hash] Argumentos
130
+ # @return [Boolean] true para add
131
+ def self.destructive?(args)
132
+ operation = args[:operation] || args['operation']
133
+ operation == 'add'
134
+ end
135
+ end
136
+ end
137
+ end
138
+
139
+ # Registra a tool
140
+ Gsd::Tools::Registry.register('gsd_phase', Gsd::Tools::GsdPhaseTool, category: :gsd)
@@ -0,0 +1,108 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'gsd/tools/base'
4
+ require 'gsd/go/bridge'
5
+
6
+ module Gsd
7
+ module Tools
8
+ # GsdRoadmapTool - Operações de ROADMAP.md via Go bridge
9
+ #
10
+ # Uso:
11
+ # tool = GsdRoadmapTool.new(cwd: '/path')
12
+ # result = tool.execute(operation: 'analyze')
13
+ class GsdRoadmapTool < Base
14
+ class << self
15
+ tool_name('gsd_roadmap')
16
+ tool_description('GSD Roadmap operations: get-phase, analyze')
17
+ tool_input_schema({
18
+ type: 'object',
19
+ properties: {
20
+ operation: {
21
+ type: 'string',
22
+ description: 'Operation: get-phase, analyze',
23
+ enum: ['get-phase', 'analyze']
24
+ },
25
+ phase: {
26
+ type: 'string',
27
+ description: 'Phase number (for get-phase operation)'
28
+ }
29
+ },
30
+ required: ['operation']
31
+ })
32
+ end
33
+
34
+ # Executa operação de Roadmap
35
+ #
36
+ # @param args [Hash] Argumentos
37
+ # @return [Hash] Resultado da operação
38
+ def execute(args)
39
+ operation = args[:operation] || args['operation']
40
+ phase = args[:phase] || args['phase']
41
+
42
+ raise ArgumentError, 'Operation is required' unless operation
43
+
44
+ log_debug("Roadmap operation: #{operation}")
45
+
46
+ # Chama Go bridge
47
+ result = case operation
48
+ when 'get-phase'
49
+ raise ArgumentError, 'Phase number required' unless phase
50
+ Gsd::Go::Bridge.call('roadmap', {
51
+ 'get-phase' => true,
52
+ 'phase' => phase
53
+ }, cwd: @cwd)
54
+ when 'analyze'
55
+ Gsd::Go::Bridge.call('roadmap', {
56
+ 'analyze' => true
57
+ }, cwd: @cwd)
58
+ else
59
+ { 'success' => false, 'error' => "Invalid operation: #{operation}" }
60
+ end
61
+
62
+ # Parseia resultado
63
+ if result['success']
64
+ {
65
+ success: true,
66
+ operation: operation,
67
+ data: result['data'],
68
+ cwd: @cwd
69
+ }
70
+ else
71
+ {
72
+ success: false,
73
+ error: result['error'] || 'unknown_error',
74
+ message: result['message'],
75
+ operation: operation
76
+ }
77
+ end
78
+ rescue => e
79
+ log_debug("Error: #{e.message}")
80
+ {
81
+ success: false,
82
+ error: 'bridge_error',
83
+ message: e.message,
84
+ operation: operation
85
+ }
86
+ end
87
+
88
+ # Verifica se é safe
89
+ #
90
+ # @param args [Hash] Argumentos
91
+ # @return [Boolean] true (apenas leitura)
92
+ def self.safe?(args)
93
+ true
94
+ end
95
+
96
+ # Verifica se é read-only
97
+ #
98
+ # @param args [Hash] Argumentos
99
+ # @return [Boolean] true
100
+ def self.read_only?(args)
101
+ true
102
+ end
103
+ end
104
+ end
105
+ end
106
+
107
+ # Registra a tool
108
+ Gsd::Tools::Registry.register('gsd_roadmap', Gsd::Tools::GsdRoadmapTool, category: :gsd)
@@ -0,0 +1,143 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'gsd/tools/base'
4
+ require 'gsd/go/bridge'
5
+
6
+ module Gsd
7
+ module Tools
8
+ # GsdStateTool - Operações de STATE.md via Go bridge
9
+ #
10
+ # Uso:
11
+ # tool = GsdStateTool.new(cwd: '/path')
12
+ # result = tool.execute(operation: 'json')
13
+ class GsdStateTool < Base
14
+ class << self
15
+ tool_name('gsd_state')
16
+ tool_description('GSD State operations: load, json, update, patch, get')
17
+ tool_input_schema({
18
+ type: 'object',
19
+ properties: {
20
+ operation: {
21
+ type: 'string',
22
+ description: 'Operation: load, json, update, patch, get',
23
+ enum: ['load', 'json', 'update', 'patch', 'get']
24
+ },
25
+ field: {
26
+ type: 'string',
27
+ description: 'Field name (for update/patch operations)'
28
+ },
29
+ value: {
30
+ type: 'string',
31
+ description: 'Field value (for update/patch operations)'
32
+ },
33
+ fields: {
34
+ type: 'object',
35
+ description: 'Multiple fields (for patch operation)'
36
+ },
37
+ section: {
38
+ type: 'string',
39
+ description: 'Section name (for get operation)'
40
+ }
41
+ },
42
+ required: ['operation']
43
+ })
44
+ end
45
+
46
+ # Executa operação de State
47
+ #
48
+ # @param args [Hash] Argumentos
49
+ # @return [Hash] Resultado da operação
50
+ def execute(args)
51
+ operation = args[:operation] || args['operation']
52
+ field = args[:field] || args['field']
53
+ value = args[:value] || args['value']
54
+ fields = args[:fields] || args['fields']
55
+ section = args[:section] || args['section']
56
+
57
+ raise ArgumentError, 'Operation is required' unless operation
58
+
59
+ log_debug("State operation: #{operation}")
60
+
61
+ # Chama Go bridge
62
+ result = case operation
63
+ when 'load', 'json'
64
+ Gsd::Go::Bridge.call('state', { 'json' => true }, cwd: @cwd)
65
+ when 'update'
66
+ raise ArgumentError, 'Field and value required for update' unless field && value
67
+ Gsd::Go::Bridge.call('state', {
68
+ 'update' => true,
69
+ 'field' => field,
70
+ 'value' => value
71
+ }, cwd: @cwd)
72
+ when 'patch'
73
+ raise ArgumentError, 'Fields required for patch' unless fields
74
+ Gsd::Go::Bridge.call('state', {
75
+ 'patch' => true,
76
+ 'fields' => fields
77
+ }, cwd: @cwd)
78
+ when 'get'
79
+ Gsd::Go::Bridge.call('state', {
80
+ 'get' => true,
81
+ 'section' => section
82
+ }, cwd: @cwd)
83
+ else
84
+ { 'success' => false, 'error' => "Invalid operation: #{operation}" }
85
+ end
86
+
87
+ # Parseia resultado
88
+ if result['success']
89
+ {
90
+ success: true,
91
+ operation: operation,
92
+ data: result['data'],
93
+ cwd: @cwd
94
+ }
95
+ else
96
+ {
97
+ success: false,
98
+ error: result['error'] || 'unknown_error',
99
+ message: result['message'],
100
+ operation: operation
101
+ }
102
+ end
103
+ rescue => e
104
+ log_debug("Error: #{e.message}")
105
+ {
106
+ success: false,
107
+ error: 'bridge_error',
108
+ message: e.message,
109
+ operation: operation
110
+ }
111
+ end
112
+
113
+ # Verifica se é safe
114
+ #
115
+ # @param args [Hash] Argumentos
116
+ # @return [Boolean] true apenas para load/json/get
117
+ def self.safe?(args)
118
+ operation = args[:operation] || args['operation']
119
+ ['load', 'json', 'get'].include?(operation)
120
+ end
121
+
122
+ # Verifica se é read-only
123
+ #
124
+ # @param args [Hash] Argumentos
125
+ # @return [Boolean] true apenas para load/json/get
126
+ def self.read_only?(args)
127
+ safe?(args)
128
+ end
129
+
130
+ # Verifica se é destrutivo
131
+ #
132
+ # @param args [Hash] Argumentos
133
+ # @return [Boolean] true para update/patch
134
+ def self.destructive?(args)
135
+ operation = args[:operation] || args['operation']
136
+ ['update', 'patch'].include?(operation)
137
+ end
138
+ end
139
+ end
140
+ end
141
+
142
+ # Registra a tool
143
+ Gsd::Tools::Registry.register('gsd_state', Gsd::Tools::GsdStateTool, category: :gsd)
@@ -0,0 +1,157 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'gsd/tools/base'
4
+ require 'gsd/go/bridge'
5
+
6
+ module Gsd
7
+ module Tools
8
+ # GsdTemplateTool - Preenchimento de templates via Go bridge
9
+ #
10
+ # Uso:
11
+ # tool = GsdTemplateTool.new(cwd: '/path')
12
+ # result = tool.execute(operation: 'fill', type: 'summary', phase: '1')
13
+ class GsdTemplateTool < Base
14
+ class << self
15
+ tool_name('gsd_template')
16
+ tool_description('GSD Template operations: fill summary, plan, verification, context')
17
+ tool_input_schema({
18
+ type: 'object',
19
+ properties: {
20
+ operation: {
21
+ type: 'string',
22
+ description: 'Operation: fill',
23
+ enum: ['fill']
24
+ },
25
+ type: {
26
+ type: 'string',
27
+ description: 'Template type: summary, plan, verification, context',
28
+ enum: ['summary', 'plan', 'verification', 'context']
29
+ },
30
+ phase: {
31
+ type: 'string',
32
+ description: 'Phase number'
33
+ },
34
+ plan: {
35
+ type: 'string',
36
+ description: 'Plan number (for plan template)'
37
+ },
38
+ name: {
39
+ type: 'string',
40
+ description: 'Template name'
41
+ },
42
+ template_type: {
43
+ type: 'string',
44
+ description: 'Plan type: execute, tdd (for plan template)'
45
+ }
46
+ },
47
+ required: ['operation', 'type', 'phase']
48
+ })
49
+ end
50
+
51
+ # Executa operação de Template
52
+ #
53
+ # @param args [Hash] Argumentos
54
+ # @return [Hash] Resultado da operação
55
+ def execute(args)
56
+ operation = args[:operation] || args['operation']
57
+ template_type = args[:type] || args['type']
58
+ phase = args[:phase] || args['phase']
59
+ plan = args[:plan] || args['plan']
60
+ name = args[:name] || args['name']
61
+ plan_type = args[:template_type] || args['template_type']
62
+
63
+ raise ArgumentError, 'Operation is required' unless operation
64
+ raise ArgumentError, 'Type is required' unless template_type
65
+ raise ArgumentError, 'Phase is required' unless phase
66
+
67
+ log_debug("Template operation: #{operation}, type: #{template_type}")
68
+
69
+ # Chama Go bridge
70
+ result = case operation
71
+ when 'fill'
72
+ params = build_fill_params(template_type, phase, plan, name, plan_type)
73
+ Gsd::Go::Bridge.call('template', params, cwd: @cwd)
74
+ else
75
+ { 'success' => false, 'error' => "Invalid operation: #{operation}" }
76
+ end
77
+
78
+ # Parseia resultado
79
+ if result['success']
80
+ {
81
+ success: true,
82
+ operation: operation,
83
+ type: template_type,
84
+ data: result['data'],
85
+ cwd: @cwd
86
+ }
87
+ else
88
+ {
89
+ success: false,
90
+ error: result['error'] || 'unknown_error',
91
+ message: result['message'],
92
+ operation: operation
93
+ }
94
+ end
95
+ rescue => e
96
+ log_debug("Error: #{e.message}")
97
+ {
98
+ success: false,
99
+ error: 'bridge_error',
100
+ message: e.message,
101
+ operation: operation
102
+ }
103
+ end
104
+
105
+ # Verifica se é safe
106
+ #
107
+ # @param args [Hash] Argumentos
108
+ # @return [Boolean] false (cria arquivos)
109
+ def self.safe?(args)
110
+ false
111
+ end
112
+
113
+ # Verifica se é read-only
114
+ #
115
+ # @param args [Hash] Argumentos
116
+ # @return [Boolean] false
117
+ def self.read_only?(args)
118
+ false
119
+ end
120
+
121
+ # Verifica se é destrutivo
122
+ #
123
+ # @param args [Hash] Argumentos
124
+ # @return [Boolean] false (cria novos arquivos)
125
+ def self.destructive?(args)
126
+ false
127
+ end
128
+
129
+ private
130
+
131
+ # Constrói params para operação fill
132
+ #
133
+ # @param type [String] Tipo de template
134
+ # @param phase [String] Número da phase
135
+ # @param plan [String] Número do plan
136
+ # @param name [String] Nome
137
+ # @param plan_type [String] Tipo do plan
138
+ # @return [Hash] Params
139
+ def build_fill_params(type, phase, plan, name, plan_type)
140
+ params = {
141
+ 'fill' => true,
142
+ 'type' => type,
143
+ 'phase' => phase
144
+ }
145
+
146
+ params['plan'] = plan if plan
147
+ params['name'] = name if name
148
+ params['template_type'] = plan_type if plan_type
149
+
150
+ params
151
+ end
152
+ end
153
+ end
154
+ end
155
+
156
+ # Registra a tool
157
+ Gsd::Tools::Registry.register('gsd_template', Gsd::Tools::GsdTemplateTool, category: :gsd)
@@ -0,0 +1,159 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'gsd/tools/base'
4
+ require 'gsd/go/bridge'
5
+
6
+ module Gsd
7
+ module Tools
8
+ # GsdVerifyTool - Operações de verificação via Go bridge
9
+ #
10
+ # Uso:
11
+ # tool = GsdVerifyTool.new(cwd: '/path')
12
+ # result = tool.execute(operation: 'plan-structure', file: 'PLAN.md')
13
+ class GsdVerifyTool < Base
14
+ class << self
15
+ tool_name('gsd_verify')
16
+ tool_description('GSD Verify operations: plan-structure, phase-completeness, references, commits, artifacts, key-links, tasks, summary')
17
+ tool_input_schema({
18
+ type: 'object',
19
+ properties: {
20
+ operation: {
21
+ type: 'string',
22
+ description: 'Operation: plan-structure, phase-completeness, references, commits, artifacts, key-links, tasks, summary',
23
+ enum: ['plan-structure', 'phase-completeness', 'references', 'commits', 'artifacts', 'key-links', 'tasks', 'summary']
24
+ },
25
+ file: {
26
+ type: 'string',
27
+ description: 'File path (for file-based operations)'
28
+ },
29
+ phase: {
30
+ type: 'string',
31
+ description: 'Phase number (for phase-completeness)'
32
+ },
33
+ commits: {
34
+ type: 'array',
35
+ description: 'Commit hashes (for commits operation)',
36
+ items: {
37
+ type: 'string'
38
+ }
39
+ }
40
+ },
41
+ required: ['operation']
42
+ })
43
+ end
44
+
45
+ # Executa operação de Verify
46
+ #
47
+ # @param args [Hash] Argumentos
48
+ # @return [Hash] Resultado da verificação
49
+ def execute(args)
50
+ operation = args[:operation] || args['operation']
51
+ file = args[:file] || args['file']
52
+ phase = args[:phase] || args['phase']
53
+ commits = args[:commits] || args['commits']
54
+
55
+ raise ArgumentError, 'Operation is required' unless operation
56
+
57
+ log_debug("Verify operation: #{operation}")
58
+
59
+ # Chama Go bridge
60
+ result = case operation
61
+ when 'plan-structure'
62
+ raise ArgumentError, 'File required' unless file
63
+ Gsd::Go::Bridge.call('verify', {
64
+ 'plan-structure' => true,
65
+ 'file' => file
66
+ }, cwd: @cwd)
67
+ when 'phase-completeness'
68
+ raise ArgumentError, 'Phase required' unless phase
69
+ Gsd::Go::Bridge.call('verify', {
70
+ 'phase-completeness' => true,
71
+ 'phase' => phase
72
+ }, cwd: @cwd)
73
+ when 'references'
74
+ raise ArgumentError, 'File required' unless file
75
+ Gsd::Go::Bridge.call('verify', {
76
+ 'references' => true,
77
+ 'file' => file
78
+ }, cwd: @cwd)
79
+ when 'commits'
80
+ raise ArgumentError, 'Commits required' unless commits && commits.any?
81
+ Gsd::Go::Bridge.call('verify', {
82
+ 'commits' => true,
83
+ 'commits' => commits
84
+ }, cwd: @cwd)
85
+ when 'artifacts'
86
+ raise ArgumentError, 'File required' unless file
87
+ Gsd::Go::Bridge.call('verify', {
88
+ 'artifacts' => true,
89
+ 'file' => file
90
+ }, cwd: @cwd)
91
+ when 'key-links'
92
+ raise ArgumentError, 'File required' unless file
93
+ Gsd::Go::Bridge.call('verify', {
94
+ 'key-links' => true,
95
+ 'file' => file
96
+ }, cwd: @cwd)
97
+ when 'tasks'
98
+ raise ArgumentError, 'File required' unless file
99
+ Gsd::Go::Bridge.call('verify', {
100
+ 'tasks' => true,
101
+ 'file' => file
102
+ }, cwd: @cwd)
103
+ when 'summary'
104
+ raise ArgumentError, 'File required' unless file
105
+ Gsd::Go::Bridge.call('verify', {
106
+ 'summary' => true,
107
+ 'file' => file
108
+ }, cwd: @cwd)
109
+ else
110
+ { 'success' => false, 'error' => "Invalid operation: #{operation}" }
111
+ end
112
+
113
+ # Parseia resultado
114
+ if result['success']
115
+ {
116
+ success: true,
117
+ operation: operation,
118
+ data: result['data'],
119
+ cwd: @cwd
120
+ }
121
+ else
122
+ {
123
+ success: false,
124
+ error: result['error'] || 'unknown_error',
125
+ message: result['message'],
126
+ operation: operation
127
+ }
128
+ end
129
+ rescue => e
130
+ log_debug("Error: #{e.message}")
131
+ {
132
+ success: false,
133
+ error: 'bridge_error',
134
+ message: e.message,
135
+ operation: operation
136
+ }
137
+ end
138
+
139
+ # Verifica se é safe
140
+ #
141
+ # @param args [Hash] Argumentos
142
+ # @return [Boolean] true (apenas leitura)
143
+ def self.safe?(args)
144
+ true
145
+ end
146
+
147
+ # Verifica se é read-only
148
+ #
149
+ # @param args [Hash] Argumentos
150
+ # @return [Boolean] true
151
+ def self.read_only?(args)
152
+ true
153
+ end
154
+ end
155
+ end
156
+ end
157
+
158
+ # Registra a tool
159
+ Gsd::Tools::Registry.register('gsd_verify', Gsd::Tools::GsdVerifyTool, category: :gsd)