Skip to content

Commit e3adc84

Browse files
authored
Merge pull request #274 from shelltime/claude/show-command-context-info-ej2YW
feat(cli): send pwd and hostname with shelltime q
2 parents 88967e8 + 8ea0ced commit e3adc84

4 files changed

Lines changed: 38 additions & 10 deletions

File tree

commands/query.go

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ func commandQuery(c *cli.Context) error {
6060
}
6161

6262
// Get system context
63-
systemContext, err := getSystemContext(query)
63+
systemContext, err := getSystemContext(query, cfg.AI)
6464
if err != nil {
6565
slog.Warn("Failed to get system context", slog.Any("err", err))
6666
}
@@ -225,7 +225,7 @@ func sanitizeSuggestedCommand(raw string) string {
225225
return s
226226
}
227227

228-
func getSystemContext(query string) (model.CommandSuggestVariables, error) {
228+
func getSystemContext(query string, ai *model.AIConfig) (model.CommandSuggestVariables, error) {
229229
// Get shell information
230230
shell := os.Getenv("SHELL")
231231
if shell == "" {
@@ -240,9 +240,25 @@ func getSystemContext(query string) (model.CommandSuggestVariables, error) {
240240
// Get OS information
241241
osInfo := runtime.GOOS
242242

243-
return model.CommandSuggestVariables{
243+
vars := model.CommandSuggestVariables{
244244
Shell: shell,
245245
Os: osInfo,
246246
Query: query,
247-
}, nil
247+
}
248+
249+
// Skip context fields when the user has opted out via config:
250+
// [ai]
251+
// shareContext = false
252+
if ai != nil && ai.ShareContext != nil && !*ai.ShareContext {
253+
return vars, nil
254+
}
255+
256+
if pwd, err := os.Getwd(); err == nil {
257+
vars.Pwd = pwd
258+
}
259+
if host, err := os.Hostname(); err == nil {
260+
vars.Hostname = host
261+
}
262+
263+
return vars, nil
248264
}

commands/query_test.go

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -326,25 +326,32 @@ func (s *queryTestSuite) TestGetSystemContext() {
326326
os.Setenv("SHELL", "/bin/bash")
327327
defer os.Setenv("SHELL", originalShell)
328328

329-
context, err := getSystemContext(query)
329+
context, err := getSystemContext(query, nil)
330330
assert.Nil(s.T(), err)
331331
assert.Equal(s.T(), "bash", context.Shell)
332332
assert.Equal(s.T(), runtime.GOOS, context.Os)
333333
assert.Equal(s.T(), query, context.Query)
334334

335335
// Test with no SHELL environment variable
336336
os.Unsetenv("SHELL")
337-
context, err = getSystemContext(query)
337+
context, err = getSystemContext(query, nil)
338338
assert.Nil(s.T(), err)
339339
assert.Equal(s.T(), "unknown", context.Shell)
340340
assert.Equal(s.T(), runtime.GOOS, context.Os)
341341
assert.Equal(s.T(), query, context.Query)
342342

343343
// Test with full path shell
344344
os.Setenv("SHELL", "/usr/local/bin/zsh")
345-
context, err = getSystemContext(query)
345+
context, err = getSystemContext(query, nil)
346346
assert.Nil(s.T(), err)
347347
assert.Equal(s.T(), "zsh", context.Shell)
348+
349+
// Opt-out: when ShareContext is explicitly false, pwd/hostname are omitted.
350+
disabled := false
351+
context, err = getSystemContext(query, &model.AIConfig{ShareContext: &disabled})
352+
assert.Nil(s.T(), err)
353+
assert.Empty(s.T(), context.Pwd)
354+
assert.Empty(s.T(), context.Hostname)
348355
}
349356

350357
func (s *queryTestSuite) TestQueryCommandWithAlias() {

model/ai_service.go

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,11 @@ type AIService interface {
1717
}
1818

1919
type CommandSuggestVariables struct {
20-
Shell string `json:"shell"`
21-
Os string `json:"os"`
22-
Query string `json:"query"`
20+
Shell string `json:"shell"`
21+
Os string `json:"os"`
22+
Query string `json:"query"`
23+
Pwd string `json:"pwd,omitempty"`
24+
Hostname string `json:"hostname,omitempty"`
2325
}
2426

2527
type sseAIService struct{}

model/types.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@ type AIAgentConfig struct {
1919
type AIConfig struct {
2020
Agent AIAgentConfig `toml:"agent,omitempty" yaml:"agent,omitempty" json:"agent,omitempty"`
2121
ShowTips *bool `toml:"showTips" yaml:"showTips" json:"showTips"`
22+
// ShareContext controls whether `shelltime q` sends the working directory
23+
// and hostname alongside the prompt. Defaults to true if unset.
24+
ShareContext *bool `toml:"shareContext,omitempty" yaml:"shareContext,omitempty" json:"shareContext,omitempty"`
2225
}
2326

2427
type CCUsage struct {

0 commit comments

Comments
 (0)