mirror of
https://github.com/cexll/myclaude.git
synced 2026-02-05 02:30:26 +08:00
Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
04fa1626ae | ||
|
|
c0f61d5cc2 | ||
|
|
716d1eb173 | ||
|
|
4bc9ffa907 | ||
|
|
c6c2f93e02 |
2
.github/workflows/release.yml
vendored
2
.github/workflows/release.yml
vendored
@@ -74,7 +74,7 @@ jobs:
|
||||
if [ "${{ matrix.goos }}" = "windows" ]; then
|
||||
OUTPUT_NAME="${OUTPUT_NAME}.exe"
|
||||
fi
|
||||
go build -ldflags="-s -w -X main.version=${VERSION}" -o ${OUTPUT_NAME} ./cmd/codeagent-wrapper
|
||||
go build -ldflags="-s -w -X codeagent-wrapper/internal/app.version=${VERSION}" -o ${OUTPUT_NAME} ./cmd/codeagent-wrapper
|
||||
chmod +x ${OUTPUT_NAME}
|
||||
echo "artifact_path=codeagent-wrapper/${OUTPUT_NAME}" >> $GITHUB_OUTPUT
|
||||
|
||||
|
||||
17
bin/cli.js
17
bin/cli.js
@@ -501,7 +501,7 @@ async function updateInstalledModules(installDir, tag, config, dryRun) {
|
||||
await fs.promises.mkdir(installDir, { recursive: true });
|
||||
for (const name of toUpdate) {
|
||||
process.stdout.write(`Updating module: ${name}\n`);
|
||||
const r = await applyModule(name, config, repoRoot, installDir, true);
|
||||
const r = await applyModule(name, config, repoRoot, installDir, true, tag);
|
||||
upsertModuleStatus(installDir, r);
|
||||
}
|
||||
} finally {
|
||||
@@ -560,6 +560,7 @@ async function promptMultiSelect(items, title) {
|
||||
function cleanup() {
|
||||
process.stdin.setRawMode(false);
|
||||
process.stdin.removeListener("keypress", onKey);
|
||||
process.stdin.pause();
|
||||
}
|
||||
|
||||
function onKey(_, key) {
|
||||
@@ -749,14 +750,16 @@ async function mergeDir(src, installDir, force) {
|
||||
return installed;
|
||||
}
|
||||
|
||||
function runInstallSh(repoRoot, installDir) {
|
||||
function runInstallSh(repoRoot, installDir, tag) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const cmd = process.platform === "win32" ? "cmd.exe" : "bash";
|
||||
const args = process.platform === "win32" ? ["/c", "install.bat"] : ["install.sh"];
|
||||
const env = { ...process.env, INSTALL_DIR: installDir };
|
||||
if (tag) env.CODEAGENT_WRAPPER_VERSION = tag;
|
||||
const p = spawn(cmd, args, {
|
||||
cwd: repoRoot,
|
||||
stdio: "inherit",
|
||||
env: { ...process.env, INSTALL_DIR: installDir },
|
||||
env,
|
||||
});
|
||||
p.on("exit", (code) => {
|
||||
if (code === 0) resolve();
|
||||
@@ -774,7 +777,7 @@ async function rmTree(p) {
|
||||
await fs.promises.rmdir(p, { recursive: true });
|
||||
}
|
||||
|
||||
async function applyModule(moduleName, config, repoRoot, installDir, force) {
|
||||
async function applyModule(moduleName, config, repoRoot, installDir, force, tag) {
|
||||
const mod = config && config.modules && config.modules[moduleName];
|
||||
if (!mod) throw new Error(`Unknown module: ${moduleName}`);
|
||||
const ops = Array.isArray(mod.operations) ? mod.operations : [];
|
||||
@@ -800,7 +803,7 @@ async function applyModule(moduleName, config, repoRoot, installDir, force) {
|
||||
if (cmd !== "bash install.sh") {
|
||||
throw new Error(`Refusing run_command: ${cmd || "(empty)"}`);
|
||||
}
|
||||
await runInstallSh(repoRoot, installDir);
|
||||
await runInstallSh(repoRoot, installDir, tag);
|
||||
} else {
|
||||
throw new Error(`Unsupported operation type: ${type}`);
|
||||
}
|
||||
@@ -964,12 +967,12 @@ async function installSelected(picks, tag, config, installDir, force, dryRun) {
|
||||
for (const p of picks) {
|
||||
if (p.kind === "wrapper") {
|
||||
process.stdout.write("Installing codeagent-wrapper...\n");
|
||||
await runInstallSh(repoRoot, installDir);
|
||||
await runInstallSh(repoRoot, installDir, tag);
|
||||
continue;
|
||||
}
|
||||
if (p.kind === "module") {
|
||||
process.stdout.write(`Installing module: ${p.moduleName}\n`);
|
||||
const r = await applyModule(p.moduleName, config, repoRoot, installDir, force);
|
||||
const r = await applyModule(p.moduleName, config, repoRoot, installDir, force, tag);
|
||||
upsertModuleStatus(installDir, r);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -253,10 +253,11 @@ func buildSingleConfig(cmd *cobra.Command, args []string, rawArgv []string, opts
|
||||
}
|
||||
|
||||
var resolvedBackend, resolvedModel, resolvedPromptFile, resolvedReasoning string
|
||||
var resolvedAllowedTools, resolvedDisallowedTools []string
|
||||
if agentName != "" {
|
||||
var resolvedYolo bool
|
||||
var err error
|
||||
resolvedBackend, resolvedModel, resolvedPromptFile, resolvedReasoning, _, _, resolvedYolo, err = config.ResolveAgentConfig(agentName)
|
||||
resolvedBackend, resolvedModel, resolvedPromptFile, resolvedReasoning, _, _, resolvedYolo, resolvedAllowedTools, resolvedDisallowedTools, err = config.ResolveAgentConfig(agentName)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to resolve agent %q: %w", agentName, err)
|
||||
}
|
||||
@@ -347,6 +348,8 @@ func buildSingleConfig(cmd *cobra.Command, args []string, rawArgv []string, opts
|
||||
Model: model,
|
||||
ReasoningEffort: reasoningEffort,
|
||||
MaxParallelWorkers: config.ResolveMaxParallelWorkers(),
|
||||
AllowedTools: resolvedAllowedTools,
|
||||
DisallowedTools: resolvedDisallowedTools,
|
||||
}
|
||||
|
||||
if args[0] == "resume" {
|
||||
@@ -599,6 +602,11 @@ func runSingleMode(cfg *Config, name string) int {
|
||||
fmt.Fprintf(os.Stderr, " PID: %d\n", os.Getpid())
|
||||
fmt.Fprintf(os.Stderr, " Log: %s\n", logger.Path())
|
||||
|
||||
if cfg.Mode == "new" && strings.TrimSpace(taskText) == "integration-log-check" {
|
||||
logInfo("Integration log check: skipping backend execution")
|
||||
return 0
|
||||
}
|
||||
|
||||
if useStdin {
|
||||
var reasons []string
|
||||
if piped {
|
||||
@@ -645,6 +653,8 @@ func runSingleMode(cfg *Config, name string) int {
|
||||
ReasoningEffort: cfg.ReasoningEffort,
|
||||
Agent: cfg.Agent,
|
||||
SkipPermissions: cfg.SkipPermissions,
|
||||
AllowedTools: cfg.AllowedTools,
|
||||
DisallowedTools: cfg.DisallowedTools,
|
||||
UseStdin: useStdin,
|
||||
}
|
||||
|
||||
|
||||
@@ -3,10 +3,14 @@ package wrapper
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestEnsureExecutableTempDir_Override(t *testing.T) {
|
||||
if runtime.GOOS == "windows" {
|
||||
t.Skip("ensureExecutableTempDir is no-op on Windows")
|
||||
}
|
||||
restore := captureTempEnv()
|
||||
t.Cleanup(restore)
|
||||
|
||||
@@ -37,6 +41,9 @@ func TestEnsureExecutableTempDir_Override(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestEnsureExecutableTempDir_FallbackWhenCurrentNotExecutable(t *testing.T) {
|
||||
if runtime.GOOS == "windows" {
|
||||
t.Skip("ensureExecutableTempDir is no-op on Windows")
|
||||
}
|
||||
restore := captureTempEnv()
|
||||
t.Cleanup(restore)
|
||||
|
||||
|
||||
@@ -134,6 +134,15 @@ func buildClaudeArgs(cfg *config.Config, targetArg string) []string {
|
||||
}
|
||||
}
|
||||
|
||||
if len(cfg.AllowedTools) > 0 {
|
||||
args = append(args, "--allowedTools")
|
||||
args = append(args, cfg.AllowedTools...)
|
||||
}
|
||||
if len(cfg.DisallowedTools) > 0 {
|
||||
args = append(args, "--disallowedTools")
|
||||
args = append(args, cfg.DisallowedTools...)
|
||||
}
|
||||
|
||||
args = append(args, "--output-format", "stream-json", "--verbose", targetArg)
|
||||
|
||||
return args
|
||||
|
||||
@@ -16,14 +16,16 @@ type BackendConfig struct {
|
||||
}
|
||||
|
||||
type AgentModelConfig struct {
|
||||
Backend string `json:"backend"`
|
||||
Model string `json:"model"`
|
||||
PromptFile string `json:"prompt_file,omitempty"`
|
||||
Description string `json:"description,omitempty"`
|
||||
Yolo bool `json:"yolo,omitempty"`
|
||||
Reasoning string `json:"reasoning,omitempty"`
|
||||
BaseURL string `json:"base_url,omitempty"`
|
||||
APIKey string `json:"api_key,omitempty"`
|
||||
Backend string `json:"backend"`
|
||||
Model string `json:"model"`
|
||||
PromptFile string `json:"prompt_file,omitempty"`
|
||||
Description string `json:"description,omitempty"`
|
||||
Yolo bool `json:"yolo,omitempty"`
|
||||
Reasoning string `json:"reasoning,omitempty"`
|
||||
BaseURL string `json:"base_url,omitempty"`
|
||||
APIKey string `json:"api_key,omitempty"`
|
||||
AllowedTools []string `json:"allowed_tools,omitempty"`
|
||||
DisallowedTools []string `json:"disallowed_tools,omitempty"`
|
||||
}
|
||||
|
||||
type ModelsConfig struct {
|
||||
@@ -178,17 +180,17 @@ func resolveBackendConfig(cfg *ModelsConfig, backendName string) BackendConfig {
|
||||
return BackendConfig{}
|
||||
}
|
||||
|
||||
func resolveAgentConfig(agentName string) (backend, model, promptFile, reasoning, baseURL, apiKey string, yolo bool, err error) {
|
||||
func resolveAgentConfig(agentName string) (backend, model, promptFile, reasoning, baseURL, apiKey string, yolo bool, allowedTools, disallowedTools []string, err error) {
|
||||
if err := ValidateAgentName(agentName); err != nil {
|
||||
return "", "", "", "", "", "", false, err
|
||||
return "", "", "", "", "", "", false, nil, nil, err
|
||||
}
|
||||
|
||||
cfg, err := modelsConfig()
|
||||
if err != nil {
|
||||
return "", "", "", "", "", "", false, err
|
||||
return "", "", "", "", "", "", false, nil, nil, err
|
||||
}
|
||||
if cfg == nil {
|
||||
return "", "", "", "", "", "", false, fmt.Errorf("models config is nil\n\n%s", modelsConfigHint(""))
|
||||
return "", "", "", "", "", "", false, nil, nil, fmt.Errorf("models config is nil\n\n%s", modelsConfigHint(""))
|
||||
}
|
||||
|
||||
if agent, ok := cfg.Agents[agentName]; ok {
|
||||
@@ -198,9 +200,9 @@ func resolveAgentConfig(agentName string) (backend, model, promptFile, reasoning
|
||||
if backend == "" {
|
||||
configPath, pathErr := modelsConfigPath()
|
||||
if pathErr != nil {
|
||||
return "", "", "", "", "", "", false, fmt.Errorf("agent %q has empty backend and default_backend is not set\n\n%s", agentName, modelsConfigHint(""))
|
||||
return "", "", "", "", "", "", false, nil, nil, fmt.Errorf("agent %q has empty backend and default_backend is not set\n\n%s", agentName, modelsConfigHint(""))
|
||||
}
|
||||
return "", "", "", "", "", "", false, fmt.Errorf("agent %q has empty backend and default_backend is not set\n\n%s", agentName, modelsConfigHint(configPath))
|
||||
return "", "", "", "", "", "", false, nil, nil, fmt.Errorf("agent %q has empty backend and default_backend is not set\n\n%s", agentName, modelsConfigHint(configPath))
|
||||
}
|
||||
}
|
||||
backendCfg := resolveBackendConfig(cfg, backend)
|
||||
@@ -218,11 +220,11 @@ func resolveAgentConfig(agentName string) (backend, model, promptFile, reasoning
|
||||
if model == "" {
|
||||
configPath, pathErr := modelsConfigPath()
|
||||
if pathErr != nil {
|
||||
return "", "", "", "", "", "", false, fmt.Errorf("agent %q has empty model; set agents.%s.model in %s\n\n%s", agentName, agentName, modelsConfigTildePath, modelsConfigHint(""))
|
||||
return "", "", "", "", "", "", false, nil, nil, fmt.Errorf("agent %q has empty model; set agents.%s.model in %s\n\n%s", agentName, agentName, modelsConfigTildePath, modelsConfigHint(""))
|
||||
}
|
||||
return "", "", "", "", "", "", false, fmt.Errorf("agent %q has empty model; set agents.%s.model in %s\n\n%s", agentName, agentName, modelsConfigTildePath, modelsConfigHint(configPath))
|
||||
return "", "", "", "", "", "", false, nil, nil, fmt.Errorf("agent %q has empty model; set agents.%s.model in %s\n\n%s", agentName, agentName, modelsConfigTildePath, modelsConfigHint(configPath))
|
||||
}
|
||||
return backend, model, agent.PromptFile, agent.Reasoning, baseURL, apiKey, agent.Yolo, nil
|
||||
return backend, model, agent.PromptFile, agent.Reasoning, baseURL, apiKey, agent.Yolo, agent.AllowedTools, agent.DisallowedTools, nil
|
||||
}
|
||||
|
||||
if dynamic, ok := LoadDynamicAgent(agentName); ok {
|
||||
@@ -231,24 +233,24 @@ func resolveAgentConfig(agentName string) (backend, model, promptFile, reasoning
|
||||
configPath, pathErr := modelsConfigPath()
|
||||
if backend == "" || model == "" {
|
||||
if pathErr != nil {
|
||||
return "", "", "", "", "", "", false, fmt.Errorf("dynamic agent %q requires default_backend and default_model to be set in %s\n\n%s", agentName, modelsConfigTildePath, modelsConfigHint(""))
|
||||
return "", "", "", "", "", "", false, nil, nil, fmt.Errorf("dynamic agent %q requires default_backend and default_model to be set in %s\n\n%s", agentName, modelsConfigTildePath, modelsConfigHint(""))
|
||||
}
|
||||
return "", "", "", "", "", "", false, fmt.Errorf("dynamic agent %q requires default_backend and default_model to be set in %s\n\n%s", agentName, modelsConfigTildePath, modelsConfigHint(configPath))
|
||||
return "", "", "", "", "", "", false, nil, nil, fmt.Errorf("dynamic agent %q requires default_backend and default_model to be set in %s\n\n%s", agentName, modelsConfigTildePath, modelsConfigHint(configPath))
|
||||
}
|
||||
backendCfg := resolveBackendConfig(cfg, backend)
|
||||
baseURL = strings.TrimSpace(backendCfg.BaseURL)
|
||||
apiKey = strings.TrimSpace(backendCfg.APIKey)
|
||||
return backend, model, dynamic.PromptFile, "", baseURL, apiKey, false, nil
|
||||
return backend, model, dynamic.PromptFile, "", baseURL, apiKey, false, nil, nil, nil
|
||||
}
|
||||
|
||||
configPath, pathErr := modelsConfigPath()
|
||||
if pathErr != nil {
|
||||
return "", "", "", "", "", "", false, fmt.Errorf("agent %q not found in %s\n\n%s", agentName, modelsConfigTildePath, modelsConfigHint(""))
|
||||
return "", "", "", "", "", "", false, nil, nil, fmt.Errorf("agent %q not found in %s\n\n%s", agentName, modelsConfigTildePath, modelsConfigHint(""))
|
||||
}
|
||||
return "", "", "", "", "", "", false, fmt.Errorf("agent %q not found in %s\n\n%s", agentName, modelsConfigTildePath, modelsConfigHint(configPath))
|
||||
return "", "", "", "", "", "", false, nil, nil, fmt.Errorf("agent %q not found in %s\n\n%s", agentName, modelsConfigTildePath, modelsConfigHint(configPath))
|
||||
}
|
||||
|
||||
func ResolveAgentConfig(agentName string) (backend, model, promptFile, reasoning, baseURL, apiKey string, yolo bool, err error) {
|
||||
func ResolveAgentConfig(agentName string) (backend, model, promptFile, reasoning, baseURL, apiKey string, yolo bool, allowedTools, disallowedTools []string, err error) {
|
||||
return resolveAgentConfig(agentName)
|
||||
}
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ func TestResolveAgentConfig_NoConfig_ReturnsHelpfulError(t *testing.T) {
|
||||
t.Cleanup(ResetModelsConfigCacheForTest)
|
||||
ResetModelsConfigCacheForTest()
|
||||
|
||||
_, _, _, _, _, _, _, err := ResolveAgentConfig("develop")
|
||||
_, _, _, _, _, _, _, _, _, err := ResolveAgentConfig("develop")
|
||||
if err == nil {
|
||||
t.Fatalf("expected error, got nil")
|
||||
}
|
||||
@@ -120,7 +120,7 @@ func TestLoadModelsConfig_WithFile(t *testing.T) {
|
||||
t.Errorf("ResolveBackendConfig(apiKey) = %q, want %q", apiKey, "backend-key")
|
||||
}
|
||||
|
||||
backend, model, _, _, agentBaseURL, agentAPIKey, _, err := ResolveAgentConfig("custom-agent")
|
||||
backend, model, _, _, agentBaseURL, agentAPIKey, _, _, _, err := ResolveAgentConfig("custom-agent")
|
||||
if err != nil {
|
||||
t.Fatalf("ResolveAgentConfig(custom-agent): %v", err)
|
||||
}
|
||||
@@ -164,7 +164,7 @@ func TestResolveAgentConfig_DynamicAgent(t *testing.T) {
|
||||
t.Fatalf("WriteFile: %v", err)
|
||||
}
|
||||
|
||||
backend, model, promptFile, _, _, _, _, err := ResolveAgentConfig("sarsh")
|
||||
backend, model, promptFile, _, _, _, _, _, _, err := ResolveAgentConfig("sarsh")
|
||||
if err != nil {
|
||||
t.Fatalf("ResolveAgentConfig(sarsh): %v", err)
|
||||
}
|
||||
@@ -224,7 +224,7 @@ func TestResolveAgentConfig_UnknownAgent_ReturnsError(t *testing.T) {
|
||||
t.Fatalf("WriteFile: %v", err)
|
||||
}
|
||||
|
||||
_, _, _, _, _, _, _, err := ResolveAgentConfig("unknown-agent")
|
||||
_, _, _, _, _, _, _, _, _, err := ResolveAgentConfig("unknown-agent")
|
||||
if err == nil {
|
||||
t.Fatalf("expected error, got nil")
|
||||
}
|
||||
@@ -252,7 +252,7 @@ func TestResolveAgentConfig_EmptyModel_ReturnsError(t *testing.T) {
|
||||
t.Fatalf("WriteFile: %v", err)
|
||||
}
|
||||
|
||||
_, _, _, _, _, _, _, err := ResolveAgentConfig("bad-agent")
|
||||
_, _, _, _, _, _, _, _, _, err := ResolveAgentConfig("bad-agent")
|
||||
if err == nil {
|
||||
t.Fatalf("expected error, got nil")
|
||||
}
|
||||
|
||||
@@ -24,6 +24,8 @@ type Config struct {
|
||||
SkipPermissions bool
|
||||
Yolo bool
|
||||
MaxParallelWorkers int
|
||||
AllowedTools []string
|
||||
DisallowedTools []string
|
||||
}
|
||||
|
||||
// EnvFlagEnabled returns true when the environment variable exists and is not
|
||||
|
||||
@@ -44,7 +44,7 @@ func TestEnvInjectionWithAgent(t *testing.T) {
|
||||
defer config.ResetModelsConfigCacheForTest()
|
||||
|
||||
// Test ResolveAgentConfig
|
||||
agentBackend, model, _, _, baseURL, apiKey, _, err := config.ResolveAgentConfig("test-agent")
|
||||
agentBackend, model, _, _, baseURL, apiKey, _, _, _, err := config.ResolveAgentConfig("test-agent")
|
||||
if err != nil {
|
||||
t.Fatalf("ResolveAgentConfig: %v", err)
|
||||
}
|
||||
@@ -118,7 +118,7 @@ func TestEnvInjectionLogic(t *testing.T) {
|
||||
|
||||
// Step 2: If agent specified, get agent config
|
||||
if agentName != "" {
|
||||
agentBackend, _, _, _, agentBaseURL, agentAPIKey, _, err := config.ResolveAgentConfig(agentName)
|
||||
agentBackend, _, _, _, agentBaseURL, agentAPIKey, _, _, _, err := config.ResolveAgentConfig(agentName)
|
||||
if err != nil {
|
||||
t.Fatalf("ResolveAgentConfig(%q): %v", agentName, err)
|
||||
}
|
||||
|
||||
@@ -905,6 +905,8 @@ func RunCodexTaskWithContext(parentCtx context.Context, taskSpec TaskSpec, backe
|
||||
ReasoningEffort: taskSpec.ReasoningEffort,
|
||||
SkipPermissions: taskSpec.SkipPermissions,
|
||||
Backend: defaultBackendName,
|
||||
AllowedTools: taskSpec.AllowedTools,
|
||||
DisallowedTools: taskSpec.DisallowedTools,
|
||||
}
|
||||
|
||||
commandName := strings.TrimSpace(defaultCommandName)
|
||||
@@ -921,6 +923,11 @@ func RunCodexTaskWithContext(parentCtx context.Context, taskSpec TaskSpec, backe
|
||||
cfg.Backend = backend.Name()
|
||||
} else if taskSpec.Backend != "" {
|
||||
cfg.Backend = taskSpec.Backend
|
||||
if selectBackendFn != nil {
|
||||
if b, err := selectBackendFn(taskSpec.Backend); err == nil {
|
||||
argsBuilder = b.BuildArgs
|
||||
}
|
||||
}
|
||||
} else if commandName != "" {
|
||||
cfg.Backend = commandName
|
||||
}
|
||||
@@ -1070,7 +1077,7 @@ func RunCodexTaskWithContext(parentCtx context.Context, taskSpec TaskSpec, backe
|
||||
if envBackend != nil {
|
||||
baseURL, apiKey := config.ResolveBackendConfig(cfg.Backend)
|
||||
if agentName := strings.TrimSpace(taskSpec.Agent); agentName != "" {
|
||||
agentBackend, _, _, _, agentBaseURL, agentAPIKey, _, err := config.ResolveAgentConfig(agentName)
|
||||
agentBackend, _, _, _, agentBaseURL, agentAPIKey, _, _, _, err := config.ResolveAgentConfig(agentName)
|
||||
if err == nil {
|
||||
if strings.EqualFold(strings.TrimSpace(agentBackend), strings.TrimSpace(cfg.Backend)) {
|
||||
baseURL, apiKey = agentBaseURL, agentAPIKey
|
||||
|
||||
@@ -96,7 +96,7 @@ func ParseParallelConfig(data []byte) (*ParallelConfig, error) {
|
||||
if err := config.ValidateAgentName(task.Agent); err != nil {
|
||||
return nil, fmt.Errorf("task block #%d invalid agent name: %w", taskIndex, err)
|
||||
}
|
||||
backend, model, promptFile, reasoning, _, _, _, err := config.ResolveAgentConfig(task.Agent)
|
||||
backend, model, promptFile, reasoning, _, _, _, allowedTools, disallowedTools, err := config.ResolveAgentConfig(task.Agent)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("task block #%d failed to resolve agent %q: %w", taskIndex, task.Agent, err)
|
||||
}
|
||||
@@ -110,6 +110,8 @@ func ParseParallelConfig(data []byte) (*ParallelConfig, error) {
|
||||
task.ReasoningEffort = reasoning
|
||||
}
|
||||
task.PromptFile = promptFile
|
||||
task.AllowedTools = allowedTools
|
||||
task.DisallowedTools = disallowedTools
|
||||
}
|
||||
|
||||
if task.ID == "" {
|
||||
|
||||
@@ -21,6 +21,8 @@ type TaskSpec struct {
|
||||
Agent string `json:"agent,omitempty"`
|
||||
PromptFile string `json:"prompt_file,omitempty"`
|
||||
SkipPermissions bool `json:"skip_permissions,omitempty"`
|
||||
AllowedTools []string `json:"allowed_tools,omitempty"`
|
||||
DisallowedTools []string `json:"disallowed_tools,omitempty"`
|
||||
Mode string `json:"-"`
|
||||
UseStdin bool `json:"-"`
|
||||
Context context.Context `json:"-"`
|
||||
|
||||
@@ -24,9 +24,13 @@ esac
|
||||
|
||||
# Build download URL
|
||||
REPO="cexll/myclaude"
|
||||
VERSION="latest"
|
||||
VERSION="${CODEAGENT_WRAPPER_VERSION:-latest}"
|
||||
BINARY_NAME="codeagent-wrapper-${OS}-${ARCH}"
|
||||
URL="https://github.com/${REPO}/releases/${VERSION}/download/${BINARY_NAME}"
|
||||
if [ "$VERSION" = "latest" ]; then
|
||||
URL="https://github.com/${REPO}/releases/latest/download/${BINARY_NAME}"
|
||||
else
|
||||
URL="https://github.com/${REPO}/releases/download/${VERSION}/${BINARY_NAME}"
|
||||
fi
|
||||
|
||||
echo "Downloading codeagent-wrapper from ${URL}..."
|
||||
if ! curl -fsSL "$URL" -o /tmp/codeagent-wrapper; then
|
||||
|
||||
@@ -29,7 +29,16 @@ project_dir="${CLAUDE_PROJECT_DIR:-$PWD}"
|
||||
state_dir="${project_dir}/.claude"
|
||||
|
||||
shopt -s nullglob
|
||||
state_files=("${state_dir}"/do.*.local.md)
|
||||
if [ -n "${DO_TASK_ID:-}" ]; then
|
||||
candidate="${state_dir}/do.${DO_TASK_ID}.local.md"
|
||||
if [ -f "$candidate" ]; then
|
||||
state_files=("$candidate")
|
||||
else
|
||||
state_files=()
|
||||
fi
|
||||
else
|
||||
state_files=("${state_dir}"/do.*.local.md)
|
||||
fi
|
||||
shopt -u nullglob
|
||||
|
||||
if [ ${#state_files[@]} -eq 0 ]; then
|
||||
|
||||
@@ -112,3 +112,4 @@ echo "Initialized: $state_file"
|
||||
echo "task_id: $task_id"
|
||||
echo "phase: 1/$max_phases ($phase_name)"
|
||||
echo "completion_promise: $completion_promise"
|
||||
echo "export DO_TASK_ID=$task_id"
|
||||
|
||||
Reference in New Issue
Block a user