feat: Embedded baseline MCP config and global tools
This commit is contained in:
@@ -0,0 +1,35 @@
|
|||||||
|
{
|
||||||
|
"mcpServers": {
|
||||||
|
"github": {
|
||||||
|
"command": "docker",
|
||||||
|
"args": [
|
||||||
|
"run",
|
||||||
|
"-i",
|
||||||
|
"--rm",
|
||||||
|
"-e",
|
||||||
|
"GITHUB_PERSONAL_ACCESS_TOKEN",
|
||||||
|
"ghcr.io/github/github-mcp-server"
|
||||||
|
],
|
||||||
|
"env": {
|
||||||
|
"GITHUB_PERSONAL_ACCESS_TOKEN": "{{GITHUB_PERSONAL_ACCESS_TOKEN}}"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"gitmcp": {
|
||||||
|
"command": "npx",
|
||||||
|
"args": ["mcp-remote", "https://gitmcp.io/docs"]
|
||||||
|
},
|
||||||
|
"docker": {
|
||||||
|
"command": "uvx",
|
||||||
|
"args": ["docker-mcp"]
|
||||||
|
},
|
||||||
|
"slack": {
|
||||||
|
"command": "npx",
|
||||||
|
"args": ["-y", "slack-mcp-server@latest", "--transport", "stdio"],
|
||||||
|
"env": {
|
||||||
|
"SLACK_MCP_XOXC_TOKEN": "{{SLACK_MCP_XOXC_TOKEN}}",
|
||||||
|
"SLACK_MCP_XOXD_TOKEN": "{{SLACK_MCP_XOXD_TOKEN}}",
|
||||||
|
"SLACK_MCP_ADD_MESSAGE_TOOL": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
# demo_py.py
|
||||||
|
# demo_sh.sh
|
||||||
|
execute_command.sh
|
||||||
|
# execute_py_code.py
|
||||||
|
# execute_sql_code.sh
|
||||||
|
# fetch_url_via_curl.sh
|
||||||
|
# fetch_url_via_jina.sh
|
||||||
|
fs_cat.sh
|
||||||
|
fs_ls.sh
|
||||||
|
# fs_mkdir.sh
|
||||||
|
# fs_patch.sh
|
||||||
|
# fs_write.sh
|
||||||
|
get_current_time.sh
|
||||||
|
# get_current_weather.py
|
||||||
|
get_current_weather.sh
|
||||||
|
query_jira_issues.sh
|
||||||
|
# search_arxiv.sh
|
||||||
|
# search_wikipedia.sh
|
||||||
|
# search_wolframalpha.sh
|
||||||
|
# send_mail.sh
|
||||||
|
# send_twilio.sh
|
||||||
|
# web_search_loki.sh
|
||||||
|
# web_search_perplexity.sh
|
||||||
|
# web_search_tavily.sh
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
import os
|
||||||
|
from typing import List, Literal, Optional
|
||||||
|
|
||||||
|
def run(
|
||||||
|
string: str,
|
||||||
|
string_enum: Literal["foo", "bar"],
|
||||||
|
boolean: bool,
|
||||||
|
integer: int,
|
||||||
|
number: float,
|
||||||
|
array: List[str],
|
||||||
|
string_optional: Optional[str] = None,
|
||||||
|
array_optional: Optional[List[str]] = None,
|
||||||
|
):
|
||||||
|
"""Demonstrates how to create a tool using Python and how to use comments.
|
||||||
|
Args:
|
||||||
|
string: Define a required string property
|
||||||
|
string_enum: Define a required string property with enum
|
||||||
|
boolean: Define a required boolean property
|
||||||
|
integer: Define a required integer property
|
||||||
|
number: Define a required number property
|
||||||
|
array: Define a required string array property
|
||||||
|
string_optional: Define an optional string property
|
||||||
|
array_optional: Define an optional string array property
|
||||||
|
"""
|
||||||
|
output = f"""string: {string}
|
||||||
|
string_enum: {string_enum}
|
||||||
|
string_optional: {string_optional}
|
||||||
|
boolean: {boolean}
|
||||||
|
integer: {integer}
|
||||||
|
number: {number}
|
||||||
|
array: {array}
|
||||||
|
array_optional: {array_optional}"""
|
||||||
|
|
||||||
|
for key, value in os.environ.items():
|
||||||
|
if key.startswith("LLM_"):
|
||||||
|
output = f"{output}\n{key}: {value}"
|
||||||
|
|
||||||
|
return output
|
||||||
Executable
+29
@@ -0,0 +1,29 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# @describe Demonstrate how to create a tool using Bash and how to use comment tags.
|
||||||
|
# @option --string! Define a required string property
|
||||||
|
# @option --string-enum![foo|bar] Define a required string property with enum
|
||||||
|
# @option --string-optional Define a optional string property
|
||||||
|
# @flag --boolean Define a boolean property
|
||||||
|
# @option --integer! <INT> Define a required integer property
|
||||||
|
# @option --number! <NUM> Define a required number property
|
||||||
|
# @option --array+ <VALUE> Define a required string array property
|
||||||
|
# @option --array-optional* Define a optional string array property
|
||||||
|
|
||||||
|
# @env LLM_OUTPUT=/dev/stdout The output path
|
||||||
|
|
||||||
|
# shellcheck disable=SC2154
|
||||||
|
main() {
|
||||||
|
cat <<EOF >> "$LLM_OUTPUT"
|
||||||
|
string: ${argc_string}
|
||||||
|
string_enum: ${argc_string_enum}
|
||||||
|
string_optional: ${argc_string_optional}
|
||||||
|
boolean: ${argc_boolean}
|
||||||
|
integer: ${argc_integer}
|
||||||
|
number: ${argc_number}
|
||||||
|
array: ${argc_array[@]}
|
||||||
|
array_optional: ${argc_array_optional[@]}
|
||||||
|
$(printenv | grep '^LLM_')
|
||||||
|
EOF
|
||||||
|
}
|
||||||
Executable
+204
@@ -0,0 +1,204 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# @describe Execute the shell command.
|
||||||
|
# @option --command! The command to execute.
|
||||||
|
|
||||||
|
# @env LLM_OUTPUT=/dev/stdout The output path
|
||||||
|
|
||||||
|
PROMPT_UTILS="${LLM_ROOT_DIR:-$(dirname "${BASH_SOURCE[0]}")/..}/utils/prompt-utils.sh"
|
||||||
|
# shellcheck disable=SC1090
|
||||||
|
source "$PROMPT_UTILS"
|
||||||
|
|
||||||
|
main() {
|
||||||
|
guard_operation
|
||||||
|
# shellcheck disable=SC2154
|
||||||
|
eval "$argc_command" >> "$LLM_OUTPUT"
|
||||||
|
}
|
||||||
|
|
||||||
|
# ARGC-BUILD {
|
||||||
|
# This block was generated by argc (https://github.com/sigoden/argc).
|
||||||
|
# Modifying it manually is not recommended
|
||||||
|
|
||||||
|
_argc_run() {
|
||||||
|
if [[ "${1:-}" == "___internal___" ]]; then
|
||||||
|
_argc_die "error: unsupported ___internal___ command"
|
||||||
|
fi
|
||||||
|
if [[ "${OS:-}" == "Windows_NT" ]] && [[ -n "${MSYSTEM:-}" ]]; then
|
||||||
|
set -o igncr
|
||||||
|
fi
|
||||||
|
argc__args=("$(basename "$0" .sh)" "$@")
|
||||||
|
argc__positionals=()
|
||||||
|
_argc_index=1
|
||||||
|
_argc_len="${#argc__args[@]}"
|
||||||
|
_argc_tools=()
|
||||||
|
_argc_parse
|
||||||
|
if [ -n "${argc__fn:-}" ]; then
|
||||||
|
$argc__fn "${argc__positionals[@]}"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
_argc_usage() {
|
||||||
|
cat <<-'EOF'
|
||||||
|
Execute the shell command.
|
||||||
|
|
||||||
|
USAGE: --command <COMMAND>
|
||||||
|
|
||||||
|
OPTIONS:
|
||||||
|
--command <COMMAND> The command to execute.
|
||||||
|
-h, --help Print help
|
||||||
|
-V, --version Print version
|
||||||
|
|
||||||
|
ENVIRONMENTS:
|
||||||
|
LLM_OUTPUT The output path [default: /dev/stdout]
|
||||||
|
EOF
|
||||||
|
exit
|
||||||
|
}
|
||||||
|
|
||||||
|
_argc_version() {
|
||||||
|
echo 0.0.0
|
||||||
|
exit
|
||||||
|
}
|
||||||
|
|
||||||
|
_argc_parse() {
|
||||||
|
local _argc_key _argc_action
|
||||||
|
local _argc_subcmds=""
|
||||||
|
while [[ $_argc_index -lt $_argc_len ]]; do
|
||||||
|
_argc_item="${argc__args[_argc_index]}"
|
||||||
|
_argc_key="${_argc_item%%=*}"
|
||||||
|
case "$_argc_key" in
|
||||||
|
--help | -help | -h)
|
||||||
|
_argc_usage
|
||||||
|
;;
|
||||||
|
--version | -version | -V)
|
||||||
|
_argc_version
|
||||||
|
;;
|
||||||
|
--)
|
||||||
|
_argc_dash="${#argc__positionals[@]}"
|
||||||
|
argc__positionals+=("${argc__args[@]:$((_argc_index + 1))}")
|
||||||
|
_argc_index=$_argc_len
|
||||||
|
break
|
||||||
|
;;
|
||||||
|
--command)
|
||||||
|
_argc_take_args "--command <COMMAND>" 1 1 "-" ""
|
||||||
|
_argc_index=$((_argc_index + _argc_take_args_len + 1))
|
||||||
|
if [[ -z "${argc_command:-}" ]]; then
|
||||||
|
argc_command="${_argc_take_args_values[0]:-}"
|
||||||
|
else
|
||||||
|
_argc_die "error: the argument \`--command\` cannot be used multiple times"
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
if _argc_maybe_flag_option "-" "$_argc_item"; then
|
||||||
|
_argc_die "error: unexpected argument \`$_argc_key\` found"
|
||||||
|
fi
|
||||||
|
argc__positionals+=("$_argc_item")
|
||||||
|
_argc_index=$((_argc_index + 1))
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
_argc_require_params "error: the following required arguments were not provided:" \
|
||||||
|
'argc_command:--command <COMMAND>'
|
||||||
|
if [[ -n "${_argc_action:-}" ]]; then
|
||||||
|
$_argc_action
|
||||||
|
else
|
||||||
|
argc__fn=main
|
||||||
|
if [[ "${argc__positionals[0]:-}" == "help" ]] && [[ "${#argc__positionals[@]}" -eq 1 ]]; then
|
||||||
|
_argc_usage
|
||||||
|
fi
|
||||||
|
if [[ -z "${LLM_OUTPUT:-}" ]]; then
|
||||||
|
export LLM_OUTPUT=/dev/stdout
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
_argc_take_args() {
|
||||||
|
_argc_take_args_values=()
|
||||||
|
_argc_take_args_len=0
|
||||||
|
local param="$1" min="$2" max="$3" signs="$4" delimiter="$5"
|
||||||
|
if [[ "$min" -eq 0 ]] && [[ "$max" -eq 0 ]]; then
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
local _argc_take_index=$((_argc_index + 1)) _argc_take_value
|
||||||
|
if [[ "$_argc_item" == *=* ]]; then
|
||||||
|
_argc_take_args_values=("${_argc_item##*=}")
|
||||||
|
else
|
||||||
|
while [[ $_argc_take_index -lt $_argc_len ]]; do
|
||||||
|
_argc_take_value="${argc__args[_argc_take_index]}"
|
||||||
|
if _argc_maybe_flag_option "$signs" "$_argc_take_value"; then
|
||||||
|
if [[ "${#_argc_take_value}" -gt 1 ]]; then
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
_argc_take_args_values+=("$_argc_take_value")
|
||||||
|
_argc_take_args_len=$((_argc_take_args_len + 1))
|
||||||
|
if [[ "$_argc_take_args_len" -ge "$max" ]]; then
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
_argc_take_index=$((_argc_take_index + 1))
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
if [[ "${#_argc_take_args_values[@]}" -lt "$min" ]]; then
|
||||||
|
_argc_die "error: incorrect number of values for \`$param\`"
|
||||||
|
fi
|
||||||
|
if [[ -n "$delimiter" ]] && [[ "${#_argc_take_args_values[@]}" -gt 0 ]]; then
|
||||||
|
local item values arr=()
|
||||||
|
for item in "${_argc_take_args_values[@]}"; do
|
||||||
|
IFS="$delimiter" read -r -a values <<<"$item"
|
||||||
|
arr+=("${values[@]}")
|
||||||
|
done
|
||||||
|
_argc_take_args_values=("${arr[@]}")
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
_argc_require_params() {
|
||||||
|
local message="$1" missed_envs="" item name render_name
|
||||||
|
for item in "${@:2}"; do
|
||||||
|
name="${item%%:*}"
|
||||||
|
render_name="${item##*:}"
|
||||||
|
if [[ -z "${!name:-}" ]]; then
|
||||||
|
missed_envs="$missed_envs"$'\n'" $render_name"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
if [[ -n "${missed_envs}" ]]; then
|
||||||
|
_argc_die "$message$missed_envs"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
_argc_maybe_flag_option() {
|
||||||
|
local signs="$1" arg="$2"
|
||||||
|
if [[ -z "$signs" ]]; then
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
local cond=false
|
||||||
|
if [[ "$signs" == *"+"* ]]; then
|
||||||
|
if [[ "$arg" =~ ^\+[^+].* ]]; then
|
||||||
|
cond=true
|
||||||
|
fi
|
||||||
|
elif [[ "$arg" == -* ]]; then
|
||||||
|
if (( ${#arg} < 3 )) || [[ ! "$arg" =~ ^---.* ]]; then
|
||||||
|
cond=true
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
if [[ "$cond" == "false" ]]; then
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
local value="${arg%%=*}"
|
||||||
|
if [[ "$value" =~ [[:space:]] ]]; then
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
_argc_die() {
|
||||||
|
if [[ $# -eq 0 ]]; then
|
||||||
|
cat
|
||||||
|
else
|
||||||
|
echo "$*" >&2
|
||||||
|
fi
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
_argc_run "$@"
|
||||||
|
|
||||||
|
# ARGC-BUILD }
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
import ast
|
||||||
|
import io
|
||||||
|
from contextlib import redirect_stdout
|
||||||
|
|
||||||
|
|
||||||
|
def run(code: str):
|
||||||
|
"""Execute the python code.
|
||||||
|
Args:
|
||||||
|
code: Python code to execute, such as `print("hello world")`
|
||||||
|
"""
|
||||||
|
output = io.StringIO()
|
||||||
|
with redirect_stdout(output):
|
||||||
|
value = exec_with_return(code, {}, {})
|
||||||
|
|
||||||
|
if value is not None:
|
||||||
|
output.write(str(value))
|
||||||
|
|
||||||
|
return output.getvalue()
|
||||||
|
|
||||||
|
|
||||||
|
def exec_with_return(code: str, globals: dict, locals: dict):
|
||||||
|
a = ast.parse(code)
|
||||||
|
last_expression = None
|
||||||
|
if a.body:
|
||||||
|
if isinstance(a_last := a.body[-1], ast.Expr):
|
||||||
|
last_expression = ast.unparse(a.body.pop())
|
||||||
|
elif isinstance(a_last, ast.Assign):
|
||||||
|
last_expression = ast.unparse(a_last.targets[0])
|
||||||
|
elif isinstance(a_last, (ast.AnnAssign, ast.AugAssign)):
|
||||||
|
last_expression = ast.unparse(a_last.target)
|
||||||
|
exec(ast.unparse(a), globals, locals)
|
||||||
|
if last_expression:
|
||||||
|
return eval(last_expression, globals, locals)
|
||||||
Executable
+22
@@ -0,0 +1,22 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# @describe Execute sql code.
|
||||||
|
# @option --code! The code to execute.
|
||||||
|
|
||||||
|
# @meta require-tools usql
|
||||||
|
|
||||||
|
# @env USQL_DSN! The database connection url. e.g. pgsql://user:pass@host:port
|
||||||
|
# @env LLM_OUTPUT=/dev/stdout The output path
|
||||||
|
|
||||||
|
PROMPT_UTILS="${LLM_ROOT_DIR:-$(dirname "${BASH_SOURCE[0]}")/..}/utils/prompt-utils.sh"
|
||||||
|
# shellcheck disable=SC1090
|
||||||
|
source "$PROMPT_UTILS"
|
||||||
|
|
||||||
|
# shellcheck disable=SC2154
|
||||||
|
main() {
|
||||||
|
if ! grep -qi '^select' <<<"$argc_code"; then
|
||||||
|
guard_operation ""
|
||||||
|
fi
|
||||||
|
usql -c "$argc_code" "$USQL_DSN" >> "$LLM_OUTPUT"
|
||||||
|
}
|
||||||
Executable
+18
@@ -0,0 +1,18 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# @describe Extract the content from a given URL.
|
||||||
|
# @option --url! The URL to scrape.
|
||||||
|
|
||||||
|
# @meta require-tools pandoc
|
||||||
|
|
||||||
|
# @env LLM_OUTPUT=/dev/stdout The output path
|
||||||
|
|
||||||
|
# shellcheck disable=SC2154
|
||||||
|
main() {
|
||||||
|
# span and div tags are dropped from the HTML https://pandoc.org/MANUAL.html#raw-htmltex and sed removes any inline SVG images in image tags from the Markdown content.
|
||||||
|
curl -fsSL "$argc_url" | \
|
||||||
|
pandoc -f html-native_divs-native_spans -t gfm-raw_html --wrap=none | \
|
||||||
|
sed -E 's/!\[[^]]*\]\([^)]*\)//g' \
|
||||||
|
>> "$LLM_OUTPUT"
|
||||||
|
}
|
||||||
Executable
+17
@@ -0,0 +1,17 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# @describe Extract the content from a given URL.
|
||||||
|
# @option --url! The URL to scrape.
|
||||||
|
|
||||||
|
# @env JINA_API_KEY Your Jina API key
|
||||||
|
# @env LLM_OUTPUT=/dev/stdout The output path
|
||||||
|
|
||||||
|
# shellcheck disable=SC2154
|
||||||
|
main() {
|
||||||
|
curl_args=()
|
||||||
|
if [[ -n "$JINA_API_KEY" ]]; then
|
||||||
|
curl_args+=("-H" "Authorization: Bearer $JINA_API_KEY")
|
||||||
|
fi
|
||||||
|
curl -fsSL "${curl_args[@]}" "https://r.jina.ai/$argc_url" >> "$LLM_OUTPUT"
|
||||||
|
}
|
||||||
Executable
+202
@@ -0,0 +1,202 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# @describe Read the contents of a file at the specified path.
|
||||||
|
# Use this when you need to examine the contents of an existing file.
|
||||||
|
|
||||||
|
# @option --path! The path of the file to read
|
||||||
|
|
||||||
|
# @env LLM_OUTPUT=/dev/stdout The output path
|
||||||
|
|
||||||
|
main() {
|
||||||
|
# shellcheck disable=SC2154
|
||||||
|
cat "$argc_path" >> "$LLM_OUTPUT"
|
||||||
|
}
|
||||||
|
|
||||||
|
# ARGC-BUILD {
|
||||||
|
# This block was generated by argc (https://github.com/sigoden/argc).
|
||||||
|
# Modifying it manually is not recommended
|
||||||
|
|
||||||
|
_argc_run() {
|
||||||
|
if [[ "${1:-}" == "___internal___" ]]; then
|
||||||
|
_argc_die "error: unsupported ___internal___ command"
|
||||||
|
fi
|
||||||
|
if [[ "${OS:-}" == "Windows_NT" ]] && [[ -n "${MSYSTEM:-}" ]]; then
|
||||||
|
set -o igncr
|
||||||
|
fi
|
||||||
|
argc__args=("$(basename "$0" .sh)" "$@")
|
||||||
|
argc__positionals=()
|
||||||
|
_argc_index=1
|
||||||
|
_argc_len="${#argc__args[@]}"
|
||||||
|
_argc_tools=()
|
||||||
|
_argc_parse
|
||||||
|
if [ -n "${argc__fn:-}" ]; then
|
||||||
|
$argc__fn "${argc__positionals[@]}"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
_argc_usage() {
|
||||||
|
cat <<-'EOF'
|
||||||
|
Read the contents of a file at the specified path.
|
||||||
|
Use this when you need to examine the contents of an existing file.
|
||||||
|
|
||||||
|
USAGE: --path <PATH>
|
||||||
|
|
||||||
|
OPTIONS:
|
||||||
|
--path <PATH> The path of the file to read
|
||||||
|
-h, --help Print help
|
||||||
|
-V, --version Print version
|
||||||
|
|
||||||
|
ENVIRONMENTS:
|
||||||
|
LLM_OUTPUT The output path [default: /dev/stdout]
|
||||||
|
EOF
|
||||||
|
exit
|
||||||
|
}
|
||||||
|
|
||||||
|
_argc_version() {
|
||||||
|
echo 0.0.0
|
||||||
|
exit
|
||||||
|
}
|
||||||
|
|
||||||
|
_argc_parse() {
|
||||||
|
local _argc_key _argc_action
|
||||||
|
local _argc_subcmds=""
|
||||||
|
while [[ $_argc_index -lt $_argc_len ]]; do
|
||||||
|
_argc_item="${argc__args[_argc_index]}"
|
||||||
|
_argc_key="${_argc_item%%=*}"
|
||||||
|
case "$_argc_key" in
|
||||||
|
--help | -help | -h)
|
||||||
|
_argc_usage
|
||||||
|
;;
|
||||||
|
--version | -version | -V)
|
||||||
|
_argc_version
|
||||||
|
;;
|
||||||
|
--)
|
||||||
|
_argc_dash="${#argc__positionals[@]}"
|
||||||
|
argc__positionals+=("${argc__args[@]:$((_argc_index + 1))}")
|
||||||
|
_argc_index=$_argc_len
|
||||||
|
break
|
||||||
|
;;
|
||||||
|
--path)
|
||||||
|
_argc_take_args "--path <PATH>" 1 1 "-" ""
|
||||||
|
_argc_index=$((_argc_index + _argc_take_args_len + 1))
|
||||||
|
if [[ -z "${argc_path:-}" ]]; then
|
||||||
|
argc_path="${_argc_take_args_values[0]:-}"
|
||||||
|
else
|
||||||
|
_argc_die "error: the argument \`--path\` cannot be used multiple times"
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
if _argc_maybe_flag_option "-" "$_argc_item"; then
|
||||||
|
_argc_die "error: unexpected argument \`$_argc_key\` found"
|
||||||
|
fi
|
||||||
|
argc__positionals+=("$_argc_item")
|
||||||
|
_argc_index=$((_argc_index + 1))
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
_argc_require_params "error: the following required arguments were not provided:" \
|
||||||
|
'argc_path:--path <PATH>'
|
||||||
|
if [[ -n "${_argc_action:-}" ]]; then
|
||||||
|
$_argc_action
|
||||||
|
else
|
||||||
|
argc__fn=main
|
||||||
|
if [[ "${argc__positionals[0]:-}" == "help" ]] && [[ "${#argc__positionals[@]}" -eq 1 ]]; then
|
||||||
|
_argc_usage
|
||||||
|
fi
|
||||||
|
if [[ -z "${LLM_OUTPUT:-}" ]]; then
|
||||||
|
export LLM_OUTPUT=/dev/stdout
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
_argc_take_args() {
|
||||||
|
_argc_take_args_values=()
|
||||||
|
_argc_take_args_len=0
|
||||||
|
local param="$1" min="$2" max="$3" signs="$4" delimiter="$5"
|
||||||
|
if [[ "$min" -eq 0 ]] && [[ "$max" -eq 0 ]]; then
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
local _argc_take_index=$((_argc_index + 1)) _argc_take_value
|
||||||
|
if [[ "$_argc_item" == *=* ]]; then
|
||||||
|
_argc_take_args_values=("${_argc_item##*=}")
|
||||||
|
else
|
||||||
|
while [[ $_argc_take_index -lt $_argc_len ]]; do
|
||||||
|
_argc_take_value="${argc__args[_argc_take_index]}"
|
||||||
|
if _argc_maybe_flag_option "$signs" "$_argc_take_value"; then
|
||||||
|
if [[ "${#_argc_take_value}" -gt 1 ]]; then
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
_argc_take_args_values+=("$_argc_take_value")
|
||||||
|
_argc_take_args_len=$((_argc_take_args_len + 1))
|
||||||
|
if [[ "$_argc_take_args_len" -ge "$max" ]]; then
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
_argc_take_index=$((_argc_take_index + 1))
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
if [[ "${#_argc_take_args_values[@]}" -lt "$min" ]]; then
|
||||||
|
_argc_die "error: incorrect number of values for \`$param\`"
|
||||||
|
fi
|
||||||
|
if [[ -n "$delimiter" ]] && [[ "${#_argc_take_args_values[@]}" -gt 0 ]]; then
|
||||||
|
local item values arr=()
|
||||||
|
for item in "${_argc_take_args_values[@]}"; do
|
||||||
|
IFS="$delimiter" read -r -a values <<<"$item"
|
||||||
|
arr+=("${values[@]}")
|
||||||
|
done
|
||||||
|
_argc_take_args_values=("${arr[@]}")
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
_argc_require_params() {
|
||||||
|
local message="$1" missed_envs="" item name render_name
|
||||||
|
for item in "${@:2}"; do
|
||||||
|
name="${item%%:*}"
|
||||||
|
render_name="${item##*:}"
|
||||||
|
if [[ -z "${!name:-}" ]]; then
|
||||||
|
missed_envs="$missed_envs"$'\n'" $render_name"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
if [[ -n "${missed_envs}" ]]; then
|
||||||
|
_argc_die "$message$missed_envs"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
_argc_maybe_flag_option() {
|
||||||
|
local signs="$1" arg="$2"
|
||||||
|
if [[ -z "$signs" ]]; then
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
local cond=false
|
||||||
|
if [[ "$signs" == *"+"* ]]; then
|
||||||
|
if [[ "$arg" =~ ^\+[^+].* ]]; then
|
||||||
|
cond=true
|
||||||
|
fi
|
||||||
|
elif [[ "$arg" == -* ]]; then
|
||||||
|
if (( ${#arg} < 3 )) || [[ ! "$arg" =~ ^---.* ]]; then
|
||||||
|
cond=true
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
if [[ "$cond" == "false" ]]; then
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
local value="${arg%%=*}"
|
||||||
|
if [[ "$value" =~ [[:space:]] ]]; then
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
_argc_die() {
|
||||||
|
if [[ $# -eq 0 ]]; then
|
||||||
|
cat
|
||||||
|
else
|
||||||
|
echo "$*" >&2
|
||||||
|
fi
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
_argc_run "$@"
|
||||||
|
|
||||||
|
# ARGC-BUILD }
|
||||||
Executable
+200
@@ -0,0 +1,200 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# @describe List all files and directories at the specified path.
|
||||||
|
|
||||||
|
# @option --path! The path of the directory to list
|
||||||
|
|
||||||
|
# @env LLM_OUTPUT=/dev/stdout The output path
|
||||||
|
|
||||||
|
main() {
|
||||||
|
# shellcheck disable=SC2154
|
||||||
|
ls -1 "$argc_path" >> "$LLM_OUTPUT"
|
||||||
|
}
|
||||||
|
|
||||||
|
# ARGC-BUILD {
|
||||||
|
# This block was generated by argc (https://github.com/sigoden/argc).
|
||||||
|
# Modifying it manually is not recommended
|
||||||
|
|
||||||
|
_argc_run() {
|
||||||
|
if [[ "${1:-}" == "___internal___" ]]; then
|
||||||
|
_argc_die "error: unsupported ___internal___ command"
|
||||||
|
fi
|
||||||
|
if [[ "${OS:-}" == "Windows_NT" ]] && [[ -n "${MSYSTEM:-}" ]]; then
|
||||||
|
set -o igncr
|
||||||
|
fi
|
||||||
|
argc__args=("$(basename "$0" .sh)" "$@")
|
||||||
|
argc__positionals=()
|
||||||
|
_argc_index=1
|
||||||
|
_argc_len="${#argc__args[@]}"
|
||||||
|
_argc_tools=()
|
||||||
|
_argc_parse
|
||||||
|
if [ -n "${argc__fn:-}" ]; then
|
||||||
|
$argc__fn "${argc__positionals[@]}"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
_argc_usage() {
|
||||||
|
cat <<-'EOF'
|
||||||
|
List all files and directories at the specified path.
|
||||||
|
|
||||||
|
USAGE: --path <PATH>
|
||||||
|
|
||||||
|
OPTIONS:
|
||||||
|
--path <PATH> The path of the directory to list
|
||||||
|
-h, --help Print help
|
||||||
|
-V, --version Print version
|
||||||
|
|
||||||
|
ENVIRONMENTS:
|
||||||
|
LLM_OUTPUT The output path [default: /dev/stdout]
|
||||||
|
EOF
|
||||||
|
exit
|
||||||
|
}
|
||||||
|
|
||||||
|
_argc_version() {
|
||||||
|
echo 0.0.0
|
||||||
|
exit
|
||||||
|
}
|
||||||
|
|
||||||
|
_argc_parse() {
|
||||||
|
local _argc_key _argc_action
|
||||||
|
local _argc_subcmds=""
|
||||||
|
while [[ $_argc_index -lt $_argc_len ]]; do
|
||||||
|
_argc_item="${argc__args[_argc_index]}"
|
||||||
|
_argc_key="${_argc_item%%=*}"
|
||||||
|
case "$_argc_key" in
|
||||||
|
--help | -help | -h)
|
||||||
|
_argc_usage
|
||||||
|
;;
|
||||||
|
--version | -version | -V)
|
||||||
|
_argc_version
|
||||||
|
;;
|
||||||
|
--)
|
||||||
|
_argc_dash="${#argc__positionals[@]}"
|
||||||
|
argc__positionals+=("${argc__args[@]:$((_argc_index + 1))}")
|
||||||
|
_argc_index=$_argc_len
|
||||||
|
break
|
||||||
|
;;
|
||||||
|
--path)
|
||||||
|
_argc_take_args "--path <PATH>" 1 1 "-" ""
|
||||||
|
_argc_index=$((_argc_index + _argc_take_args_len + 1))
|
||||||
|
if [[ -z "${argc_path:-}" ]]; then
|
||||||
|
argc_path="${_argc_take_args_values[0]:-}"
|
||||||
|
else
|
||||||
|
_argc_die "error: the argument \`--path\` cannot be used multiple times"
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
if _argc_maybe_flag_option "-" "$_argc_item"; then
|
||||||
|
_argc_die "error: unexpected argument \`$_argc_key\` found"
|
||||||
|
fi
|
||||||
|
argc__positionals+=("$_argc_item")
|
||||||
|
_argc_index=$((_argc_index + 1))
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
_argc_require_params "error: the following required arguments were not provided:" \
|
||||||
|
'argc_path:--path <PATH>'
|
||||||
|
if [[ -n "${_argc_action:-}" ]]; then
|
||||||
|
$_argc_action
|
||||||
|
else
|
||||||
|
argc__fn=main
|
||||||
|
if [[ "${argc__positionals[0]:-}" == "help" ]] && [[ "${#argc__positionals[@]}" -eq 1 ]]; then
|
||||||
|
_argc_usage
|
||||||
|
fi
|
||||||
|
if [[ -z "${LLM_OUTPUT:-}" ]]; then
|
||||||
|
export LLM_OUTPUT=/dev/stdout
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
_argc_take_args() {
|
||||||
|
_argc_take_args_values=()
|
||||||
|
_argc_take_args_len=0
|
||||||
|
local param="$1" min="$2" max="$3" signs="$4" delimiter="$5"
|
||||||
|
if [[ "$min" -eq 0 ]] && [[ "$max" -eq 0 ]]; then
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
local _argc_take_index=$((_argc_index + 1)) _argc_take_value
|
||||||
|
if [[ "$_argc_item" == *=* ]]; then
|
||||||
|
_argc_take_args_values=("${_argc_item##*=}")
|
||||||
|
else
|
||||||
|
while [[ $_argc_take_index -lt $_argc_len ]]; do
|
||||||
|
_argc_take_value="${argc__args[_argc_take_index]}"
|
||||||
|
if _argc_maybe_flag_option "$signs" "$_argc_take_value"; then
|
||||||
|
if [[ "${#_argc_take_value}" -gt 1 ]]; then
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
_argc_take_args_values+=("$_argc_take_value")
|
||||||
|
_argc_take_args_len=$((_argc_take_args_len + 1))
|
||||||
|
if [[ "$_argc_take_args_len" -ge "$max" ]]; then
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
_argc_take_index=$((_argc_take_index + 1))
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
if [[ "${#_argc_take_args_values[@]}" -lt "$min" ]]; then
|
||||||
|
_argc_die "error: incorrect number of values for \`$param\`"
|
||||||
|
fi
|
||||||
|
if [[ -n "$delimiter" ]] && [[ "${#_argc_take_args_values[@]}" -gt 0 ]]; then
|
||||||
|
local item values arr=()
|
||||||
|
for item in "${_argc_take_args_values[@]}"; do
|
||||||
|
IFS="$delimiter" read -r -a values <<<"$item"
|
||||||
|
arr+=("${values[@]}")
|
||||||
|
done
|
||||||
|
_argc_take_args_values=("${arr[@]}")
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
_argc_require_params() {
|
||||||
|
local message="$1" missed_envs="" item name render_name
|
||||||
|
for item in "${@:2}"; do
|
||||||
|
name="${item%%:*}"
|
||||||
|
render_name="${item##*:}"
|
||||||
|
if [[ -z "${!name:-}" ]]; then
|
||||||
|
missed_envs="$missed_envs"$'\n'" $render_name"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
if [[ -n "${missed_envs}" ]]; then
|
||||||
|
_argc_die "$message$missed_envs"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
_argc_maybe_flag_option() {
|
||||||
|
local signs="$1" arg="$2"
|
||||||
|
if [[ -z "$signs" ]]; then
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
local cond=false
|
||||||
|
if [[ "$signs" == *"+"* ]]; then
|
||||||
|
if [[ "$arg" =~ ^\+[^+].* ]]; then
|
||||||
|
cond=true
|
||||||
|
fi
|
||||||
|
elif [[ "$arg" == -* ]]; then
|
||||||
|
if (( ${#arg} < 3 )) || [[ ! "$arg" =~ ^---.* ]]; then
|
||||||
|
cond=true
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
if [[ "$cond" == "false" ]]; then
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
local value="${arg%%=*}"
|
||||||
|
if [[ "$value" =~ [[:space:]] ]]; then
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
_argc_die() {
|
||||||
|
if [[ $# -eq 0 ]]; then
|
||||||
|
cat
|
||||||
|
else
|
||||||
|
echo "$*" >&2
|
||||||
|
fi
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
_argc_run "$@"
|
||||||
|
|
||||||
|
# ARGC-BUILD }
|
||||||
Executable
+201
@@ -0,0 +1,201 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# @describe Create a new directory at the specified path.
|
||||||
|
|
||||||
|
# @option --path! The path of the directory to create
|
||||||
|
|
||||||
|
# @env LLM_OUTPUT=/dev/stdout The output path
|
||||||
|
|
||||||
|
main() {
|
||||||
|
# shellcheck disable=SC2154
|
||||||
|
mkdir -p "$argc_path"
|
||||||
|
echo "Directory created: $argc_path" >> "$LLM_OUTPUT"
|
||||||
|
}
|
||||||
|
|
||||||
|
# ARGC-BUILD {
|
||||||
|
# This block was generated by argc (https://github.com/sigoden/argc).
|
||||||
|
# Modifying it manually is not recommended
|
||||||
|
|
||||||
|
_argc_run() {
|
||||||
|
if [[ "${1:-}" == "___internal___" ]]; then
|
||||||
|
_argc_die "error: unsupported ___internal___ command"
|
||||||
|
fi
|
||||||
|
if [[ "${OS:-}" == "Windows_NT" ]] && [[ -n "${MSYSTEM:-}" ]]; then
|
||||||
|
set -o igncr
|
||||||
|
fi
|
||||||
|
argc__args=("$(basename "$0" .sh)" "$@")
|
||||||
|
argc__positionals=()
|
||||||
|
_argc_index=1
|
||||||
|
_argc_len="${#argc__args[@]}"
|
||||||
|
_argc_tools=()
|
||||||
|
_argc_parse
|
||||||
|
if [ -n "${argc__fn:-}" ]; then
|
||||||
|
$argc__fn "${argc__positionals[@]}"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
_argc_usage() {
|
||||||
|
cat <<-'EOF'
|
||||||
|
Create a new directory at the specified path.
|
||||||
|
|
||||||
|
USAGE: --path <PATH>
|
||||||
|
|
||||||
|
OPTIONS:
|
||||||
|
--path <PATH> The path of the directory to create
|
||||||
|
-h, --help Print help
|
||||||
|
-V, --version Print version
|
||||||
|
|
||||||
|
ENVIRONMENTS:
|
||||||
|
LLM_OUTPUT The output path [default: /dev/stdout]
|
||||||
|
EOF
|
||||||
|
exit
|
||||||
|
}
|
||||||
|
|
||||||
|
_argc_version() {
|
||||||
|
echo 0.0.0
|
||||||
|
exit
|
||||||
|
}
|
||||||
|
|
||||||
|
_argc_parse() {
|
||||||
|
local _argc_key _argc_action
|
||||||
|
local _argc_subcmds=""
|
||||||
|
while [[ $_argc_index -lt $_argc_len ]]; do
|
||||||
|
_argc_item="${argc__args[_argc_index]}"
|
||||||
|
_argc_key="${_argc_item%%=*}"
|
||||||
|
case "$_argc_key" in
|
||||||
|
--help | -help | -h)
|
||||||
|
_argc_usage
|
||||||
|
;;
|
||||||
|
--version | -version | -V)
|
||||||
|
_argc_version
|
||||||
|
;;
|
||||||
|
--)
|
||||||
|
_argc_dash="${#argc__positionals[@]}"
|
||||||
|
argc__positionals+=("${argc__args[@]:$((_argc_index + 1))}")
|
||||||
|
_argc_index=$_argc_len
|
||||||
|
break
|
||||||
|
;;
|
||||||
|
--path)
|
||||||
|
_argc_take_args "--path <PATH>" 1 1 "-" ""
|
||||||
|
_argc_index=$((_argc_index + _argc_take_args_len + 1))
|
||||||
|
if [[ -z "${argc_path:-}" ]]; then
|
||||||
|
argc_path="${_argc_take_args_values[0]:-}"
|
||||||
|
else
|
||||||
|
_argc_die "error: the argument \`--path\` cannot be used multiple times"
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
if _argc_maybe_flag_option "-" "$_argc_item"; then
|
||||||
|
_argc_die "error: unexpected argument \`$_argc_key\` found"
|
||||||
|
fi
|
||||||
|
argc__positionals+=("$_argc_item")
|
||||||
|
_argc_index=$((_argc_index + 1))
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
_argc_require_params "error: the following required arguments were not provided:" \
|
||||||
|
'argc_path:--path <PATH>'
|
||||||
|
if [[ -n "${_argc_action:-}" ]]; then
|
||||||
|
$_argc_action
|
||||||
|
else
|
||||||
|
argc__fn=main
|
||||||
|
if [[ "${argc__positionals[0]:-}" == "help" ]] && [[ "${#argc__positionals[@]}" -eq 1 ]]; then
|
||||||
|
_argc_usage
|
||||||
|
fi
|
||||||
|
if [[ -z "${LLM_OUTPUT:-}" ]]; then
|
||||||
|
export LLM_OUTPUT=/dev/stdout
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
_argc_take_args() {
|
||||||
|
_argc_take_args_values=()
|
||||||
|
_argc_take_args_len=0
|
||||||
|
local param="$1" min="$2" max="$3" signs="$4" delimiter="$5"
|
||||||
|
if [[ "$min" -eq 0 ]] && [[ "$max" -eq 0 ]]; then
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
local _argc_take_index=$((_argc_index + 1)) _argc_take_value
|
||||||
|
if [[ "$_argc_item" == *=* ]]; then
|
||||||
|
_argc_take_args_values=("${_argc_item##*=}")
|
||||||
|
else
|
||||||
|
while [[ $_argc_take_index -lt $_argc_len ]]; do
|
||||||
|
_argc_take_value="${argc__args[_argc_take_index]}"
|
||||||
|
if _argc_maybe_flag_option "$signs" "$_argc_take_value"; then
|
||||||
|
if [[ "${#_argc_take_value}" -gt 1 ]]; then
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
_argc_take_args_values+=("$_argc_take_value")
|
||||||
|
_argc_take_args_len=$((_argc_take_args_len + 1))
|
||||||
|
if [[ "$_argc_take_args_len" -ge "$max" ]]; then
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
_argc_take_index=$((_argc_take_index + 1))
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
if [[ "${#_argc_take_args_values[@]}" -lt "$min" ]]; then
|
||||||
|
_argc_die "error: incorrect number of values for \`$param\`"
|
||||||
|
fi
|
||||||
|
if [[ -n "$delimiter" ]] && [[ "${#_argc_take_args_values[@]}" -gt 0 ]]; then
|
||||||
|
local item values arr=()
|
||||||
|
for item in "${_argc_take_args_values[@]}"; do
|
||||||
|
IFS="$delimiter" read -r -a values <<<"$item"
|
||||||
|
arr+=("${values[@]}")
|
||||||
|
done
|
||||||
|
_argc_take_args_values=("${arr[@]}")
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
_argc_require_params() {
|
||||||
|
local message="$1" missed_envs="" item name render_name
|
||||||
|
for item in "${@:2}"; do
|
||||||
|
name="${item%%:*}"
|
||||||
|
render_name="${item##*:}"
|
||||||
|
if [[ -z "${!name:-}" ]]; then
|
||||||
|
missed_envs="$missed_envs"$'\n'" $render_name"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
if [[ -n "${missed_envs}" ]]; then
|
||||||
|
_argc_die "$message$missed_envs"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
_argc_maybe_flag_option() {
|
||||||
|
local signs="$1" arg="$2"
|
||||||
|
if [[ -z "$signs" ]]; then
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
local cond=false
|
||||||
|
if [[ "$signs" == *"+"* ]]; then
|
||||||
|
if [[ "$arg" =~ ^\+[^+].* ]]; then
|
||||||
|
cond=true
|
||||||
|
fi
|
||||||
|
elif [[ "$arg" == -* ]]; then
|
||||||
|
if (( ${#arg} < 3 )) || [[ ! "$arg" =~ ^---.* ]]; then
|
||||||
|
cond=true
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
if [[ "$cond" == "false" ]]; then
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
local value="${arg%%=*}"
|
||||||
|
if [[ "$value" =~ [[:space:]] ]]; then
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
_argc_die() {
|
||||||
|
if [[ $# -eq 0 ]]; then
|
||||||
|
cat
|
||||||
|
else
|
||||||
|
echo "$*" >&2
|
||||||
|
fi
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
_argc_run "$@"
|
||||||
|
|
||||||
|
# ARGC-BUILD }
|
||||||
Executable
+229
@@ -0,0 +1,229 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# @describe Apply a patch to a file at the specified path.
|
||||||
|
# This can be used to edit the file without having to rewrite the whole file.
|
||||||
|
|
||||||
|
# @option --path! The path of the file to apply the patch to
|
||||||
|
# @option --contents! The patch to apply to the file
|
||||||
|
|
||||||
|
# @env LLM_OUTPUT=/dev/stdout The output path
|
||||||
|
|
||||||
|
PROMPT_UTILS="${LLM_ROOT_DIR:-$(dirname "${BASH_SOURCE[0]}")/..}/utils/prompt-utils.sh"
|
||||||
|
# shellcheck disable=SC1090
|
||||||
|
source "$PROMPT_UTILS"
|
||||||
|
|
||||||
|
# shellcheck disable=SC2154
|
||||||
|
main() {
|
||||||
|
if [[ ! -f "$argc_path" ]]; then
|
||||||
|
error "Unable to find the specified file: $argc_path"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
new_contents="$(patch_file "$argc_path" <(printf "%s" "$argc_contents"))"
|
||||||
|
printf "%s" "$new_contents" | git diff --no-index "$argc_path" - || true
|
||||||
|
|
||||||
|
guard_operation "Apply changes?"
|
||||||
|
|
||||||
|
printf "%s" "$new_contents" > "$argc_path"
|
||||||
|
|
||||||
|
info "Applied the patch to: $argc_path" >> "$LLM_OUTPUT"
|
||||||
|
}
|
||||||
|
|
||||||
|
# ARGC-BUILD {
|
||||||
|
# This block was generated by argc (https://github.com/sigoden/argc).
|
||||||
|
# Modifying it manually is not recommended
|
||||||
|
|
||||||
|
_argc_run() {
|
||||||
|
if [[ "${1:-}" == "___internal___" ]]; then
|
||||||
|
_argc_die "error: unsupported ___internal___ command"
|
||||||
|
fi
|
||||||
|
if [[ "${OS:-}" == "Windows_NT" ]] && [[ -n "${MSYSTEM:-}" ]]; then
|
||||||
|
set -o igncr
|
||||||
|
fi
|
||||||
|
argc__args=("$(basename "$0" .sh)" "$@")
|
||||||
|
argc__positionals=()
|
||||||
|
_argc_index=1
|
||||||
|
_argc_len="${#argc__args[@]}"
|
||||||
|
_argc_tools=()
|
||||||
|
_argc_parse
|
||||||
|
if [ -n "${argc__fn:-}" ]; then
|
||||||
|
$argc__fn "${argc__positionals[@]}"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
_argc_usage() {
|
||||||
|
cat <<-'EOF'
|
||||||
|
Apply a patch to a file at the specified path.
|
||||||
|
This can be used to edit the file without having to rewrite the whole file.
|
||||||
|
|
||||||
|
USAGE: --path <PATH> --contents <CONTENTS>
|
||||||
|
|
||||||
|
OPTIONS:
|
||||||
|
--path <PATH> The path of the file to apply the patch to
|
||||||
|
--contents <CONTENTS> The patch to apply to the file
|
||||||
|
-h, --help Print help
|
||||||
|
-V, --version Print version
|
||||||
|
|
||||||
|
ENVIRONMENTS:
|
||||||
|
LLM_OUTPUT The output path [default: /dev/stdout]
|
||||||
|
EOF
|
||||||
|
exit
|
||||||
|
}
|
||||||
|
|
||||||
|
_argc_version() {
|
||||||
|
echo 0.0.0
|
||||||
|
exit
|
||||||
|
}
|
||||||
|
|
||||||
|
_argc_parse() {
|
||||||
|
local _argc_key _argc_action
|
||||||
|
local _argc_subcmds=""
|
||||||
|
while [[ $_argc_index -lt $_argc_len ]]; do
|
||||||
|
_argc_item="${argc__args[_argc_index]}"
|
||||||
|
_argc_key="${_argc_item%%=*}"
|
||||||
|
case "$_argc_key" in
|
||||||
|
--help | -help | -h)
|
||||||
|
_argc_usage
|
||||||
|
;;
|
||||||
|
--version | -version | -V)
|
||||||
|
_argc_version
|
||||||
|
;;
|
||||||
|
--)
|
||||||
|
_argc_dash="${#argc__positionals[@]}"
|
||||||
|
argc__positionals+=("${argc__args[@]:$((_argc_index + 1))}")
|
||||||
|
_argc_index=$_argc_len
|
||||||
|
break
|
||||||
|
;;
|
||||||
|
--path)
|
||||||
|
_argc_take_args "--path <PATH>" 1 1 "-" ""
|
||||||
|
_argc_index=$((_argc_index + _argc_take_args_len + 1))
|
||||||
|
if [[ -z "${argc_path:-}" ]]; then
|
||||||
|
argc_path="${_argc_take_args_values[0]:-}"
|
||||||
|
else
|
||||||
|
_argc_die "error: the argument \`--path\` cannot be used multiple times"
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
--contents)
|
||||||
|
_argc_take_args "--contents <CONTENTS>" 1 1 "-" ""
|
||||||
|
_argc_index=$((_argc_index + _argc_take_args_len + 1))
|
||||||
|
if [[ -z "${argc_contents:-}" ]]; then
|
||||||
|
argc_contents="${_argc_take_args_values[0]:-}"
|
||||||
|
else
|
||||||
|
_argc_die "error: the argument \`--contents\` cannot be used multiple times"
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
if _argc_maybe_flag_option "-" "$_argc_item"; then
|
||||||
|
_argc_die "error: unexpected argument \`$_argc_key\` found"
|
||||||
|
fi
|
||||||
|
argc__positionals+=("$_argc_item")
|
||||||
|
_argc_index=$((_argc_index + 1))
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
_argc_require_params "error: the following required arguments were not provided:" \
|
||||||
|
'argc_path:--path <PATH>' 'argc_contents:--contents <CONTENTS>'
|
||||||
|
if [[ -n "${_argc_action:-}" ]]; then
|
||||||
|
$_argc_action
|
||||||
|
else
|
||||||
|
argc__fn=main
|
||||||
|
if [[ "${argc__positionals[0]:-}" == "help" ]] && [[ "${#argc__positionals[@]}" -eq 1 ]]; then
|
||||||
|
_argc_usage
|
||||||
|
fi
|
||||||
|
if [[ -z "${LLM_OUTPUT:-}" ]]; then
|
||||||
|
export LLM_OUTPUT=/dev/stdout
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
_argc_take_args() {
|
||||||
|
_argc_take_args_values=()
|
||||||
|
_argc_take_args_len=0
|
||||||
|
local param="$1" min="$2" max="$3" signs="$4" delimiter="$5"
|
||||||
|
if [[ "$min" -eq 0 ]] && [[ "$max" -eq 0 ]]; then
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
local _argc_take_index=$((_argc_index + 1)) _argc_take_value
|
||||||
|
if [[ "$_argc_item" == *=* ]]; then
|
||||||
|
_argc_take_args_values=("${_argc_item##*=}")
|
||||||
|
else
|
||||||
|
while [[ $_argc_take_index -lt $_argc_len ]]; do
|
||||||
|
_argc_take_value="${argc__args[_argc_take_index]}"
|
||||||
|
if _argc_maybe_flag_option "$signs" "$_argc_take_value"; then
|
||||||
|
if [[ "${#_argc_take_value}" -gt 1 ]]; then
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
_argc_take_args_values+=("$_argc_take_value")
|
||||||
|
_argc_take_args_len=$((_argc_take_args_len + 1))
|
||||||
|
if [[ "$_argc_take_args_len" -ge "$max" ]]; then
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
_argc_take_index=$((_argc_take_index + 1))
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
if [[ "${#_argc_take_args_values[@]}" -lt "$min" ]]; then
|
||||||
|
_argc_die "error: incorrect number of values for \`$param\`"
|
||||||
|
fi
|
||||||
|
if [[ -n "$delimiter" ]] && [[ "${#_argc_take_args_values[@]}" -gt 0 ]]; then
|
||||||
|
local item values arr=()
|
||||||
|
for item in "${_argc_take_args_values[@]}"; do
|
||||||
|
IFS="$delimiter" read -r -a values <<<"$item"
|
||||||
|
arr+=("${values[@]}")
|
||||||
|
done
|
||||||
|
_argc_take_args_values=("${arr[@]}")
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
_argc_require_params() {
|
||||||
|
local message="$1" missed_envs="" item name render_name
|
||||||
|
for item in "${@:2}"; do
|
||||||
|
name="${item%%:*}"
|
||||||
|
render_name="${item##*:}"
|
||||||
|
if [[ -z "${!name:-}" ]]; then
|
||||||
|
missed_envs="$missed_envs"$'\n'" $render_name"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
if [[ -n "${missed_envs}" ]]; then
|
||||||
|
_argc_die "$message$missed_envs"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
_argc_maybe_flag_option() {
|
||||||
|
local signs="$1" arg="$2"
|
||||||
|
if [[ -z "$signs" ]]; then
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
local cond=false
|
||||||
|
if [[ "$signs" == *"+"* ]]; then
|
||||||
|
if [[ "$arg" =~ ^\+[^+].* ]]; then
|
||||||
|
cond=true
|
||||||
|
fi
|
||||||
|
elif [[ "$arg" == -* ]]; then
|
||||||
|
if (( ${#arg} < 3 )) || [[ ! "$arg" =~ ^---.* ]]; then
|
||||||
|
cond=true
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
if [[ "$cond" == "false" ]]; then
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
local value="${arg%%=*}"
|
||||||
|
if [[ "$value" =~ [[:space:]] ]]; then
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
_argc_die() {
|
||||||
|
if [[ $# -eq 0 ]]; then
|
||||||
|
cat
|
||||||
|
else
|
||||||
|
echo "$*" >&2
|
||||||
|
fi
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
_argc_run "$@"
|
||||||
|
|
||||||
|
# ARGC-BUILD }
|
||||||
Executable
+210
@@ -0,0 +1,210 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# @describe Remove the file or directory at the specified path.
|
||||||
|
|
||||||
|
# @option --path! The path of the file or directory to remove
|
||||||
|
|
||||||
|
# @env LLM_OUTPUT=/dev/stdout The output path
|
||||||
|
|
||||||
|
PROMPT_UTILS="${LLM_ROOT_DIR:-$(dirname "${BASH_SOURCE[0]}")/..}/utils/prompt-utils.sh"
|
||||||
|
# shellcheck disable=SC1090
|
||||||
|
source "$PROMPT_UTILS"
|
||||||
|
|
||||||
|
# shellcheck disable=SC2154
|
||||||
|
main() {
|
||||||
|
if [[ -f "$argc_path" ]]; then
|
||||||
|
guard_path "$argc_path" "Remove '$argc_path'?"
|
||||||
|
rm -rf "$argc_path"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Path removed: $argc_path" >> "$LLM_OUTPUT"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# ARGC-BUILD {
|
||||||
|
# This block was generated by argc (https://github.com/sigoden/argc).
|
||||||
|
# Modifying it manually is not recommended
|
||||||
|
|
||||||
|
_argc_run() {
|
||||||
|
if [[ "${1:-}" == "___internal___" ]]; then
|
||||||
|
_argc_die "error: unsupported ___internal___ command"
|
||||||
|
fi
|
||||||
|
if [[ "${OS:-}" == "Windows_NT" ]] && [[ -n "${MSYSTEM:-}" ]]; then
|
||||||
|
set -o igncr
|
||||||
|
fi
|
||||||
|
argc__args=("$(basename "$0" .sh)" "$@")
|
||||||
|
argc__positionals=()
|
||||||
|
_argc_index=1
|
||||||
|
_argc_len="${#argc__args[@]}"
|
||||||
|
_argc_tools=()
|
||||||
|
_argc_parse
|
||||||
|
if [ -n "${argc__fn:-}" ]; then
|
||||||
|
$argc__fn "${argc__positionals[@]}"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
_argc_usage() {
|
||||||
|
cat <<-'EOF'
|
||||||
|
Remove the file or directory at the specified path.
|
||||||
|
|
||||||
|
USAGE: --path <PATH>
|
||||||
|
|
||||||
|
OPTIONS:
|
||||||
|
--path <PATH> The path of the file or directory to remove
|
||||||
|
-h, --help Print help
|
||||||
|
-V, --version Print version
|
||||||
|
|
||||||
|
ENVIRONMENTS:
|
||||||
|
LLM_OUTPUT The output path [default: /dev/stdout]
|
||||||
|
EOF
|
||||||
|
exit
|
||||||
|
}
|
||||||
|
|
||||||
|
_argc_version() {
|
||||||
|
echo 0.0.0
|
||||||
|
exit
|
||||||
|
}
|
||||||
|
|
||||||
|
_argc_parse() {
|
||||||
|
local _argc_key _argc_action
|
||||||
|
local _argc_subcmds=""
|
||||||
|
while [[ $_argc_index -lt $_argc_len ]]; do
|
||||||
|
_argc_item="${argc__args[_argc_index]}"
|
||||||
|
_argc_key="${_argc_item%%=*}"
|
||||||
|
case "$_argc_key" in
|
||||||
|
--help | -help | -h)
|
||||||
|
_argc_usage
|
||||||
|
;;
|
||||||
|
--version | -version | -V)
|
||||||
|
_argc_version
|
||||||
|
;;
|
||||||
|
--)
|
||||||
|
_argc_dash="${#argc__positionals[@]}"
|
||||||
|
argc__positionals+=("${argc__args[@]:$((_argc_index + 1))}")
|
||||||
|
_argc_index=$_argc_len
|
||||||
|
break
|
||||||
|
;;
|
||||||
|
--path)
|
||||||
|
_argc_take_args "--path <PATH>" 1 1 "-" ""
|
||||||
|
_argc_index=$((_argc_index + _argc_take_args_len + 1))
|
||||||
|
if [[ -z "${argc_path:-}" ]]; then
|
||||||
|
argc_path="${_argc_take_args_values[0]:-}"
|
||||||
|
else
|
||||||
|
_argc_die "error: the argument \`--path\` cannot be used multiple times"
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
if _argc_maybe_flag_option "-" "$_argc_item"; then
|
||||||
|
_argc_die "error: unexpected argument \`$_argc_key\` found"
|
||||||
|
fi
|
||||||
|
argc__positionals+=("$_argc_item")
|
||||||
|
_argc_index=$((_argc_index + 1))
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
_argc_require_params "error: the following required arguments were not provided:" \
|
||||||
|
'argc_path:--path <PATH>'
|
||||||
|
if [[ -n "${_argc_action:-}" ]]; then
|
||||||
|
$_argc_action
|
||||||
|
else
|
||||||
|
argc__fn=main
|
||||||
|
if [[ "${argc__positionals[0]:-}" == "help" ]] && [[ "${#argc__positionals[@]}" -eq 1 ]]; then
|
||||||
|
_argc_usage
|
||||||
|
fi
|
||||||
|
if [[ -z "${LLM_OUTPUT:-}" ]]; then
|
||||||
|
export LLM_OUTPUT=/dev/stdout
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
_argc_take_args() {
|
||||||
|
_argc_take_args_values=()
|
||||||
|
_argc_take_args_len=0
|
||||||
|
local param="$1" min="$2" max="$3" signs="$4" delimiter="$5"
|
||||||
|
if [[ "$min" -eq 0 ]] && [[ "$max" -eq 0 ]]; then
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
local _argc_take_index=$((_argc_index + 1)) _argc_take_value
|
||||||
|
if [[ "$_argc_item" == *=* ]]; then
|
||||||
|
_argc_take_args_values=("${_argc_item##*=}")
|
||||||
|
else
|
||||||
|
while [[ $_argc_take_index -lt $_argc_len ]]; do
|
||||||
|
_argc_take_value="${argc__args[_argc_take_index]}"
|
||||||
|
if _argc_maybe_flag_option "$signs" "$_argc_take_value"; then
|
||||||
|
if [[ "${#_argc_take_value}" -gt 1 ]]; then
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
_argc_take_args_values+=("$_argc_take_value")
|
||||||
|
_argc_take_args_len=$((_argc_take_args_len + 1))
|
||||||
|
if [[ "$_argc_take_args_len" -ge "$max" ]]; then
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
_argc_take_index=$((_argc_take_index + 1))
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
if [[ "${#_argc_take_args_values[@]}" -lt "$min" ]]; then
|
||||||
|
_argc_die "error: incorrect number of values for \`$param\`"
|
||||||
|
fi
|
||||||
|
if [[ -n "$delimiter" ]] && [[ "${#_argc_take_args_values[@]}" -gt 0 ]]; then
|
||||||
|
local item values arr=()
|
||||||
|
for item in "${_argc_take_args_values[@]}"; do
|
||||||
|
IFS="$delimiter" read -r -a values <<<"$item"
|
||||||
|
arr+=("${values[@]}")
|
||||||
|
done
|
||||||
|
_argc_take_args_values=("${arr[@]}")
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
_argc_require_params() {
|
||||||
|
local message="$1" missed_envs="" item name render_name
|
||||||
|
for item in "${@:2}"; do
|
||||||
|
name="${item%%:*}"
|
||||||
|
render_name="${item##*:}"
|
||||||
|
if [[ -z "${!name:-}" ]]; then
|
||||||
|
missed_envs="$missed_envs"$'\n'" $render_name"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
if [[ -n "${missed_envs}" ]]; then
|
||||||
|
_argc_die "$message$missed_envs"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
_argc_maybe_flag_option() {
|
||||||
|
local signs="$1" arg="$2"
|
||||||
|
if [[ -z "$signs" ]]; then
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
local cond=false
|
||||||
|
if [[ "$signs" == *"+"* ]]; then
|
||||||
|
if [[ "$arg" =~ ^\+[^+].* ]]; then
|
||||||
|
cond=true
|
||||||
|
fi
|
||||||
|
elif [[ "$arg" == -* ]]; then
|
||||||
|
if (( ${#arg} < 3 )) || [[ ! "$arg" =~ ^---.* ]]; then
|
||||||
|
cond=true
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
if [[ "$cond" == "false" ]]; then
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
local value="${arg%%=*}"
|
||||||
|
if [[ "$value" =~ [[:space:]] ]]; then
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
_argc_die() {
|
||||||
|
if [[ $# -eq 0 ]]; then
|
||||||
|
cat
|
||||||
|
else
|
||||||
|
echo "$*" >&2
|
||||||
|
fi
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
_argc_run "$@"
|
||||||
|
|
||||||
|
# ARGC-BUILD }
|
||||||
Executable
+224
@@ -0,0 +1,224 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# @describe Write the full file contents to a file at the specified path.
|
||||||
|
|
||||||
|
# @option --path! The path of the file to write to
|
||||||
|
# @option --contents! The full contents to write to the file
|
||||||
|
|
||||||
|
# @env LLM_OUTPUT=/dev/stdout The output path
|
||||||
|
|
||||||
|
PROMPT_UTILS="${LLM_ROOT_DIR:-$(dirname "${BASH_SOURCE[0]}")/..}/utils/prompt-utils.sh"
|
||||||
|
# shellcheck disable=SC1090
|
||||||
|
source "$PROMPT_UTILS"
|
||||||
|
|
||||||
|
# shellcheck disable=SC2154
|
||||||
|
main() {
|
||||||
|
if [[ -f "$argc_path" ]]; then
|
||||||
|
printf "%s" "$argc_contents" | git diff --no-index "$argc_path" - || true
|
||||||
|
guard_operation "Apply changes?"
|
||||||
|
else
|
||||||
|
guard_path "$argc_path" "Write '$argc_path'?"
|
||||||
|
mkdir -p "$(dirname "$argc_path")"
|
||||||
|
fi
|
||||||
|
|
||||||
|
printf "%s" "$argc_contents" > "$argc_path"
|
||||||
|
echo "The File contents were written to: $argc_path" >> "$LLM_OUTPUT"
|
||||||
|
}
|
||||||
|
|
||||||
|
# ARGC-BUILD {
|
||||||
|
# This block was generated by argc (https://github.com/sigoden/argc).
|
||||||
|
# Modifying it manually is not recommended
|
||||||
|
|
||||||
|
_argc_run() {
|
||||||
|
if [[ "${1:-}" == "___internal___" ]]; then
|
||||||
|
_argc_die "error: unsupported ___internal___ command"
|
||||||
|
fi
|
||||||
|
if [[ "${OS:-}" == "Windows_NT" ]] && [[ -n "${MSYSTEM:-}" ]]; then
|
||||||
|
set -o igncr
|
||||||
|
fi
|
||||||
|
argc__args=("$(basename "$0" .sh)" "$@")
|
||||||
|
argc__positionals=()
|
||||||
|
_argc_index=1
|
||||||
|
_argc_len="${#argc__args[@]}"
|
||||||
|
_argc_tools=()
|
||||||
|
_argc_parse
|
||||||
|
if [ -n "${argc__fn:-}" ]; then
|
||||||
|
$argc__fn "${argc__positionals[@]}"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
_argc_usage() {
|
||||||
|
cat <<-'EOF'
|
||||||
|
Write the full file contents to a file at the specified path.
|
||||||
|
|
||||||
|
USAGE: --path <PATH> --contents <CONTENTS>
|
||||||
|
|
||||||
|
OPTIONS:
|
||||||
|
--path <PATH> The path of the file to write to
|
||||||
|
--contents <CONTENTS> The full contents to write to the file
|
||||||
|
-h, --help Print help
|
||||||
|
-V, --version Print version
|
||||||
|
|
||||||
|
ENVIRONMENTS:
|
||||||
|
LLM_OUTPUT The output path [default: /dev/stdout]
|
||||||
|
EOF
|
||||||
|
exit
|
||||||
|
}
|
||||||
|
|
||||||
|
_argc_version() {
|
||||||
|
echo 0.0.0
|
||||||
|
exit
|
||||||
|
}
|
||||||
|
|
||||||
|
_argc_parse() {
|
||||||
|
local _argc_key _argc_action
|
||||||
|
local _argc_subcmds=""
|
||||||
|
while [[ $_argc_index -lt $_argc_len ]]; do
|
||||||
|
_argc_item="${argc__args[_argc_index]}"
|
||||||
|
_argc_key="${_argc_item%%=*}"
|
||||||
|
case "$_argc_key" in
|
||||||
|
--help | -help | -h)
|
||||||
|
_argc_usage
|
||||||
|
;;
|
||||||
|
--version | -version | -V)
|
||||||
|
_argc_version
|
||||||
|
;;
|
||||||
|
--)
|
||||||
|
_argc_dash="${#argc__positionals[@]}"
|
||||||
|
argc__positionals+=("${argc__args[@]:$((_argc_index + 1))}")
|
||||||
|
_argc_index=$_argc_len
|
||||||
|
break
|
||||||
|
;;
|
||||||
|
--path)
|
||||||
|
_argc_take_args "--path <PATH>" 1 1 "-" ""
|
||||||
|
_argc_index=$((_argc_index + _argc_take_args_len + 1))
|
||||||
|
if [[ -z "${argc_path:-}" ]]; then
|
||||||
|
argc_path="${_argc_take_args_values[0]:-}"
|
||||||
|
else
|
||||||
|
_argc_die "error: the argument \`--path\` cannot be used multiple times"
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
--contents)
|
||||||
|
_argc_take_args "--contents <CONTENTS>" 1 1 "-" ""
|
||||||
|
_argc_index=$((_argc_index + _argc_take_args_len + 1))
|
||||||
|
if [[ -z "${argc_contents:-}" ]]; then
|
||||||
|
argc_contents="${_argc_take_args_values[0]:-}"
|
||||||
|
else
|
||||||
|
_argc_die "error: the argument \`--contents\` cannot be used multiple times"
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
if _argc_maybe_flag_option "-" "$_argc_item"; then
|
||||||
|
_argc_die "error: unexpected argument \`$_argc_key\` found"
|
||||||
|
fi
|
||||||
|
argc__positionals+=("$_argc_item")
|
||||||
|
_argc_index=$((_argc_index + 1))
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
_argc_require_params "error: the following required arguments were not provided:" \
|
||||||
|
'argc_path:--path <PATH>' 'argc_contents:--contents <CONTENTS>'
|
||||||
|
if [[ -n "${_argc_action:-}" ]]; then
|
||||||
|
$_argc_action
|
||||||
|
else
|
||||||
|
argc__fn=main
|
||||||
|
if [[ "${argc__positionals[0]:-}" == "help" ]] && [[ "${#argc__positionals[@]}" -eq 1 ]]; then
|
||||||
|
_argc_usage
|
||||||
|
fi
|
||||||
|
if [[ -z "${LLM_OUTPUT:-}" ]]; then
|
||||||
|
export LLM_OUTPUT=/dev/stdout
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
_argc_take_args() {
|
||||||
|
_argc_take_args_values=()
|
||||||
|
_argc_take_args_len=0
|
||||||
|
local param="$1" min="$2" max="$3" signs="$4" delimiter="$5"
|
||||||
|
if [[ "$min" -eq 0 ]] && [[ "$max" -eq 0 ]]; then
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
local _argc_take_index=$((_argc_index + 1)) _argc_take_value
|
||||||
|
if [[ "$_argc_item" == *=* ]]; then
|
||||||
|
_argc_take_args_values=("${_argc_item##*=}")
|
||||||
|
else
|
||||||
|
while [[ $_argc_take_index -lt $_argc_len ]]; do
|
||||||
|
_argc_take_value="${argc__args[_argc_take_index]}"
|
||||||
|
if _argc_maybe_flag_option "$signs" "$_argc_take_value"; then
|
||||||
|
if [[ "${#_argc_take_value}" -gt 1 ]]; then
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
_argc_take_args_values+=("$_argc_take_value")
|
||||||
|
_argc_take_args_len=$((_argc_take_args_len + 1))
|
||||||
|
if [[ "$_argc_take_args_len" -ge "$max" ]]; then
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
_argc_take_index=$((_argc_take_index + 1))
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
if [[ "${#_argc_take_args_values[@]}" -lt "$min" ]]; then
|
||||||
|
_argc_die "error: incorrect number of values for \`$param\`"
|
||||||
|
fi
|
||||||
|
if [[ -n "$delimiter" ]] && [[ "${#_argc_take_args_values[@]}" -gt 0 ]]; then
|
||||||
|
local item values arr=()
|
||||||
|
for item in "${_argc_take_args_values[@]}"; do
|
||||||
|
IFS="$delimiter" read -r -a values <<<"$item"
|
||||||
|
arr+=("${values[@]}")
|
||||||
|
done
|
||||||
|
_argc_take_args_values=("${arr[@]}")
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
_argc_require_params() {
|
||||||
|
local message="$1" missed_envs="" item name render_name
|
||||||
|
for item in "${@:2}"; do
|
||||||
|
name="${item%%:*}"
|
||||||
|
render_name="${item##*:}"
|
||||||
|
if [[ -z "${!name:-}" ]]; then
|
||||||
|
missed_envs="$missed_envs"$'\n'" $render_name"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
if [[ -n "${missed_envs}" ]]; then
|
||||||
|
_argc_die "$message$missed_envs"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
_argc_maybe_flag_option() {
|
||||||
|
local signs="$1" arg="$2"
|
||||||
|
if [[ -z "$signs" ]]; then
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
local cond=false
|
||||||
|
if [[ "$signs" == *"+"* ]]; then
|
||||||
|
if [[ "$arg" =~ ^\+[^+].* ]]; then
|
||||||
|
cond=true
|
||||||
|
fi
|
||||||
|
elif [[ "$arg" == -* ]]; then
|
||||||
|
if (( ${#arg} < 3 )) || [[ ! "$arg" =~ ^---.* ]]; then
|
||||||
|
cond=true
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
if [[ "$cond" == "false" ]]; then
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
local value="${arg%%=*}"
|
||||||
|
if [[ "$value" =~ [[:space:]] ]]; then
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
_argc_die() {
|
||||||
|
if [[ $# -eq 0 ]]; then
|
||||||
|
cat
|
||||||
|
else
|
||||||
|
echo "$*" >&2
|
||||||
|
fi
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
_argc_run "$@"
|
||||||
|
|
||||||
|
# ARGC-BUILD }
|
||||||
Executable
+10
@@ -0,0 +1,10 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# @describe Get the current time.
|
||||||
|
|
||||||
|
# @env LLM_OUTPUT=/dev/stdout The output path
|
||||||
|
|
||||||
|
main() {
|
||||||
|
date >> "$LLM_OUTPUT"
|
||||||
|
}
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
import os
|
||||||
|
from pathlib import Path
|
||||||
|
from typing import Optional
|
||||||
|
from urllib.parse import quote_plus
|
||||||
|
from urllib.request import urlopen
|
||||||
|
|
||||||
|
|
||||||
|
def run(
|
||||||
|
location: str,
|
||||||
|
llm_output: Optional[str] = None,
|
||||||
|
) -> str:
|
||||||
|
"""Get the current weather in a given location
|
||||||
|
|
||||||
|
Args:
|
||||||
|
location (str): The city and optionally the state or country (e.g., "London", "San Francisco, CA").
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
str: A single-line formatted weather string from wttr.in (``format=4`` with metric units).
|
||||||
|
"""
|
||||||
|
url = f"https://wttr.in/{quote_plus(location)}?format=4&M"
|
||||||
|
|
||||||
|
with urlopen(url, timeout=10) as resp:
|
||||||
|
weather = resp.read().decode("utf-8", errors="replace")
|
||||||
|
|
||||||
|
dest = llm_output if llm_output is not None else os.environ.get("LLM_OUTPUT", "/dev/stdout")
|
||||||
|
|
||||||
|
if dest not in {"-", "/dev/stdout"}:
|
||||||
|
path = Path(dest)
|
||||||
|
path.parent.mkdir(parents=True, exist_ok=True)
|
||||||
|
with path.open("a", encoding="utf-8") as fh:
|
||||||
|
fh.write(weather)
|
||||||
|
else:
|
||||||
|
pass
|
||||||
|
|
||||||
|
return weather
|
||||||
+199
@@ -0,0 +1,199 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# @describe Get the current weather in a given location.
|
||||||
|
# @option --location! The city and optionally the state or country, e.g., "London", "San Francisco, CA".
|
||||||
|
|
||||||
|
# @env LLM_OUTPUT=/dev/stdout The output path
|
||||||
|
|
||||||
|
main() {
|
||||||
|
curl -fsSL "https://wttr.in/$(echo "$argc_location" | sed 's/ /+/g')?format=4&M" \
|
||||||
|
>> "$LLM_OUTPUT"
|
||||||
|
}
|
||||||
|
|
||||||
|
# ARGC-BUILD {
|
||||||
|
# This block was generated by argc (https://github.com/sigoden/argc).
|
||||||
|
# Modifying it manually is not recommended
|
||||||
|
|
||||||
|
_argc_run() {
|
||||||
|
if [[ "${1:-}" == "___internal___" ]]; then
|
||||||
|
_argc_die "error: unsupported ___internal___ command"
|
||||||
|
fi
|
||||||
|
if [[ "${OS:-}" == "Windows_NT" ]] && [[ -n "${MSYSTEM:-}" ]]; then
|
||||||
|
set -o igncr
|
||||||
|
fi
|
||||||
|
argc__args=("$(basename "$0" .sh)" "$@")
|
||||||
|
argc__positionals=()
|
||||||
|
_argc_index=1
|
||||||
|
_argc_len="${#argc__args[@]}"
|
||||||
|
_argc_tools=()
|
||||||
|
_argc_parse
|
||||||
|
if [ -n "${argc__fn:-}" ]; then
|
||||||
|
$argc__fn "${argc__positionals[@]}"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
_argc_usage() {
|
||||||
|
cat <<-'EOF'
|
||||||
|
Get the current weather in a given location.
|
||||||
|
|
||||||
|
USAGE: --location <LOCATION>
|
||||||
|
|
||||||
|
OPTIONS:
|
||||||
|
--location <LOCATION> The city and optionally the state or country, e.g., "London", "San Francisco, CA".
|
||||||
|
-h, --help Print help
|
||||||
|
-V, --version Print version
|
||||||
|
|
||||||
|
ENVIRONMENTS:
|
||||||
|
LLM_OUTPUT The output path [default: /dev/stdout]
|
||||||
|
EOF
|
||||||
|
exit
|
||||||
|
}
|
||||||
|
|
||||||
|
_argc_version() {
|
||||||
|
echo 0.0.0
|
||||||
|
exit
|
||||||
|
}
|
||||||
|
|
||||||
|
_argc_parse() {
|
||||||
|
local _argc_key _argc_action
|
||||||
|
local _argc_subcmds=""
|
||||||
|
while [[ $_argc_index -lt $_argc_len ]]; do
|
||||||
|
_argc_item="${argc__args[_argc_index]}"
|
||||||
|
_argc_key="${_argc_item%%=*}"
|
||||||
|
case "$_argc_key" in
|
||||||
|
--help | -help | -h)
|
||||||
|
_argc_usage
|
||||||
|
;;
|
||||||
|
--version | -version | -V)
|
||||||
|
_argc_version
|
||||||
|
;;
|
||||||
|
--)
|
||||||
|
_argc_dash="${#argc__positionals[@]}"
|
||||||
|
argc__positionals+=("${argc__args[@]:$((_argc_index + 1))}")
|
||||||
|
_argc_index=$_argc_len
|
||||||
|
break
|
||||||
|
;;
|
||||||
|
--location)
|
||||||
|
_argc_take_args "--location <LOCATION>" 1 1 "-" ""
|
||||||
|
_argc_index=$((_argc_index + _argc_take_args_len + 1))
|
||||||
|
if [[ -z "${argc_location:-}" ]]; then
|
||||||
|
argc_location="${_argc_take_args_values[0]:-}"
|
||||||
|
else
|
||||||
|
_argc_die "error: the argument \`--location\` cannot be used multiple times"
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
if _argc_maybe_flag_option "-" "$_argc_item"; then
|
||||||
|
_argc_die "error: unexpected argument \`$_argc_key\` found"
|
||||||
|
fi
|
||||||
|
argc__positionals+=("$_argc_item")
|
||||||
|
_argc_index=$((_argc_index + 1))
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
_argc_require_params "error: the following required arguments were not provided:" \
|
||||||
|
'argc_location:--location <LOCATION>'
|
||||||
|
if [[ -n "${_argc_action:-}" ]]; then
|
||||||
|
$_argc_action
|
||||||
|
else
|
||||||
|
argc__fn=main
|
||||||
|
if [[ "${argc__positionals[0]:-}" == "help" ]] && [[ "${#argc__positionals[@]}" -eq 1 ]]; then
|
||||||
|
_argc_usage
|
||||||
|
fi
|
||||||
|
if [[ -z "${LLM_OUTPUT:-}" ]]; then
|
||||||
|
export LLM_OUTPUT=/dev/stdout
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
_argc_take_args() {
|
||||||
|
_argc_take_args_values=()
|
||||||
|
_argc_take_args_len=0
|
||||||
|
local param="$1" min="$2" max="$3" signs="$4" delimiter="$5"
|
||||||
|
if [[ "$min" -eq 0 ]] && [[ "$max" -eq 0 ]]; then
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
local _argc_take_index=$((_argc_index + 1)) _argc_take_value
|
||||||
|
if [[ "$_argc_item" == *=* ]]; then
|
||||||
|
_argc_take_args_values=("${_argc_item##*=}")
|
||||||
|
else
|
||||||
|
while [[ $_argc_take_index -lt $_argc_len ]]; do
|
||||||
|
_argc_take_value="${argc__args[_argc_take_index]}"
|
||||||
|
if _argc_maybe_flag_option "$signs" "$_argc_take_value"; then
|
||||||
|
if [[ "${#_argc_take_value}" -gt 1 ]]; then
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
_argc_take_args_values+=("$_argc_take_value")
|
||||||
|
_argc_take_args_len=$((_argc_take_args_len + 1))
|
||||||
|
if [[ "$_argc_take_args_len" -ge "$max" ]]; then
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
_argc_take_index=$((_argc_take_index + 1))
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
if [[ "${#_argc_take_args_values[@]}" -lt "$min" ]]; then
|
||||||
|
_argc_die "error: incorrect number of values for \`$param\`"
|
||||||
|
fi
|
||||||
|
if [[ -n "$delimiter" ]] && [[ "${#_argc_take_args_values[@]}" -gt 0 ]]; then
|
||||||
|
local item values arr=()
|
||||||
|
for item in "${_argc_take_args_values[@]}"; do
|
||||||
|
IFS="$delimiter" read -r -a values <<<"$item"
|
||||||
|
arr+=("${values[@]}")
|
||||||
|
done
|
||||||
|
_argc_take_args_values=("${arr[@]}")
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
_argc_require_params() {
|
||||||
|
local message="$1" missed_envs="" item name render_name
|
||||||
|
for item in "${@:2}"; do
|
||||||
|
name="${item%%:*}"
|
||||||
|
render_name="${item##*:}"
|
||||||
|
if [[ -z "${!name:-}" ]]; then
|
||||||
|
missed_envs="$missed_envs"$'\n'" $render_name"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
if [[ -n "${missed_envs}" ]]; then
|
||||||
|
_argc_die "$message$missed_envs"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
_argc_maybe_flag_option() {
|
||||||
|
local signs="$1" arg="$2"
|
||||||
|
if [[ -z "$signs" ]]; then
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
local cond=false
|
||||||
|
if [[ "$signs" == *"+"* ]]; then
|
||||||
|
if [[ "$arg" =~ ^\+[^+].* ]]; then
|
||||||
|
cond=true
|
||||||
|
fi
|
||||||
|
elif [[ "$arg" == -* ]]; then
|
||||||
|
if (( ${#arg} < 3 )) || [[ ! "$arg" =~ ^---.* ]]; then
|
||||||
|
cond=true
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
if [[ "$cond" == "false" ]]; then
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
local value="${arg%%=*}"
|
||||||
|
if [[ "$value" =~ [[:space:]] ]]; then
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
_argc_die() {
|
||||||
|
if [[ $# -eq 0 ]]; then
|
||||||
|
cat
|
||||||
|
else
|
||||||
|
echo "$*" >&2
|
||||||
|
fi
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
_argc_run "$@"
|
||||||
|
|
||||||
|
# ARGC-BUILD }
|
||||||
Executable
+198
@@ -0,0 +1,198 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# @meta require-tools jira
|
||||||
|
# @describe Query for jira issues using a Jira Query Language (JQL) query
|
||||||
|
# @option --jql-query! The Jira Query Language query to execute
|
||||||
|
# @env LLM_OUTPUT=/dev/stdout The output path
|
||||||
|
|
||||||
|
main() {
|
||||||
|
jira issue ls -q "$argc_jql_query" --plain >> "$LLM_OUTPUT"
|
||||||
|
}
|
||||||
|
|
||||||
|
# ARGC-BUILD {
|
||||||
|
# This block was generated by argc (https://github.com/sigoden/argc).
|
||||||
|
# Modifying it manually is not recommended
|
||||||
|
|
||||||
|
_argc_run() {
|
||||||
|
if [[ "${1:-}" == "___internal___" ]]; then
|
||||||
|
_argc_die "error: unsupported ___internal___ command"
|
||||||
|
fi
|
||||||
|
if [[ "${OS:-}" == "Windows_NT" ]] && [[ -n "${MSYSTEM:-}" ]]; then
|
||||||
|
set -o igncr
|
||||||
|
fi
|
||||||
|
argc__args=("$(basename "$0" .sh)" "$@")
|
||||||
|
argc__positionals=()
|
||||||
|
_argc_index=1
|
||||||
|
_argc_len="${#argc__args[@]}"
|
||||||
|
_argc_tools=()
|
||||||
|
_argc_parse
|
||||||
|
if [ -n "${argc__fn:-}" ]; then
|
||||||
|
$argc__fn "${argc__positionals[@]}"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
_argc_usage() {
|
||||||
|
cat <<-'EOF'
|
||||||
|
Query for jira issues using a Jira Query Language (JQL) query
|
||||||
|
|
||||||
|
USAGE: --jql-query <JQL-QUERY>
|
||||||
|
|
||||||
|
OPTIONS:
|
||||||
|
--jql-query <JQL-QUERY> The Jira Query Language query to execute
|
||||||
|
-h, --help Print help
|
||||||
|
-V, --version Print version
|
||||||
|
|
||||||
|
ENVIRONMENTS:
|
||||||
|
LLM_OUTPUT The output path [default: /dev/stdout]
|
||||||
|
EOF
|
||||||
|
exit
|
||||||
|
}
|
||||||
|
|
||||||
|
_argc_version() {
|
||||||
|
echo 0.0.0
|
||||||
|
exit
|
||||||
|
}
|
||||||
|
|
||||||
|
_argc_parse() {
|
||||||
|
local _argc_key _argc_action
|
||||||
|
local _argc_subcmds=""
|
||||||
|
while [[ $_argc_index -lt $_argc_len ]]; do
|
||||||
|
_argc_item="${argc__args[_argc_index]}"
|
||||||
|
_argc_key="${_argc_item%%=*}"
|
||||||
|
case "$_argc_key" in
|
||||||
|
--help | -help | -h)
|
||||||
|
_argc_usage
|
||||||
|
;;
|
||||||
|
--version | -version | -V)
|
||||||
|
_argc_version
|
||||||
|
;;
|
||||||
|
--)
|
||||||
|
_argc_dash="${#argc__positionals[@]}"
|
||||||
|
argc__positionals+=("${argc__args[@]:$((_argc_index + 1))}")
|
||||||
|
_argc_index=$_argc_len
|
||||||
|
break
|
||||||
|
;;
|
||||||
|
--jql-query)
|
||||||
|
_argc_take_args "--jql-query <JQL-QUERY>" 1 1 "-" ""
|
||||||
|
_argc_index=$((_argc_index + _argc_take_args_len + 1))
|
||||||
|
if [[ -z "${argc_jql_query:-}" ]]; then
|
||||||
|
argc_jql_query="${_argc_take_args_values[0]:-}"
|
||||||
|
else
|
||||||
|
_argc_die "error: the argument \`--jql-query\` cannot be used multiple times"
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
if _argc_maybe_flag_option "-" "$_argc_item"; then
|
||||||
|
_argc_die "error: unexpected argument \`$_argc_key\` found"
|
||||||
|
fi
|
||||||
|
argc__positionals+=("$_argc_item")
|
||||||
|
_argc_index=$((_argc_index + 1))
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
_argc_require_params "error: the following required arguments were not provided:" \
|
||||||
|
'argc_jql_query:--jql-query <JQL-QUERY>'
|
||||||
|
if [[ -n "${_argc_action:-}" ]]; then
|
||||||
|
$_argc_action
|
||||||
|
else
|
||||||
|
argc__fn=main
|
||||||
|
if [[ "${argc__positionals[0]:-}" == "help" ]] && [[ "${#argc__positionals[@]}" -eq 1 ]]; then
|
||||||
|
_argc_usage
|
||||||
|
fi
|
||||||
|
if [[ -z "${LLM_OUTPUT:-}" ]]; then
|
||||||
|
export LLM_OUTPUT=/dev/stdout
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
_argc_take_args() {
|
||||||
|
_argc_take_args_values=()
|
||||||
|
_argc_take_args_len=0
|
||||||
|
local param="$1" min="$2" max="$3" signs="$4" delimiter="$5"
|
||||||
|
if [[ "$min" -eq 0 ]] && [[ "$max" -eq 0 ]]; then
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
local _argc_take_index=$((_argc_index + 1)) _argc_take_value
|
||||||
|
if [[ "$_argc_item" == *=* ]]; then
|
||||||
|
_argc_take_args_values=("${_argc_item##*=}")
|
||||||
|
else
|
||||||
|
while [[ $_argc_take_index -lt $_argc_len ]]; do
|
||||||
|
_argc_take_value="${argc__args[_argc_take_index]}"
|
||||||
|
if _argc_maybe_flag_option "$signs" "$_argc_take_value"; then
|
||||||
|
if [[ "${#_argc_take_value}" -gt 1 ]]; then
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
_argc_take_args_values+=("$_argc_take_value")
|
||||||
|
_argc_take_args_len=$((_argc_take_args_len + 1))
|
||||||
|
if [[ "$_argc_take_args_len" -ge "$max" ]]; then
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
_argc_take_index=$((_argc_take_index + 1))
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
if [[ "${#_argc_take_args_values[@]}" -lt "$min" ]]; then
|
||||||
|
_argc_die "error: incorrect number of values for \`$param\`"
|
||||||
|
fi
|
||||||
|
if [[ -n "$delimiter" ]] && [[ "${#_argc_take_args_values[@]}" -gt 0 ]]; then
|
||||||
|
local item values arr=()
|
||||||
|
for item in "${_argc_take_args_values[@]}"; do
|
||||||
|
IFS="$delimiter" read -r -a values <<<"$item"
|
||||||
|
arr+=("${values[@]}")
|
||||||
|
done
|
||||||
|
_argc_take_args_values=("${arr[@]}")
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
_argc_require_params() {
|
||||||
|
local message="$1" missed_envs="" item name render_name
|
||||||
|
for item in "${@:2}"; do
|
||||||
|
name="${item%%:*}"
|
||||||
|
render_name="${item##*:}"
|
||||||
|
if [[ -z "${!name:-}" ]]; then
|
||||||
|
missed_envs="$missed_envs"$'\n'" $render_name"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
if [[ -n "${missed_envs}" ]]; then
|
||||||
|
_argc_die "$message$missed_envs"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
_argc_maybe_flag_option() {
|
||||||
|
local signs="$1" arg="$2"
|
||||||
|
if [[ -z "$signs" ]]; then
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
local cond=false
|
||||||
|
if [[ "$signs" == *"+"* ]]; then
|
||||||
|
if [[ "$arg" =~ ^\+[^+].* ]]; then
|
||||||
|
cond=true
|
||||||
|
fi
|
||||||
|
elif [[ "$arg" == -* ]]; then
|
||||||
|
if (( ${#arg} < 3 )) || [[ ! "$arg" =~ ^---.* ]]; then
|
||||||
|
cond=true
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
if [[ "$cond" == "false" ]]; then
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
local value="${arg%%=*}"
|
||||||
|
if [[ "$value" =~ [[:space:]] ]]; then
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
_argc_die() {
|
||||||
|
if [[ $# -eq 0 ]]; then
|
||||||
|
cat
|
||||||
|
else
|
||||||
|
echo "$*" >&2
|
||||||
|
fi
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
_argc_run "$@"
|
||||||
|
|
||||||
|
# ARGC-BUILD }
|
||||||
Executable
+16
@@ -0,0 +1,16 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# @describe Search arXiv using the given search query and return the top papers.
|
||||||
|
|
||||||
|
# @option --query! The search query.
|
||||||
|
|
||||||
|
# @env ARXIV_MAX_RESULTS=3 The max results to return.
|
||||||
|
# @env LLM_OUTPUT=/dev/stdout The output path
|
||||||
|
|
||||||
|
main() {
|
||||||
|
# shellcheck disable=SC2154
|
||||||
|
encoded_query="$(jq -nr --arg q "$argc_query" '$q|@uri')"
|
||||||
|
url="http://export.arxiv.org/api/query?search_query=all:$encoded_query&max_results=$ARXIV_MAX_RESULTS"
|
||||||
|
curl -fsSL "$url" >> "$LLM_OUTPUT"
|
||||||
|
}
|
||||||
Executable
+29
@@ -0,0 +1,29 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# @describe Search Wikipedia using the given search query.
|
||||||
|
# Use it to get detailed information about a public figure, interpretation of a complex scientific concept or in-depth connectivity of a significant historical event, etc.
|
||||||
|
|
||||||
|
# @option --query! The search query.
|
||||||
|
|
||||||
|
# @env LLM_OUTPUT=/dev/stdout The output path
|
||||||
|
|
||||||
|
# shellcheck disable=SC2154
|
||||||
|
main() {
|
||||||
|
encoded_query="$(jq -nr --arg q "$argc_query" '$q|@uri')"
|
||||||
|
base_url="https://en.wikipedia.org/w/api.php"
|
||||||
|
url="$base_url?action=query&list=search&srprop=&srlimit=1&limit=1&srsearch=$encoded_query&srinfo=suggestion&format=json"
|
||||||
|
json="$(curl -fsSL "$url")"
|
||||||
|
# suggestion="$(echo "$json" | jq -r '.query.searchinfo.suggestion // empty')"
|
||||||
|
title="$(echo "$json" | jq -r '.query.search[0].title // empty')"
|
||||||
|
pageid="$(echo "$json" | jq -r '.query.search[0].pageid // empty')"
|
||||||
|
|
||||||
|
if [[ -z "$title" || -z "$pageid" ]]; then
|
||||||
|
echo "error: no results for '$argc_query'" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
title="$(echo "$title" | tr ' ' '_')"
|
||||||
|
url="$base_url?action=query&prop=extracts&explaintext=&titles=$title&exintro=&format=json"
|
||||||
|
curl -fsSL "$url" | jq -r '.query.pages["'"$pageid"'"].extract' >> "$LLM_OUTPUT"
|
||||||
|
}
|
||||||
+19
@@ -0,0 +1,19 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# @describe Get an answer to a question using Wolfram Alpha. The input query should be in English.
|
||||||
|
# Use it to answer user questions that require computation, detailed facts, data analysis, or complex queries.
|
||||||
|
|
||||||
|
# @option --query! The search/computation query to pass to Wolfram Alpha
|
||||||
|
|
||||||
|
# @env WOLFRAM_API_ID! Your Wolfram Alpha API ID
|
||||||
|
# @env LLM_OUTPUT=/dev/stdout The output path
|
||||||
|
|
||||||
|
# shellcheck disable=SC2154
|
||||||
|
main() {
|
||||||
|
encoded_query="$(jq -nr --arg q "$argc_query" '$q|@uri')"
|
||||||
|
url="https://api.wolframalpha.com/v2/query?appid=${WOLFRAM_API_ID}&input=$encoded_query&output=json&format=plaintext"
|
||||||
|
|
||||||
|
curl -fsSL "$url" | jq '[.queryresult | .pods[] | {title:.title, values:[.subpods[].plaintext | select(. != "")]}]' \
|
||||||
|
>> "$LLM_OUTPUT"
|
||||||
|
}
|
||||||
Executable
+30
@@ -0,0 +1,30 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# @describe Send an email.
|
||||||
|
# @option --recipient! The recipient of the email.
|
||||||
|
# @option --subject! The subject of the email.
|
||||||
|
# @option --body! The body of the email.
|
||||||
|
|
||||||
|
# @env EMAIL_SMTP_ADDR! The SMTP Address, e.g. smtps://smtp.gmail.com:465
|
||||||
|
# @env EMAIL_SMTP_USER! The SMTP User, e.g. alice@gmail.com
|
||||||
|
# @env EMAIL_SMTP_PASS! The SMTP Password
|
||||||
|
# @env EMAIL_SENDER_NAME The sender's name
|
||||||
|
# @env LLM_OUTPUT=/dev/stdout The output path
|
||||||
|
|
||||||
|
# shellcheck disable=SC2154
|
||||||
|
main() {
|
||||||
|
sender_name="${EMAIL_SENDER_NAME:-$(echo "$EMAIL_SMTP_USER" | awk -F'@' '{print $1}')}"
|
||||||
|
printf "%s\n" "From: $sender_name <$EMAIL_SMTP_USER>
|
||||||
|
To: $argc_recipient
|
||||||
|
Subject: $argc_subject
|
||||||
|
|
||||||
|
$argc_body" | \
|
||||||
|
curl -fsS --ssl-reqd \
|
||||||
|
--url "$EMAIL_SMTP_ADDR" \
|
||||||
|
--user "$EMAIL_SMTP_USER:$EMAIL_SMTP_PASS" \
|
||||||
|
--mail-from "$EMAIL_SMTP_USER" \
|
||||||
|
--mail-rcpt "$argc_recipient" \
|
||||||
|
--upload-file -
|
||||||
|
echo "Email sent successfully" >> "$LLM_OUTPUT"
|
||||||
|
}
|
||||||
Executable
+50
@@ -0,0 +1,50 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# @describe Send SMS or Twilio Messaging Channels messages using the Twilio API.
|
||||||
|
# @option --to-number! The recipient's phone number. Prefix it with 'whatsapp:' for WhatsApp messages, e.g. whatsapp:+1234567890
|
||||||
|
# @option --message! The content of the message to be sent
|
||||||
|
|
||||||
|
# @env TWILIO_ACCOUNT_SID! The twilio account sid
|
||||||
|
# @env TWILIO_AUTH_TOKEN! The twilio auth token
|
||||||
|
# @env TWILIO_FROM_NUMBER! The twilio from number
|
||||||
|
# @env LLM_OUTPUT=/dev/stdout The output path
|
||||||
|
|
||||||
|
# shellcheck disable=SC2154
|
||||||
|
main() {
|
||||||
|
from_number="$TWILIO_FROM_NUMBER"
|
||||||
|
to_number="$argc_to_number"
|
||||||
|
|
||||||
|
if [[ "$to_number" == 'whatsapp:'* ]]; then
|
||||||
|
from_number="whatsapp:$from_number"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "$to_number" != 'whatsapp:'* && "$to_number" != '+'* ]]; then
|
||||||
|
to_number="+$to_number"
|
||||||
|
fi
|
||||||
|
|
||||||
|
res="$(curl -s -X POST "https://api.twilio.com/2010-04-01/Accounts/$TWILIO_ACCOUNT_SID/Messages.json" \
|
||||||
|
-u "$TWILIO_ACCOUNT_SID:$TWILIO_AUTH_TOKEN" \
|
||||||
|
-w "\n%{http_code}" \
|
||||||
|
--data-urlencode "From=$from_number" \
|
||||||
|
--data-urlencode "To=$to_number" \
|
||||||
|
--data-urlencode "Body=$argc_message")"
|
||||||
|
status="$(echo "$res" | tail -n 1)"
|
||||||
|
body="$(echo "$res" | head -n -1)"
|
||||||
|
|
||||||
|
if [[ "$status" -ge 200 && "$status" -lt 300 ]]; then
|
||||||
|
if [[ "$(echo "$body" | jq -r 'has("sid")')" == "true" ]]; then
|
||||||
|
echo "Message sent successfully" >> "$LLM_OUTPUT"
|
||||||
|
else
|
||||||
|
_die "error: $body"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
_die "error: $body"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
_die() {
|
||||||
|
echo "$*" >&2
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
Executable
+254
@@ -0,0 +1,254 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# @describe Perform a web search to get up-to-date information or additional context.
|
||||||
|
# Use this when you need current information or feel a search could provide a better answer.
|
||||||
|
|
||||||
|
# @option --query! The search query.
|
||||||
|
|
||||||
|
# @meta require-tools loki
|
||||||
|
|
||||||
|
# @env WEB_SEARCH_MODEL=gemini:gemini-2.5-flash The model for web-searching.
|
||||||
|
#
|
||||||
|
# supported loki models:
|
||||||
|
# - gemini:gemini-2.0-*
|
||||||
|
# - vertexai:gemini-*
|
||||||
|
# - perplexity:*
|
||||||
|
# - ernie:*
|
||||||
|
# @env LLM_OUTPUT=/dev/stdout The output path
|
||||||
|
|
||||||
|
# shellcheck disable=SC2154
|
||||||
|
main() {
|
||||||
|
client="${WEB_SEARCH_MODEL%%:*}"
|
||||||
|
|
||||||
|
if [[ "$client" == "gemini" ]]; then
|
||||||
|
export LOKI_PATCH_GEMINI_CHAT_COMPLETIONS='{".*":{"body":{"tools":[{"google_search":{}}]}}}'
|
||||||
|
elif [[ "$client" == "vertexai" ]]; then
|
||||||
|
export LOKI_PATCH_VERTEXAI_CHAT_COMPLETIONS='{
|
||||||
|
"gemini-1.5-.*":{"body":{"tools":[{"googleSearchRetrieval":{}}]}},
|
||||||
|
"gemini-2.0-.*":{"body":{"tools":[{"google_search":{}}]}}
|
||||||
|
}'
|
||||||
|
elif [[ "$client" == "ernie" ]]; then
|
||||||
|
export LOKI_PATCH_ERNIE_CHAT_COMPLETIONS='{".*":{"body":{"web_search":{"enable":true}}}}'
|
||||||
|
fi
|
||||||
|
|
||||||
|
loki -m "$WEB_SEARCH_MODEL" "$argc_query" >> "$LLM_OUTPUT"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# ARGC-BUILD {
|
||||||
|
# This block was generated by argc (https://github.com/sigoden/argc).
|
||||||
|
# Modifying it manually is not recommended
|
||||||
|
|
||||||
|
_argc_run() {
|
||||||
|
if [[ "${1:-}" == "___internal___" ]]; then
|
||||||
|
_argc_die "error: unsupported ___internal___ command"
|
||||||
|
fi
|
||||||
|
if [[ "${OS:-}" == "Windows_NT" ]] && [[ -n "${MSYSTEM:-}" ]]; then
|
||||||
|
set -o igncr
|
||||||
|
fi
|
||||||
|
argc__args=("$(basename "$0" .sh)" "$@")
|
||||||
|
argc__positionals=()
|
||||||
|
_argc_index=1
|
||||||
|
_argc_len="${#argc__args[@]}"
|
||||||
|
_argc_tools=()
|
||||||
|
_argc_parse
|
||||||
|
_argc_require_tools "${_argc_tools[@]}"
|
||||||
|
if [ -n "${argc__fn:-}" ]; then
|
||||||
|
$argc__fn "${argc__positionals[@]}"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
_argc_usage() {
|
||||||
|
cat <<-'EOF'
|
||||||
|
Perform a web search to get up-to-date information or additional context.
|
||||||
|
Use this when you need current information or feel a search could provide a better answer.
|
||||||
|
|
||||||
|
USAGE: --query <QUERY>
|
||||||
|
|
||||||
|
OPTIONS:
|
||||||
|
--query <QUERY> The query to search for.
|
||||||
|
-h, --help Print help
|
||||||
|
-V, --version Print version
|
||||||
|
|
||||||
|
ENVIRONMENTS:
|
||||||
|
WEB_SEARCH_MODEL
|
||||||
|
The model for web-searching.
|
||||||
|
|
||||||
|
supported loki models:
|
||||||
|
- gemini:gemini-2.0-*
|
||||||
|
- vertexai:gemini-*
|
||||||
|
- perplexity:*
|
||||||
|
- ernie:*
|
||||||
|
[default: gemini:gemini-2.5-flash]
|
||||||
|
|
||||||
|
LLM_OUTPUT
|
||||||
|
The output path [default: /dev/stdout]
|
||||||
|
EOF
|
||||||
|
exit
|
||||||
|
}
|
||||||
|
|
||||||
|
_argc_version() {
|
||||||
|
echo 0.0.0
|
||||||
|
exit
|
||||||
|
}
|
||||||
|
|
||||||
|
_argc_parse() {
|
||||||
|
local _argc_key _argc_action
|
||||||
|
local _argc_subcmds=""
|
||||||
|
while [[ $_argc_index -lt $_argc_len ]]; do
|
||||||
|
_argc_item="${argc__args[_argc_index]}"
|
||||||
|
_argc_key="${_argc_item%%=*}"
|
||||||
|
case "$_argc_key" in
|
||||||
|
--help | -help | -h)
|
||||||
|
_argc_usage
|
||||||
|
;;
|
||||||
|
--version | -version | -V)
|
||||||
|
_argc_version
|
||||||
|
;;
|
||||||
|
--)
|
||||||
|
_argc_dash="${#argc__positionals[@]}"
|
||||||
|
argc__positionals+=("${argc__args[@]:$((_argc_index + 1))}")
|
||||||
|
_argc_index=$_argc_len
|
||||||
|
break
|
||||||
|
;;
|
||||||
|
--query)
|
||||||
|
_argc_take_args "--query <QUERY>" 1 1 "-" ""
|
||||||
|
_argc_index=$((_argc_index + _argc_take_args_len + 1))
|
||||||
|
if [[ -z "${argc_query:-}" ]]; then
|
||||||
|
argc_query="${_argc_take_args_values[0]:-}"
|
||||||
|
else
|
||||||
|
_argc_die "error: the argument \`--query\` cannot be used multiple times"
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
if _argc_maybe_flag_option "-" "$_argc_item"; then
|
||||||
|
_argc_die "error: unexpected argument \`$_argc_key\` found"
|
||||||
|
fi
|
||||||
|
argc__positionals+=("$_argc_item")
|
||||||
|
_argc_index=$((_argc_index + 1))
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
_argc_require_params "error: the following required arguments were not provided:" \
|
||||||
|
'argc_query:--query <QUERY>'
|
||||||
|
_argc_tools=(loki)
|
||||||
|
if [[ -n "${_argc_action:-}" ]]; then
|
||||||
|
$_argc_action
|
||||||
|
else
|
||||||
|
argc__fn=main
|
||||||
|
if [[ "${argc__positionals[0]:-}" == "help" ]] && [[ "${#argc__positionals[@]}" -eq 1 ]]; then
|
||||||
|
_argc_usage
|
||||||
|
fi
|
||||||
|
if [[ -z "${WEB_SEARCH_MODEL:-}" ]]; then
|
||||||
|
export WEB_SEARCH_MODEL=gemini:gemini-2.5-flash
|
||||||
|
fi
|
||||||
|
if [[ -z "${LLM_OUTPUT:-}" ]]; then
|
||||||
|
export LLM_OUTPUT=/dev/stdout
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
_argc_take_args() {
|
||||||
|
_argc_take_args_values=()
|
||||||
|
_argc_take_args_len=0
|
||||||
|
local param="$1" min="$2" max="$3" signs="$4" delimiter="$5"
|
||||||
|
if [[ "$min" -eq 0 ]] && [[ "$max" -eq 0 ]]; then
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
local _argc_take_index=$((_argc_index + 1)) _argc_take_value
|
||||||
|
if [[ "$_argc_item" == *=* ]]; then
|
||||||
|
_argc_take_args_values=("${_argc_item##*=}")
|
||||||
|
else
|
||||||
|
while [[ $_argc_take_index -lt $_argc_len ]]; do
|
||||||
|
_argc_take_value="${argc__args[_argc_take_index]}"
|
||||||
|
if _argc_maybe_flag_option "$signs" "$_argc_take_value"; then
|
||||||
|
if [[ "${#_argc_take_value}" -gt 1 ]]; then
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
_argc_take_args_values+=("$_argc_take_value")
|
||||||
|
_argc_take_args_len=$((_argc_take_args_len + 1))
|
||||||
|
if [[ "$_argc_take_args_len" -ge "$max" ]]; then
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
_argc_take_index=$((_argc_take_index + 1))
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
if [[ "${#_argc_take_args_values[@]}" -lt "$min" ]]; then
|
||||||
|
_argc_die "error: incorrect number of values for \`$param\`"
|
||||||
|
fi
|
||||||
|
if [[ -n "$delimiter" ]] && [[ "${#_argc_take_args_values[@]}" -gt 0 ]]; then
|
||||||
|
local item values arr=()
|
||||||
|
for item in "${_argc_take_args_values[@]}"; do
|
||||||
|
IFS="$delimiter" read -r -a values <<<"$item"
|
||||||
|
arr+=("${values[@]}")
|
||||||
|
done
|
||||||
|
_argc_take_args_values=("${arr[@]}")
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
_argc_require_params() {
|
||||||
|
local message="$1" missed_envs="" item name render_name
|
||||||
|
for item in "${@:2}"; do
|
||||||
|
name="${item%%:*}"
|
||||||
|
render_name="${item##*:}"
|
||||||
|
if [[ -z "${!name:-}" ]]; then
|
||||||
|
missed_envs="$missed_envs"$'\n'" $render_name"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
if [[ -n "${missed_envs}" ]]; then
|
||||||
|
_argc_die "$message$missed_envs"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
_argc_maybe_flag_option() {
|
||||||
|
local signs="$1" arg="$2"
|
||||||
|
if [[ -z "$signs" ]]; then
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
local cond=false
|
||||||
|
if [[ "$signs" == *"+"* ]]; then
|
||||||
|
if [[ "$arg" =~ ^\+[^+].* ]]; then
|
||||||
|
cond=true
|
||||||
|
fi
|
||||||
|
elif [[ "$arg" == -* ]]; then
|
||||||
|
if (( ${#arg} < 3 )) || [[ ! "$arg" =~ ^---.* ]]; then
|
||||||
|
cond=true
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
if [[ "$cond" == "false" ]]; then
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
local value="${arg%%=*}"
|
||||||
|
if [[ "$value" =~ [[:space:]] ]]; then
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
_argc_require_tools() {
|
||||||
|
local tool missing_tools=()
|
||||||
|
for tool in "$@"; do
|
||||||
|
if ! command -v "$tool" >/dev/null 2>&1; then
|
||||||
|
missing_tools+=("$tool")
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
if [[ "${#missing_tools[@]}" -gt 0 ]]; then
|
||||||
|
echo "error: missing tools: ${missing_tools[*]}" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
_argc_die() {
|
||||||
|
if [[ $# -eq 0 ]]; then
|
||||||
|
cat
|
||||||
|
else
|
||||||
|
echo "$*" >&2
|
||||||
|
fi
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
_argc_run "$@"
|
||||||
|
|
||||||
|
# ARGC-BUILD }
|
||||||
+32
@@ -0,0 +1,32 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# @describe Perform a web search using the Perplexity API to get up-to-date information or additional context.
|
||||||
|
# Use this when you need current information or feel a search could provide a better answer.
|
||||||
|
|
||||||
|
# @option --query! The search query.
|
||||||
|
|
||||||
|
# @env PERPLEXITY_API_KEY! Your Perplexity API key
|
||||||
|
# @env PERPLEXITY_WEB_SEARCH_MODEL=llama-3.1-sonar-small-128k-online The LLM model to use for the search
|
||||||
|
# @env LLM_OUTPUT=/dev/stdout The output path
|
||||||
|
|
||||||
|
# shellcheck disable=SC2154
|
||||||
|
main() {
|
||||||
|
curl -fsS -X POST https://api.perplexity.ai/chat/completions \
|
||||||
|
-H "authorization: Bearer $PERPLEXITY_API_KEY" \
|
||||||
|
-H "accept: application/json" \
|
||||||
|
-H "content-type: application/json" \
|
||||||
|
--data '
|
||||||
|
{
|
||||||
|
"model": "'"$PERPLEXITY_WEB_SEARCH_MODEL"'",
|
||||||
|
"messages": [
|
||||||
|
{
|
||||||
|
"role": "user",
|
||||||
|
"content": "'"$argc_query"'"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
' | \
|
||||||
|
jq -r '.choices[0].message.content' \
|
||||||
|
>> "$LLM_OUTPUT"
|
||||||
|
}
|
||||||
Executable
+24
@@ -0,0 +1,24 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# @describe Perform a web search using the Tavily API to get up-to-date information or additional context.
|
||||||
|
# Use this when you need current information or feel a search could provide a better answer.
|
||||||
|
|
||||||
|
# @option --query! The search query.
|
||||||
|
|
||||||
|
# @env TAVILY_API_KEY! Your Tavile API key
|
||||||
|
# @env LLM_OUTPUT=/dev/stdout The output path The output path
|
||||||
|
|
||||||
|
# shellcheck disable=SC2154
|
||||||
|
main() {
|
||||||
|
curl -fsSL -X POST https://api.tavily.com/search \
|
||||||
|
-H "content-type: application/json" \
|
||||||
|
-d '
|
||||||
|
{
|
||||||
|
"api_key": "'"$TAVILY_API_KEY"'",
|
||||||
|
"query": "'"$argc_query"'",
|
||||||
|
"include_answer": true
|
||||||
|
}' | \
|
||||||
|
jq -r '.answer' >> "$LLM_OUTPUT"
|
||||||
|
}
|
||||||
|
|
||||||
Executable
+716
@@ -0,0 +1,716 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
# Bash helper utilities for prompting users.
|
||||||
|
# This is a modified version of the excellent Bash TUI toolkit
|
||||||
|
# (https://github.com/timo-reymann/bash-tui-toolkit)
|
||||||
|
#
|
||||||
|
# It includes the following functions for you to use in your
|
||||||
|
# bash tool commands:
|
||||||
|
#
|
||||||
|
# - password Password prompt
|
||||||
|
# - checked Checkbox
|
||||||
|
# - text Text input with validation
|
||||||
|
# - list Select an option from a given list
|
||||||
|
# - range Prompt the user for a value within a range
|
||||||
|
# - confirm Confirmation prompt
|
||||||
|
# - editor Open the user's preferred editor for input
|
||||||
|
# - detect_os Detect the current OS
|
||||||
|
# - get_opener Get the file opener for the current OS
|
||||||
|
# - open_link Open the given link in the default browser
|
||||||
|
# See https://github.com/timo-reymann/bash-tui-toolkit/blob/main/test.sh
|
||||||
|
# for examples on how to use these commands
|
||||||
|
#
|
||||||
|
# - guard_operation Prompt for permission to run an operation
|
||||||
|
# - guard_path Prompt for permission to perform path operations
|
||||||
|
# - patch_file Patch a file
|
||||||
|
# - error Log an error
|
||||||
|
# - warn Log a warning
|
||||||
|
# - info Log info
|
||||||
|
# - debug Log a debug message
|
||||||
|
# - trace Log a trace message
|
||||||
|
# - red Output given text in red
|
||||||
|
# - green Output given text in green
|
||||||
|
# - gold Output given text in gold
|
||||||
|
# - blue Output given text in blue
|
||||||
|
# - magenta Output given text in magenta
|
||||||
|
# - cyan Output given text in cyan
|
||||||
|
# - white Output given text in white
|
||||||
|
|
||||||
|
# shellcheck disable=SC2034
|
||||||
|
red=$(tput setaf 1)
|
||||||
|
green=$(tput setaf 2)
|
||||||
|
gold=$(tput setaf 3)
|
||||||
|
blue=$(tput setaf 4)
|
||||||
|
magenta=$(tput setaf 5)
|
||||||
|
cyan=$(tput setaf 6)
|
||||||
|
white=$(tput setaf 7)
|
||||||
|
|
||||||
|
default=$(tput sgr0)
|
||||||
|
gray=$(tput setaf 243)
|
||||||
|
|
||||||
|
bold=$(tput bold)
|
||||||
|
underlined=$(tput smul)
|
||||||
|
|
||||||
|
error() {
|
||||||
|
echo -e "${red}${bold}ERROR:${default}${red} $1${default}"
|
||||||
|
}
|
||||||
|
|
||||||
|
warn() {
|
||||||
|
echo -e "${gold}${bold}WARN:${default}${gold} $1${default}"
|
||||||
|
}
|
||||||
|
|
||||||
|
info() {
|
||||||
|
echo -e "${cyan}${bold}INFO:${default}${cyan} $1${default}"
|
||||||
|
}
|
||||||
|
|
||||||
|
debug() {
|
||||||
|
echo -e "${blue}${bold}DEBUG:${default}${blue} $1${default}"
|
||||||
|
}
|
||||||
|
|
||||||
|
trace() {
|
||||||
|
echo -e "${gray}${bold}TRACE:${default}${gray} $1${default}"
|
||||||
|
}
|
||||||
|
|
||||||
|
success() {
|
||||||
|
echo -e "${green}${bold}SUCCESS:${default}${green} $1${default}"
|
||||||
|
}
|
||||||
|
|
||||||
|
red() {
|
||||||
|
echo -e "${red}$1${default}"
|
||||||
|
}
|
||||||
|
|
||||||
|
green() {
|
||||||
|
echo -e "${green}$1${default}"
|
||||||
|
}
|
||||||
|
|
||||||
|
gold() {
|
||||||
|
echo -e "${gold}$1${default}"
|
||||||
|
}
|
||||||
|
|
||||||
|
blue() {
|
||||||
|
echo -e "${blue}$1${default}"
|
||||||
|
}
|
||||||
|
|
||||||
|
magenta() {
|
||||||
|
echo -e "${magenta}$1${default}"
|
||||||
|
}
|
||||||
|
|
||||||
|
cyan() {
|
||||||
|
echo -e "${cyan}$1${default}"
|
||||||
|
}
|
||||||
|
|
||||||
|
white() {
|
||||||
|
echo -e "${white}$1${default}"
|
||||||
|
}
|
||||||
|
|
||||||
|
_read_stdin() {
|
||||||
|
read -r "$@" </dev/tty
|
||||||
|
}
|
||||||
|
|
||||||
|
_get_cursor_row() {
|
||||||
|
declare IFS=';'
|
||||||
|
_read_stdin -sdR -p $'\E[6n' ROW COL
|
||||||
|
echo "${ROW#*[}"
|
||||||
|
}
|
||||||
|
|
||||||
|
_cursor_blink_on() {
|
||||||
|
echo -en "\033[?25h" >&2
|
||||||
|
}
|
||||||
|
_cursor_blink_off() {
|
||||||
|
echo -en "\033[?25l" >&2
|
||||||
|
}
|
||||||
|
|
||||||
|
_cursor_to() {
|
||||||
|
echo -en "\033[$1;$2H" >&2
|
||||||
|
}
|
||||||
|
|
||||||
|
# shellcheck disable=SC2154
|
||||||
|
_key_input() {
|
||||||
|
declare ESC=$'\033'
|
||||||
|
declare IFS=''
|
||||||
|
_read_stdin -rsn1 a
|
||||||
|
if [[ "$ESC" == "$a" ]]; then
|
||||||
|
_read_stdin -rsn2 b
|
||||||
|
fi
|
||||||
|
|
||||||
|
declare input="${a}${b}"
|
||||||
|
case "$input" in
|
||||||
|
"${ESC}[A" | "k") echo up ;;
|
||||||
|
"${ESC}[B" | "j") echo down ;;
|
||||||
|
"${ESC}[C" | "l") echo right ;;
|
||||||
|
"${ESC}[D" | "h") echo left ;;
|
||||||
|
'') echo enter ;;
|
||||||
|
' ') echo space ;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
_new_line_foreach_item() {
|
||||||
|
count=0
|
||||||
|
while [[ $count -lt $1 ]]; do
|
||||||
|
echo "" >&2
|
||||||
|
((count++))
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
_prompt_text() {
|
||||||
|
echo -en "\033[32m?\033[0m\033[1m ${1}\033[0m " >&2
|
||||||
|
}
|
||||||
|
|
||||||
|
_decrement_selected() {
|
||||||
|
declare selected=$1
|
||||||
|
((selected--))
|
||||||
|
if [[ "${selected}" -lt 0 ]]; then
|
||||||
|
selected=$(($2 - 1))
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo -n $selected
|
||||||
|
}
|
||||||
|
|
||||||
|
_increment_selected() {
|
||||||
|
declare selected=$1
|
||||||
|
((selected++))
|
||||||
|
|
||||||
|
if [[ "${selected}" -ge "${opts_count}" ]]; then
|
||||||
|
selected=0
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo -n $selected
|
||||||
|
}
|
||||||
|
|
||||||
|
# shellcheck disable=SC2154
|
||||||
|
input() {
|
||||||
|
_prompt_text "$1"
|
||||||
|
echo -en "\033[36m\c" >&2
|
||||||
|
_read_stdin -r text
|
||||||
|
echo -n "${text}"
|
||||||
|
}
|
||||||
|
|
||||||
|
confirm() {
|
||||||
|
trap "stty echo; exit" EXIT
|
||||||
|
_prompt_text "$1 (y/N)"
|
||||||
|
echo -en "\033[36m\c " >&2
|
||||||
|
|
||||||
|
declare first_row
|
||||||
|
first_row=$(_get_cursor_row)
|
||||||
|
declare current_row
|
||||||
|
current_row=$((first_row - 1))
|
||||||
|
declare result=""
|
||||||
|
echo -n " " >&2
|
||||||
|
|
||||||
|
while true; do
|
||||||
|
echo -e "\033[1D\c " >&2
|
||||||
|
_read_stdin -n1 result
|
||||||
|
|
||||||
|
case "$result" in
|
||||||
|
y | Y)
|
||||||
|
echo -n 1
|
||||||
|
break
|
||||||
|
;;
|
||||||
|
n | N | *)
|
||||||
|
echo -n 0
|
||||||
|
break
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
echo -en "\033[0m" >&2
|
||||||
|
echo "" >&2
|
||||||
|
}
|
||||||
|
|
||||||
|
list() {
|
||||||
|
_prompt_text "$1 "
|
||||||
|
declare opts=("${@:2}")
|
||||||
|
declare opts_count=$(($# - 1))
|
||||||
|
|
||||||
|
_new_line_foreach_item "${#opts[@]}"
|
||||||
|
|
||||||
|
declare last_row
|
||||||
|
last_row=$(_get_cursor_row)
|
||||||
|
declare first_row
|
||||||
|
first_row=$((last_row - opts_count + 1))
|
||||||
|
|
||||||
|
trap "_cursor_blink_on; stty echo; exit" 2
|
||||||
|
|
||||||
|
_cursor_blink_off
|
||||||
|
|
||||||
|
declare selected=0
|
||||||
|
while true; do
|
||||||
|
declare idx=0
|
||||||
|
for opt in "${opts[@]}"; do
|
||||||
|
_cursor_to $((first_row + idx))
|
||||||
|
|
||||||
|
if [[ $idx -eq "$selected" ]]; then
|
||||||
|
printf "\033[0m\033[36m❯\033[0m \033[36m%s\033[0m" "$opt" >&2
|
||||||
|
else
|
||||||
|
printf " %s" "$opt" >&2
|
||||||
|
fi
|
||||||
|
|
||||||
|
((idx++))
|
||||||
|
done
|
||||||
|
|
||||||
|
case $(_key_input) in
|
||||||
|
enter) break ;;
|
||||||
|
up) selected=$(_decrement_selected "${selected}" "${opts_count}") ;;
|
||||||
|
down) selected=$(_increment_selected "${selected}" "${opts_count}") ;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
echo -en "\n" >&2
|
||||||
|
_cursor_to "${last_row}"
|
||||||
|
_cursor_blink_on
|
||||||
|
echo -n "${selected}"
|
||||||
|
}
|
||||||
|
|
||||||
|
checkbox() {
|
||||||
|
_prompt_text "$1"
|
||||||
|
declare opts
|
||||||
|
opts=("${@:2}")
|
||||||
|
declare opts_count
|
||||||
|
opts_count=$(($# - 1))
|
||||||
|
|
||||||
|
_new_line_foreach_item "${#opts[@]}"
|
||||||
|
|
||||||
|
declare last_row
|
||||||
|
last_row=$(_get_cursor_row)
|
||||||
|
declare first_row
|
||||||
|
first_row=$((last_row - opts_count + 1))
|
||||||
|
|
||||||
|
trap "_cursor_blink_on; stty echo; exit" 2
|
||||||
|
|
||||||
|
_cursor_blink_off
|
||||||
|
|
||||||
|
declare selected=0
|
||||||
|
declare checked=()
|
||||||
|
while true; do
|
||||||
|
declare idx=0
|
||||||
|
for opt in "${opts[@]}"; do
|
||||||
|
_cursor_to $((first_row + idx))
|
||||||
|
declare icon="◯"
|
||||||
|
|
||||||
|
for item in "${checked[@]}"; do
|
||||||
|
if [[ "$item" == "$idx" ]]; then
|
||||||
|
icon="◉"
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
if [[ $idx -eq "$selected" ]]; then
|
||||||
|
printf "%s \e[0m\e[36m❯\e[0m \e[36m%-50s\e[0m" "$icon" "$opt" >&2
|
||||||
|
else
|
||||||
|
printf "%s %-50s" "$icon" "$opt" >&2
|
||||||
|
fi
|
||||||
|
|
||||||
|
((idx++))
|
||||||
|
done
|
||||||
|
|
||||||
|
case $(_key_input) in
|
||||||
|
enter) break ;;
|
||||||
|
space)
|
||||||
|
declare found=0
|
||||||
|
for item in "${checked[@]}"; do
|
||||||
|
if [[ "$item" == "$selected" ]]; then
|
||||||
|
found=1
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ $found -eq 1 ]; then
|
||||||
|
checked=("${checked[@]/$selected/}")
|
||||||
|
else
|
||||||
|
checked+=("${selected}")
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
up) selected=$(_decrement_selected "${selected}" "${opts_count}") ;;
|
||||||
|
down) selected=$(_increment_selected "${selected}" "${opts_count}") ;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
_cursor_to "${last_row}"
|
||||||
|
_cursor_blink_on
|
||||||
|
IFS="" echo -n "${checked[@]}"
|
||||||
|
}
|
||||||
|
|
||||||
|
password() {
|
||||||
|
_prompt_text "$1"
|
||||||
|
echo -en "\033[36m" >&2
|
||||||
|
declare password=''
|
||||||
|
declare IFS=
|
||||||
|
|
||||||
|
while _read_stdin -r -s -n1 char; do
|
||||||
|
[[ -z "${char}" ]] && {
|
||||||
|
printf '\n' >&2
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
if [[ "${char}" == $'\x7f' ]]; then
|
||||||
|
if [[ "${#password}" -gt 0 ]]; then
|
||||||
|
password="${password%?}"
|
||||||
|
echo -en '\b \b' >&2
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
password+=$char
|
||||||
|
echo -en '*' >&2
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
echo -en "\e[0m" >&2
|
||||||
|
echo -n "${password}"
|
||||||
|
}
|
||||||
|
|
||||||
|
editor() {
|
||||||
|
tmpfile=$(mktemp)
|
||||||
|
_prompt_text "$1"
|
||||||
|
echo "" >&2
|
||||||
|
"${EDITOR:-vi}" "${tmpfile}" >/dev/tty
|
||||||
|
echo -en "\033[36m" >&2
|
||||||
|
sed -e 's/^/ /' "${tmpfile}" >&2
|
||||||
|
echo -en "\033[0m" >&2
|
||||||
|
cat "${tmpfile}"
|
||||||
|
}
|
||||||
|
|
||||||
|
with_validate() {
|
||||||
|
while true; do
|
||||||
|
declare val
|
||||||
|
val="$(eval "$1")"
|
||||||
|
|
||||||
|
if ($2 "$val" >/dev/null); then
|
||||||
|
echo "$val"
|
||||||
|
break
|
||||||
|
else
|
||||||
|
show_error "$($2 "$val")"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
range() {
|
||||||
|
declare min="$2"
|
||||||
|
declare current="$3"
|
||||||
|
declare max="$4"
|
||||||
|
declare selected="${current}"
|
||||||
|
declare max_len_current
|
||||||
|
max_len_current=0
|
||||||
|
|
||||||
|
if [[ "${#min}" -gt "${#max}" ]]; then
|
||||||
|
max_len_current="${#min}"
|
||||||
|
else
|
||||||
|
max_len_current="${#max}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
declare padding
|
||||||
|
padding="$(printf "%-${max_len_current}s" "")"
|
||||||
|
declare first_row
|
||||||
|
first_row=$(_get_cursor_row)
|
||||||
|
declare current_row
|
||||||
|
current_row=$((first_row - 1))
|
||||||
|
|
||||||
|
trap "_cursor_blink_on; stty echo; exit" 2
|
||||||
|
|
||||||
|
_cursor_blink_off
|
||||||
|
|
||||||
|
_check_range() {
|
||||||
|
val=$1
|
||||||
|
|
||||||
|
if [[ "$val" -gt "$max" ]]; then
|
||||||
|
val=$min
|
||||||
|
elif [[ "$val" -lt "$min" ]]; then
|
||||||
|
val=$max
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "$val"
|
||||||
|
}
|
||||||
|
|
||||||
|
while true; do
|
||||||
|
_prompt_text "$1"
|
||||||
|
printf "\033[37m%s\033[0m \033[1;90m❮\033[0m \033[36m%s%s\033[0m \033[1;90m❯\033[0m \033[37m%s\033[0m\n" "$min" "${padding:${#selected}}" "$selected" "$max" >&2
|
||||||
|
|
||||||
|
case $(_key_input) in
|
||||||
|
enter)
|
||||||
|
break
|
||||||
|
;;
|
||||||
|
left)
|
||||||
|
selected="$(_check_range $((selected - 1)))"
|
||||||
|
;;
|
||||||
|
right)
|
||||||
|
selected="$(_check_range $((selected + 1)))"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
_cursor_to "$current_row"
|
||||||
|
done
|
||||||
|
|
||||||
|
echo "$selected"
|
||||||
|
}
|
||||||
|
|
||||||
|
validate_present() {
|
||||||
|
if [ "$1" != "" ]; then
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
error "Please specify the value"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
show_error() {
|
||||||
|
echo -e "\033[91;1m✘ $1\033[0m" >&2
|
||||||
|
}
|
||||||
|
|
||||||
|
show_success() {
|
||||||
|
echo -e "\033[92;1m✔ $1\033[0m" >&2
|
||||||
|
}
|
||||||
|
|
||||||
|
detect_os() {
|
||||||
|
case "$OSTYPE" in
|
||||||
|
solaris*) echo "solaris" ;;
|
||||||
|
darwin*) echo "macos" ;;
|
||||||
|
linux*) echo "linux" ;;
|
||||||
|
bsd*) echo "bsd" ;;
|
||||||
|
msys*) echo "windows" ;;
|
||||||
|
cygwin*) echo "windows" ;;
|
||||||
|
*) echo "unknown" ;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
get_opener() {
|
||||||
|
declare cmd
|
||||||
|
|
||||||
|
case "$(detect_os)" in
|
||||||
|
macos) cmd="open" ;;
|
||||||
|
linux) cmd="xdg-open" ;;
|
||||||
|
windows) cmd="start" ;;
|
||||||
|
*) cmd="" ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
echo "$cmd"
|
||||||
|
}
|
||||||
|
|
||||||
|
open_link() {
|
||||||
|
cmd="$(get_opener)"
|
||||||
|
|
||||||
|
if [[ "$cmd" == "" ]]; then
|
||||||
|
error "Your platform is not supported for opening links."
|
||||||
|
red "Please open the following URL in your preferred browser:"
|
||||||
|
red " ${1}"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
$cmd "$1"
|
||||||
|
|
||||||
|
if [[ $? -eq 1 ]]; then
|
||||||
|
error "Failed to open your browser."
|
||||||
|
red "Please open the following URL in your browser:"
|
||||||
|
red "${1}"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
guard_operation() {
|
||||||
|
if [[ -t 1 ]]; then
|
||||||
|
ans="$(confirm "${1:-Are you sure you want to continue?}")"
|
||||||
|
|
||||||
|
if [[ "$ans" == 0 ]]; then
|
||||||
|
error "Operation aborted!" 2>&1
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Here is an example of a patch block that can be applied to modify the file to request the user's name:
|
||||||
|
# --- a/hello.py
|
||||||
|
# +++ b/hello.py
|
||||||
|
# \@@ ... @@
|
||||||
|
# def hello():
|
||||||
|
# - print("Hello World")
|
||||||
|
# + name = input("What is your name? ")
|
||||||
|
# + print(f"Hello {name}")
|
||||||
|
patch_file() {
|
||||||
|
awk '
|
||||||
|
FNR == NR {
|
||||||
|
lines[FNR] = $0
|
||||||
|
next;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
patchLines[FNR] = $0
|
||||||
|
}
|
||||||
|
|
||||||
|
END {
|
||||||
|
totalPatchLines=length(patchLines)
|
||||||
|
totalLines = length(lines)
|
||||||
|
patchLineIndex = 1
|
||||||
|
|
||||||
|
mode = "none"
|
||||||
|
|
||||||
|
while (patchLineIndex <= totalPatchLines) {
|
||||||
|
line = patchLines[patchLineIndex]
|
||||||
|
|
||||||
|
if (line ~ /^--- / || line ~ /^\+\+\+ /) {
|
||||||
|
patchLineIndex++
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if (line ~ /^@@ /) {
|
||||||
|
mode = "hunk"
|
||||||
|
hunkIndex++
|
||||||
|
patchLineIndex++
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mode == "hunk") {
|
||||||
|
while (patchLineIndex <= totalPatchLines && line ~ /^[-+ ]|^\s*$/ && line !~ /^--- /) {
|
||||||
|
sanitizedLine = substr(line, 2)
|
||||||
|
|
||||||
|
if (line !~ /^\+/) {
|
||||||
|
hunkTotalOriginalLines[hunkIndex]++;
|
||||||
|
hunkOriginalLines[hunkIndex,hunkTotalOriginalLines[hunkIndex]] = sanitizedLine
|
||||||
|
}
|
||||||
|
|
||||||
|
if (line !~ /^-/) {
|
||||||
|
hunkTotalUpdatedLines[hunkIndex]++;
|
||||||
|
hunkUpdatedLines[hunkIndex,hunkTotalUpdatedLines[hunkIndex]] = sanitizedLine
|
||||||
|
}
|
||||||
|
|
||||||
|
patchLineIndex++
|
||||||
|
line = patchLines[patchLineIndex]
|
||||||
|
}
|
||||||
|
|
||||||
|
mode = "none"
|
||||||
|
} else {
|
||||||
|
patchLineIndex++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hunkIndex == 0) {
|
||||||
|
print "error: no patch" > "/dev/stderr"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
totalHunks = hunkIndex
|
||||||
|
hunkIndex = 1
|
||||||
|
|
||||||
|
for (lineIndex = 1; lineIndex <= totalLines; lineIndex++) {
|
||||||
|
line = lines[lineIndex]
|
||||||
|
nextLineIndex = 0
|
||||||
|
|
||||||
|
if (hunkIndex <= totalHunks && line == hunkOriginalLines[hunkIndex,1]) {
|
||||||
|
nextLineIndex = lineIndex + 1
|
||||||
|
|
||||||
|
for (i = 2; i <= hunkTotalOriginalLines[hunkIndex]; i++) {
|
||||||
|
if (lines[nextLineIndex] != hunkOriginalLines[hunkIndex,i]) {
|
||||||
|
nextLineIndex = 0
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
nextLineIndex++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nextLineIndex > 0) {
|
||||||
|
for (i = 1; i <= hunkTotalUpdatedLines[hunkIndex]; i++) {
|
||||||
|
print hunkUpdatedLines[hunkIndex,i]
|
||||||
|
}
|
||||||
|
|
||||||
|
hunkIndex++
|
||||||
|
lineIndex = nextLineIndex - 1;
|
||||||
|
} else {
|
||||||
|
print line
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hunkIndex != totalHunks + 1) {
|
||||||
|
print "error: unable to apply patch" > "/dev/stderr"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function inspectHunks() {
|
||||||
|
print "/* Begin inspecting hunks"
|
||||||
|
|
||||||
|
for (i = 1; i <= totalHunks; i++) {
|
||||||
|
print ">>>>>> Original"
|
||||||
|
|
||||||
|
for (j = 1; j <= hunkTotalOriginalLines[i]; j++) {
|
||||||
|
print hunkOriginalLines[i,j]
|
||||||
|
}
|
||||||
|
|
||||||
|
print "======"
|
||||||
|
|
||||||
|
for (j = 1; j <= hunkTotalUpdatedLines[i]; j++) {
|
||||||
|
print hunkUpdatedLines[i,j]
|
||||||
|
}
|
||||||
|
|
||||||
|
print "<<<<<< Updated"
|
||||||
|
}
|
||||||
|
|
||||||
|
print "End inspecting hunks */\n"
|
||||||
|
}' "$1" "$2"
|
||||||
|
}
|
||||||
|
|
||||||
|
guard_path() {
|
||||||
|
if [[ "$#" -ne 2 ]]; then
|
||||||
|
echo "Usage: guard_path <path> <confirmation_prompt>" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -t 1 ]]; then
|
||||||
|
path="$(_to_real_path "$1")"
|
||||||
|
confirmation_prompt="$2"
|
||||||
|
|
||||||
|
if [[ ! "$path" == "$(pwd)"* ]]; then
|
||||||
|
ans="$(confirm "$confirmation_prompt")"
|
||||||
|
|
||||||
|
if [[ "$ans" == 0 ]]; then
|
||||||
|
error "Operation aborted!" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
_to_real_path() {
|
||||||
|
path="$1"
|
||||||
|
|
||||||
|
if [[ $OS == "Windows_NT" ]]; then
|
||||||
|
path="$(cygpath -u "$path")"
|
||||||
|
fi
|
||||||
|
|
||||||
|
awk -v path="$path" -v pwd="$PWD" '
|
||||||
|
BEGIN {
|
||||||
|
if (path !~ /^\//) {
|
||||||
|
path = pwd "/" path
|
||||||
|
}
|
||||||
|
|
||||||
|
if (path ~ /\/\.{1,2}?$/) {
|
||||||
|
isDir = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
split(path, parts, "/")
|
||||||
|
newPartsLength = 0
|
||||||
|
|
||||||
|
for (i = 1; i <= length(parts); i++) {
|
||||||
|
part = parts[i]
|
||||||
|
if (part == "..") {
|
||||||
|
if (newPartsLength > 0) {
|
||||||
|
delete newParts[newPartsLength--]
|
||||||
|
}
|
||||||
|
} else if (part != "." && part != "") {
|
||||||
|
newParts[++newPartsLength] = part
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isDir == 1 || newPartsLength == 0) {
|
||||||
|
newParts[++newPartsLength] = ""
|
||||||
|
}
|
||||||
|
|
||||||
|
printf "/"
|
||||||
|
|
||||||
|
for (i = 1; i <= newPartsLength; i++) {
|
||||||
|
newPart = newParts[i]
|
||||||
|
printf newPart
|
||||||
|
if (i < newPartsLength) {
|
||||||
|
printf "/"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}'
|
||||||
|
}
|
||||||
+41
-3
@@ -20,10 +20,11 @@ use std::{
|
|||||||
path::{Path, PathBuf},
|
path::{Path, PathBuf},
|
||||||
};
|
};
|
||||||
use strum_macros::AsRefStr;
|
use strum_macros::AsRefStr;
|
||||||
|
use crate::config::ensure_parent_exists;
|
||||||
|
|
||||||
#[derive(Embed)]
|
#[derive(Embed)]
|
||||||
#[folder = "assets/functions/"]
|
#[folder = "assets/functions/"]
|
||||||
struct FunctionAsset;
|
struct FunctionAssets;
|
||||||
|
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
const PATH_SEP: &str = ";";
|
const PATH_SEP: &str = ";";
|
||||||
@@ -122,7 +123,43 @@ pub struct Functions {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Functions {
|
impl Functions {
|
||||||
|
fn install_global_tools() -> Result<()> {
|
||||||
|
ensure_parent_exists(&Config::global_tools_file())?;
|
||||||
|
|
||||||
|
info!("Installing global built-in functions in {}", Config::functions_dir().display());
|
||||||
|
|
||||||
|
for file in FunctionAssets::iter() {
|
||||||
|
debug!("Processing function file: {}", file.as_ref());
|
||||||
|
if file.as_ref().starts_with("scripts/") {
|
||||||
|
debug!("Skipping script file: {}", file.as_ref());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
let embedded_file = FunctionAssets::get(&file).ok_or_else(|| {
|
||||||
|
anyhow!(
|
||||||
|
"Failed to load embedded function file: {}",
|
||||||
|
file.as_ref()
|
||||||
|
)
|
||||||
|
})?;
|
||||||
|
let content = unsafe { std::str::from_utf8_unchecked(&embedded_file.data) };
|
||||||
|
let file_path = Config::functions_dir().join(file.as_ref());
|
||||||
|
|
||||||
|
if file_path.exists() {
|
||||||
|
debug!("Function file already exists, skipping: {}", file_path.display());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
ensure_parent_exists(&file_path)?;
|
||||||
|
info!("Creating function file: {}", file_path.display());
|
||||||
|
let mut function_file = File::create(&file_path)?;
|
||||||
|
function_file.write_all(content.as_bytes())?;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
pub fn init() -> Result<Self> {
|
pub fn init() -> Result<Self> {
|
||||||
|
Self::install_global_tools()?;
|
||||||
info!(
|
info!(
|
||||||
"Initializing global functions from {}",
|
"Initializing global functions from {}",
|
||||||
Config::global_tools_file().display()
|
Config::global_tools_file().display()
|
||||||
@@ -144,6 +181,7 @@ impl Functions {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn init_agent(name: &str, global_tools: &[String]) -> Result<Self> {
|
pub fn init_agent(name: &str, global_tools: &[String]) -> Result<Self> {
|
||||||
|
Self::install_global_tools()?;
|
||||||
let global_tools_declarations = if !global_tools.is_empty() {
|
let global_tools_declarations = if !global_tools.is_empty() {
|
||||||
let enabled_tools = global_tools.join("\n");
|
let enabled_tools = global_tools.join("\n");
|
||||||
info!("Loading global tools for agent: {name}: {enabled_tools}");
|
info!("Loading global tools for agent: {name}: {enabled_tools}");
|
||||||
@@ -448,7 +486,7 @@ impl Functions {
|
|||||||
binary_name,
|
binary_name,
|
||||||
binary_script_file.display(),
|
binary_script_file.display(),
|
||||||
);
|
);
|
||||||
let embedded_file = FunctionAsset::get(&format!(
|
let embedded_file = FunctionAssets::get(&format!(
|
||||||
"scripts/run-{}.{}",
|
"scripts/run-{}.{}",
|
||||||
binary_type.as_ref().to_lowercase(),
|
binary_type.as_ref().to_lowercase(),
|
||||||
language.to_extension()
|
language.to_extension()
|
||||||
@@ -542,7 +580,7 @@ impl Functions {
|
|||||||
binary_name,
|
binary_name,
|
||||||
binary_file.display()
|
binary_file.display()
|
||||||
);
|
);
|
||||||
let embedded_file = FunctionAsset::get(&format!(
|
let embedded_file = FunctionAssets::get(&format!(
|
||||||
"scripts/run-{}.{}",
|
"scripts/run-{}.{}",
|
||||||
binary_type.as_ref().to_lowercase(),
|
binary_type.as_ref().to_lowercase(),
|
||||||
language.to_extension()
|
language.to_extension()
|
||||||
|
|||||||
Reference in New Issue
Block a user