ask-tools-shell 0.5.3 → 0.6.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 042db14123fc60cfaa1f3c98dd182f971260699e5d024f00decd65774104bc8b
4
- data.tar.gz: 650b21f53bef758083a06ca4a9ffe0d87e7f4dd3caf68e354d6317e92e4d11ce
3
+ metadata.gz: 2407410de312f720991b648cadfdbd84aac2986d87724c11e065c7e0b8d72c21
4
+ data.tar.gz: 585878ed410c7beff114eb62dd1dd4eb33b7fbe266fd889381d40b971ffd44a6
5
5
  SHA512:
6
- metadata.gz: 3886e03d86475235824a83dca6fc17d6cdfe8c43971f6120f93ff21811879daf2dd74cbf7c4c60962280d2a2e8a9593e69f4ecd9a803fe3ba05db728ba163035
7
- data.tar.gz: d459146b5df5ade3a3f9063c37cec837f285ec738b5435f245047f89a72306e986681087495ad65d54dad9e7c2fda4bd8b8aa851e72a83502e434b8eb5592988
6
+ metadata.gz: 6ac091ee7160a917a112846c6ace5e314013fcbd690d05689043111635a68cebf91fcf84ebea29be7c895acbd83854035637c91f1567f4dcc73874596a6f43e7
7
+ data.tar.gz: 4c6f5fe647154f278132ef95ce1c659478fad636e30ae86fd99847bcc95dcfc8d4958c043d3877bc93a40d7b75b041913d93f772c3952c5dcfff04fb4c96dab4
data/CHANGELOG.md CHANGED
@@ -1,3 +1,16 @@
1
+ ## [0.6.0] - 2026-08-14
2
+
3
+ ### Added
4
+ - **Git tools** — a scoped git surface for workspace sessions, run through
5
+ the sandbox (never a free-form shell, argv-array so nothing passes through
6
+ a shell): `git_status` (branch + changed files), `git_diff` (unstaged,
7
+ staged with `cached`, optional `path`), `git_log` (recent commits, optional
8
+ `count`), `git_commit` (commits only what is staged), `git_branch`
9
+ (current + local branches), `git_worktree` (worktree list). Each tool
10
+ honors `default_workdir` (the session workspace, pinned by the host) and
11
+ refuses loudly without one; all are registered in the global registry so
12
+ any host resolves them by name.
13
+
1
14
  ## [0.5.1] - 2026-08-10
2
15
 
3
16
  ### Fixed
@@ -16,7 +16,14 @@ module Ask
16
16
  param :timeout, type: :integer, desc: "Timeout in seconds", required: false
17
17
  param :workdir, type: :string, desc: "Working directory", required: false
18
18
 
19
+ # The session's workspace: set by the host when it builds the
20
+ # session's tools, so commands without an explicit cd run in the
21
+ # agent's workspace — not in the host process's cwd. The agent
22
+ # can still override with an explicit workdir or cd.
23
+ attr_accessor :default_workdir
24
+
19
25
  def execute(command:, timeout: 30, workdir: nil)
26
+ workdir ||= default_workdir
20
27
  result = Ask::Sandbox.provider.call(
21
28
  command,
22
29
  timeout: timeout,
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "ask-sandbox-providers"
4
+
5
+ module Ask
6
+ module Tools
7
+ module Git
8
+ # Shared plumbing for the git tools: run scoped git commands in
9
+ # the workspace through the sandbox — the same provider bash
10
+ # uses, but with a fixed command (never a free-form shell) and
11
+ # argv-array form (nothing passes through a shell, so a hostile
12
+ # value stays a value).
13
+ #
14
+ # The host pins default_workdir to the session's workspace (the
15
+ # same mechanism Bash's workdir uses); a tool invoked without a
16
+ # workspace — outside a session — refuses loudly rather than
17
+ # touching the host's own checkout.
18
+ class Base < Ask::Tool
19
+ # The session's workspace: set by the host when it builds the
20
+ # session's tools.
21
+ attr_accessor :default_workdir
22
+
23
+ private
24
+
25
+ # Run git with the given arguments in the workspace and map
26
+ # the sandbox result to Ask::Result, the ecosystem convention.
27
+ def git(*args, timeout: 30)
28
+ if default_workdir.to_s.empty?
29
+ return Ask::Result.error(message: "git tools need a session workspace")
30
+ end
31
+
32
+ result = Ask::Sandbox.provider.call(["git", *args], timeout: timeout, workdir: default_workdir)
33
+ data = {stdout: result.stdout, stderr: result.stderr, exit_code: result.exit_code, timed_out: result.timed_out}
34
+ if result.success?
35
+ Ask::Result.ok(data: data)
36
+ else
37
+ stderr = result.stderr.to_s.strip
38
+ Ask::Result.error(message: stderr.empty? ? "git failed" : stderr, metadata: data)
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Ask
4
+ module Tools
5
+ module Git
6
+ # The workspace's branches: which one is checked out, and what
7
+ # else exists. Read-only.
8
+ class Branch < Base
9
+ description "Show the current branch and all local branches in the workspace. Read-only."
10
+ name "git_branch"
11
+
12
+ def execute
13
+ git("branch", "--list")
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Ask
4
+ module Tools
5
+ module Git
6
+ # Commit the staged changes with a message. The one mutation in
7
+ # the git toolkit: the executor's deliverable becomes history.
8
+ # Commits only what is staged — staging stays a deliberate act.
9
+ class Commit < Base
10
+ description "Commit the staged changes in the workspace with the given message. " \
11
+ "Mutating — only what is staged is committed."
12
+ name "git_commit"
13
+
14
+ params do
15
+ string :message, description: "The commit message", required: true
16
+ end
17
+
18
+ def execute(message:)
19
+ git("commit", "-m", message)
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Ask
4
+ module Tools
5
+ module Git
6
+ # The changes themselves: an unstaged diff by default, staged
7
+ # with `cached`, optionally limited to one path. Read-only —
8
+ # the executor reads before it writes.
9
+ class Diff < Base
10
+ description "Show the uncommitted diff in the workspace: unstaged by default, " \
11
+ "staged with cached: true, optionally limited to one path. Read-only."
12
+ name "git_diff"
13
+
14
+ params do
15
+ boolean :cached, description: "Diff the staged changes instead", required: false
16
+ string :path, description: "Limit the diff to this path", required: false
17
+ end
18
+
19
+ def execute(cached: false, path: nil)
20
+ args = ["diff"]
21
+ args << "--cached" if cached
22
+ args += ["--", path] if path
23
+ git(*args)
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Ask
4
+ module Tools
5
+ module Git
6
+ # Recent commit history: hash, subject, author, relative time —
7
+ # the executor's sense of where the branch has been. Read-only.
8
+ class Log < Base
9
+ description "Show the recent commit history: hash, subject, author, and relative time. Read-only."
10
+ name "git_log"
11
+
12
+ params do
13
+ integer :count, description: "How many commits to show", required: false
14
+ end
15
+
16
+ def execute(count: 20)
17
+ git("log", "--oneline", "-n", count.to_s)
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Ask
4
+ module Tools
5
+ module Git
6
+ # The working tree's state: current branch plus staged, unstaged,
7
+ # and untracked changes — what the workspace looks like since the
8
+ # last commit. The executor's first question before touching code.
9
+ class Status < Base
10
+ description "Show the git working tree status: current branch and changed files " \
11
+ "(staged, unstaged, untracked). Read-only."
12
+ name "git_status"
13
+
14
+ def execute
15
+ git("status", "--short", "--branch")
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Ask
4
+ module Tools
5
+ module Git
6
+ # The workspace's worktrees: paths, branches, and checked-out
7
+ # commits — parallel work happening in the same repository.
8
+ # Read-only.
9
+ class Worktree < Base
10
+ description "Show the git worktrees in the workspace: path, branch, and commit. Read-only."
11
+ name "git_worktree"
12
+
13
+ def execute
14
+ git("worktree", "list")
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -3,7 +3,7 @@
3
3
  module Ask
4
4
  module Tools
5
5
  module Shell
6
- VERSION = "0.5.3"
6
+ VERSION = "0.6.1"
7
7
  end
8
8
  end
9
9
  end
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative "shell/version"
4
- require "ask/tools/tool"
4
+ require "ask/tools"
5
5
  require_relative "shell/bash"
6
6
  require_relative "shell/read"
7
7
  require_relative "shell/file_ledger"
@@ -12,11 +12,19 @@ require_relative "shell/grep"
12
12
  require_relative "shell/code"
13
13
  require_relative "shell/apply_patch"
14
14
  require_relative "shell/repl"
15
+ require_relative "shell/git/base"
16
+ require_relative "shell/git/status"
17
+ require_relative "shell/git/diff"
18
+ require_relative "shell/git/log"
19
+ require_relative "shell/git/commit"
20
+ require_relative "shell/git/branch"
21
+ require_relative "shell/git/worktree"
15
22
 
16
23
  module Ask
17
24
  module Tools
18
25
  module Shell
19
- TOOLS = [Bash, Read, Write, Edit, Glob, Grep, Code, ApplyPatch, Repl].freeze
26
+ TOOLS = [Bash, Read, Write, Edit, Glob, Grep, Code, ApplyPatch, Repl,
27
+ Git::Status, Git::Diff, Git::Log, Git::Commit, Git::Branch, Git::Worktree].freeze
20
28
 
21
29
  def self.all
22
30
  TOOLS.map(&:new)
@@ -24,3 +32,13 @@ module Ask
24
32
  end
25
33
  end
26
34
  end
35
+
36
+ # The git tools resolve by name from the global registry (the host's
37
+ # name-based fallback for non-built-in tools) — registering here makes
38
+ # them available to any host that loads ask-tools-shell.
39
+ Ask::Tools.register(Ask::Tools::Git::Status)
40
+ Ask::Tools.register(Ask::Tools::Git::Diff)
41
+ Ask::Tools.register(Ask::Tools::Git::Log)
42
+ Ask::Tools.register(Ask::Tools::Git::Commit)
43
+ Ask::Tools.register(Ask::Tools::Git::Branch)
44
+ Ask::Tools.register(Ask::Tools::Git::Worktree)
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ask-tools-shell
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.3
4
+ version: 0.6.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kaka Ruto
@@ -98,6 +98,13 @@ files:
98
98
  - lib/ask/tools/shell/edit.rb
99
99
  - lib/ask/tools/shell/file_ledger.rb
100
100
  - lib/ask/tools/shell/file_mutation_queue.rb
101
+ - lib/ask/tools/shell/git/base.rb
102
+ - lib/ask/tools/shell/git/branch.rb
103
+ - lib/ask/tools/shell/git/commit.rb
104
+ - lib/ask/tools/shell/git/diff.rb
105
+ - lib/ask/tools/shell/git/log.rb
106
+ - lib/ask/tools/shell/git/status.rb
107
+ - lib/ask/tools/shell/git/worktree.rb
101
108
  - lib/ask/tools/shell/glob.rb
102
109
  - lib/ask/tools/shell/grep.rb
103
110
  - lib/ask/tools/shell/read.rb