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.
- checksums.yaml +7 -0
- data/LICENSE +21 -0
- data/README.md +456 -0
- data/bin/gsd +8 -0
- data/bin/gsd-core-darwin-amd64 +0 -0
- data/bin/gsd-core-darwin-arm64 +0 -0
- data/bin/gsd-core-linux-amd64 +0 -0
- data/bin/gsd-core-linux-arm64 +0 -0
- data/bin/gsd-core-windows-amd64.exe +0 -0
- data/bin/gsd-core-windows-arm64.exe +0 -0
- data/bin/gsd-core.exe +0 -0
- data/lib/gsd/agents/coordinator.rb +195 -0
- data/lib/gsd/agents/task_manager.rb +158 -0
- data/lib/gsd/agents/worker.rb +162 -0
- data/lib/gsd/agents.rb +30 -0
- data/lib/gsd/ai/chat.rb +486 -0
- data/lib/gsd/ai/cli.rb +248 -0
- data/lib/gsd/ai/command_parser.rb +97 -0
- data/lib/gsd/ai/commands/base.rb +42 -0
- data/lib/gsd/ai/commands/clear.rb +20 -0
- data/lib/gsd/ai/commands/context.rb +30 -0
- data/lib/gsd/ai/commands/cost.rb +30 -0
- data/lib/gsd/ai/commands/export.rb +42 -0
- data/lib/gsd/ai/commands/help.rb +61 -0
- data/lib/gsd/ai/commands/model.rb +67 -0
- data/lib/gsd/ai/commands/reset.rb +22 -0
- data/lib/gsd/ai/config.rb +256 -0
- data/lib/gsd/ai/context.rb +324 -0
- data/lib/gsd/ai/cost_tracker.rb +361 -0
- data/lib/gsd/ai/git_context.rb +169 -0
- data/lib/gsd/ai/history.rb +384 -0
- data/lib/gsd/ai/providers/anthropic.rb +429 -0
- data/lib/gsd/ai/providers/base.rb +282 -0
- data/lib/gsd/ai/providers/lmstudio.rb +279 -0
- data/lib/gsd/ai/providers/ollama.rb +336 -0
- data/lib/gsd/ai/providers/openai.rb +396 -0
- data/lib/gsd/ai/providers/openrouter.rb +429 -0
- data/lib/gsd/ai/reference_resolver.rb +225 -0
- data/lib/gsd/ai/repl.rb +349 -0
- data/lib/gsd/ai/streaming.rb +438 -0
- data/lib/gsd/ai/ui.rb +429 -0
- data/lib/gsd/buddy/cli.rb +284 -0
- data/lib/gsd/buddy/gacha.rb +148 -0
- data/lib/gsd/buddy/renderer.rb +108 -0
- data/lib/gsd/buddy/species.rb +190 -0
- data/lib/gsd/buddy/stats.rb +156 -0
- data/lib/gsd/buddy.rb +28 -0
- data/lib/gsd/cli.rb +455 -0
- data/lib/gsd/commands.rb +198 -0
- data/lib/gsd/config.rb +183 -0
- data/lib/gsd/error.rb +188 -0
- data/lib/gsd/frontmatter.rb +123 -0
- data/lib/gsd/go/bridge.rb +173 -0
- data/lib/gsd/history.rb +76 -0
- data/lib/gsd/milestone.rb +75 -0
- data/lib/gsd/output.rb +184 -0
- data/lib/gsd/phase.rb +102 -0
- data/lib/gsd/plugins/base.rb +92 -0
- data/lib/gsd/plugins/cli.rb +330 -0
- data/lib/gsd/plugins/config.rb +164 -0
- data/lib/gsd/plugins/hooks.rb +132 -0
- data/lib/gsd/plugins/installer.rb +158 -0
- data/lib/gsd/plugins/loader.rb +122 -0
- data/lib/gsd/plugins/manager.rb +187 -0
- data/lib/gsd/plugins/marketplace.rb +142 -0
- data/lib/gsd/plugins/sandbox.rb +114 -0
- data/lib/gsd/plugins/search.rb +131 -0
- data/lib/gsd/plugins/validator.rb +157 -0
- data/lib/gsd/plugins.rb +48 -0
- data/lib/gsd/profile.rb +127 -0
- data/lib/gsd/research.rb +85 -0
- data/lib/gsd/roadmap.rb +90 -0
- data/lib/gsd/skills/bundled/commit.md +58 -0
- data/lib/gsd/skills/bundled/debug.md +28 -0
- data/lib/gsd/skills/bundled/explain.md +41 -0
- data/lib/gsd/skills/bundled/plan.md +42 -0
- data/lib/gsd/skills/bundled/verify.md +26 -0
- data/lib/gsd/skills/loader.rb +189 -0
- data/lib/gsd/state.rb +102 -0
- data/lib/gsd/template.rb +106 -0
- data/lib/gsd/tools/ask_user_question.rb +179 -0
- data/lib/gsd/tools/base.rb +204 -0
- data/lib/gsd/tools/bash.rb +246 -0
- data/lib/gsd/tools/file_edit.rb +297 -0
- data/lib/gsd/tools/file_read.rb +199 -0
- data/lib/gsd/tools/file_write.rb +153 -0
- data/lib/gsd/tools/glob.rb +202 -0
- data/lib/gsd/tools/grep.rb +227 -0
- data/lib/gsd/tools/gsd_frontmatter.rb +165 -0
- data/lib/gsd/tools/gsd_phase.rb +140 -0
- data/lib/gsd/tools/gsd_roadmap.rb +108 -0
- data/lib/gsd/tools/gsd_state.rb +143 -0
- data/lib/gsd/tools/gsd_template.rb +157 -0
- data/lib/gsd/tools/gsd_verify.rb +159 -0
- data/lib/gsd/tools/registry.rb +103 -0
- data/lib/gsd/tools/task.rb +235 -0
- data/lib/gsd/tools/todo_write.rb +290 -0
- data/lib/gsd/tools/web.rb +260 -0
- data/lib/gsd/tui/app.rb +366 -0
- data/lib/gsd/tui/auto_complete.rb +79 -0
- data/lib/gsd/tui/colors.rb +111 -0
- data/lib/gsd/tui/command_palette.rb +126 -0
- data/lib/gsd/tui/header.rb +38 -0
- data/lib/gsd/tui/input_box.rb +199 -0
- data/lib/gsd/tui/spinner.rb +40 -0
- data/lib/gsd/tui/status_bar.rb +51 -0
- data/lib/gsd/tui.rb +17 -0
- data/lib/gsd/validator.rb +216 -0
- data/lib/gsd/verify.rb +175 -0
- data/lib/gsd/version.rb +5 -0
- data/lib/gsd/workstream.rb +91 -0
- 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)
|