claude-task-worker 0.102.0 → 0.103.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +15 -0
- package/dist/index.js +75 -15
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -258,10 +258,25 @@ CI やクラウド VM など対話ログインできない環境では、環境
|
|
|
258
258
|
| キー | 型 | 既定 | 説明 |
|
|
259
259
|
|---|---|---|---|
|
|
260
260
|
| `fixReviewPointCallbackCommentMessage` | string | - | `fix-review-point` 完了時に PR へ投稿するコメント(未設定なら投稿しない) |
|
|
261
|
+
| `remoteEnvId` | string \| null | `null` | クラウド実行(`--cloud`)時に `--environment` へ渡すクラウド環境ID。`null` なら渡さず claude 側の既定解決に任せる(下記) |
|
|
261
262
|
| `uiDesign` | object | `{ "enabled": false, "designDir": "designs", "yolo": false }` | UIデザイン先行ワークフロー(下記) |
|
|
262
263
|
| `workers` | object | `{}` | ワーカーごとの上書き設定(下記) |
|
|
263
264
|
| `lastRun` | object | `{}` | 定期ワーカーの最終実行時刻。ワーカーが自動更新するため手で編集しない |
|
|
264
265
|
|
|
266
|
+
#### `claude-task-worker.local.json`(ローカル上書き)
|
|
267
|
+
|
|
268
|
+
同じディレクトリに `claude-task-worker.local.json` を置くと、`claude-task-worker.json` と同じキーを書けて**同じキーはローカル側が勝つ**。マージはネストしたオブジェクトのキー単位(`workers.<name>.model` だけを差し替えられる。配列・スカラーは丸ごと置き換え)。
|
|
269
|
+
|
|
270
|
+
コミットしない前提のファイルで、`claude-task-worker init` が `.gitignore` へ登録する。`remoteEnvId` のように各自の環境で値が違う設定を置く。
|
|
271
|
+
|
|
272
|
+
#### クラウド環境の指定(`remoteEnvId`)
|
|
273
|
+
|
|
274
|
+
`--cloud` 実行時に `claude --environment <id>` へ渡す環境ID。指定しない場合の選択は claude CLI に任せる(`~/.claude/settings.json` の `remote.defaultEnvironmentId` → アカウントの最初の `anthropic_cloud` 環境 → 無ければ自動作成)。ID は claude.ai の環境設定、または `/remote-env` で確認できる。自己ホスト環境(`ccpool_...`)も同じキーに書ける。
|
|
275
|
+
|
|
276
|
+
```json
|
|
277
|
+
{ "remoteEnvId": "env_xxxxxxxx" }
|
|
278
|
+
```
|
|
279
|
+
|
|
265
280
|
#### ワーカーごとの設定
|
|
266
281
|
|
|
267
282
|
未指定のワーカー・フィールドは既定値にフォールバックする。
|
package/dist/index.js
CHANGED
|
@@ -1907,11 +1907,13 @@ function checkCloudConfig(input) {
|
|
|
1907
1907
|
}
|
|
1908
1908
|
var DEFAULT_CONFIG = {
|
|
1909
1909
|
fixReviewPointCallbackCommentMessage: "",
|
|
1910
|
+
remoteEnvId: null,
|
|
1910
1911
|
uiDesign: { ...DEFAULT_UI_DESIGN_CONFIG },
|
|
1911
1912
|
lastRun: {},
|
|
1912
1913
|
workers: {}
|
|
1913
1914
|
};
|
|
1914
1915
|
var CONFIG_PATH = join(process.cwd(), "claude-task-worker.json");
|
|
1916
|
+
var LOCAL_CONFIG_PATH = join(process.cwd(), "claude-task-worker.local.json");
|
|
1915
1917
|
function defaultsFor(name) {
|
|
1916
1918
|
return WORKER_DEFAULTS[name] ?? DEFAULT_WORKER_CONFIG;
|
|
1917
1919
|
}
|
|
@@ -2043,18 +2045,44 @@ function parseLastRunEntry(val) {
|
|
|
2043
2045
|
}
|
|
2044
2046
|
return result;
|
|
2045
2047
|
}
|
|
2046
|
-
function
|
|
2047
|
-
|
|
2048
|
-
|
|
2048
|
+
function isPlainObject(val) {
|
|
2049
|
+
return typeof val === "object" && val !== null && !Array.isArray(val);
|
|
2050
|
+
}
|
|
2051
|
+
function mergeConfigRaw(base, local) {
|
|
2052
|
+
const result = { ...base };
|
|
2053
|
+
for (const [key, val] of Object.entries(local)) {
|
|
2054
|
+
const current = result[key];
|
|
2055
|
+
result[key] = isPlainObject(current) && isPlainObject(val) ? mergeConfigRaw(current, val) : val;
|
|
2056
|
+
}
|
|
2057
|
+
return result;
|
|
2058
|
+
}
|
|
2059
|
+
function readRawConfig(path2) {
|
|
2060
|
+
let parsed;
|
|
2049
2061
|
try {
|
|
2050
|
-
|
|
2062
|
+
parsed = JSON.parse(readFileSync(path2, "utf-8"));
|
|
2051
2063
|
} catch (err) {
|
|
2052
|
-
if (err.code === "ENOENT") {
|
|
2053
|
-
return { ...DEFAULT_CONFIG, uiDesign: { ...DEFAULT_UI_DESIGN_CONFIG }, lastRun: {}, workers: {} };
|
|
2054
|
-
}
|
|
2064
|
+
if (err.code === "ENOENT") return {};
|
|
2055
2065
|
throw err;
|
|
2056
2066
|
}
|
|
2067
|
+
if (!isPlainObject(parsed)) {
|
|
2068
|
+
console.warn(`[config] invalid ${path2}: expected object, ignoring`);
|
|
2069
|
+
return {};
|
|
2070
|
+
}
|
|
2071
|
+
return parsed;
|
|
2072
|
+
}
|
|
2073
|
+
function loadConfig() {
|
|
2074
|
+
const raw = mergeConfigRaw(readRawConfig(CONFIG_PATH), readRawConfig(LOCAL_CONFIG_PATH));
|
|
2057
2075
|
const result = { ...DEFAULT_CONFIG, uiDesign: { ...DEFAULT_UI_DESIGN_CONFIG }, lastRun: {}, workers: {} };
|
|
2076
|
+
if ("remoteEnvId" in raw) {
|
|
2077
|
+
const val = raw["remoteEnvId"];
|
|
2078
|
+
if (val === null) {
|
|
2079
|
+
result.remoteEnvId = null;
|
|
2080
|
+
} else if (typeof val === "string" && val.trim().length > 0) {
|
|
2081
|
+
result.remoteEnvId = val.trim();
|
|
2082
|
+
} else {
|
|
2083
|
+
console.warn(`[config] invalid remoteEnvId: ${String(val)}, using default null`);
|
|
2084
|
+
}
|
|
2085
|
+
}
|
|
2058
2086
|
if ("lastRun" in raw) {
|
|
2059
2087
|
result.lastRun = parseLastRunEntry(raw["lastRun"]);
|
|
2060
2088
|
}
|
|
@@ -2114,6 +2142,14 @@ function writeLastRun(repoRoot, workerName, at = /* @__PURE__ */ new Date()) {
|
|
|
2114
2142
|
writeFileSync(path2, `${JSON.stringify(raw, null, 2)}
|
|
2115
2143
|
`, "utf-8");
|
|
2116
2144
|
}
|
|
2145
|
+
function getRemoteEnvId() {
|
|
2146
|
+
try {
|
|
2147
|
+
return loadConfig().remoteEnvId;
|
|
2148
|
+
} catch (err) {
|
|
2149
|
+
console.warn(`[config] failed to load remoteEnvId, not passing --environment: ${err}`);
|
|
2150
|
+
return null;
|
|
2151
|
+
}
|
|
2152
|
+
}
|
|
2117
2153
|
function getUiDesignConfig() {
|
|
2118
2154
|
try {
|
|
2119
2155
|
return loadConfig().uiDesign;
|
|
@@ -2177,7 +2213,7 @@ function parseConfigFile(path2) {
|
|
|
2177
2213
|
throw err;
|
|
2178
2214
|
}
|
|
2179
2215
|
}
|
|
2180
|
-
function
|
|
2216
|
+
function readRawConfig2() {
|
|
2181
2217
|
return parseConfigFile(getUserConfigPath());
|
|
2182
2218
|
}
|
|
2183
2219
|
function parseMode(raw, path2) {
|
|
@@ -2203,7 +2239,7 @@ function parsePermission(raw, path2) {
|
|
|
2203
2239
|
}
|
|
2204
2240
|
function loadUserConfig() {
|
|
2205
2241
|
const path2 = getUserConfigPath();
|
|
2206
|
-
const raw =
|
|
2242
|
+
const raw = readRawConfig2();
|
|
2207
2243
|
if (raw === void 0) {
|
|
2208
2244
|
throw new UserConfigError(`config.json not found: ${path2}`);
|
|
2209
2245
|
}
|
|
@@ -2295,7 +2331,7 @@ function getPermissionMode() {
|
|
|
2295
2331
|
function readTopLevel(parse, fallback, label) {
|
|
2296
2332
|
let raw;
|
|
2297
2333
|
try {
|
|
2298
|
-
raw =
|
|
2334
|
+
raw = readRawConfig2();
|
|
2299
2335
|
} catch (err) {
|
|
2300
2336
|
console.warn(`[config] failed to read config file, using default ${label}: ${err}`);
|
|
2301
2337
|
return fallback;
|
|
@@ -2445,6 +2481,7 @@ function buildClaudeArgs({
|
|
|
2445
2481
|
advisorModel,
|
|
2446
2482
|
permissionMode,
|
|
2447
2483
|
cloud,
|
|
2484
|
+
remoteEnvId,
|
|
2448
2485
|
baseRef,
|
|
2449
2486
|
onBranch
|
|
2450
2487
|
}) {
|
|
@@ -2454,6 +2491,7 @@ function buildClaudeArgs({
|
|
|
2454
2491
|
throw new Error("--on-branch and --ref both set the cloud session's base branch; pass one or the other");
|
|
2455
2492
|
}
|
|
2456
2493
|
const advisor = advisorModel?.trim() ?? "";
|
|
2494
|
+
const remoteEnv = remoteEnvId?.trim() ?? "";
|
|
2457
2495
|
const permission = permissionMode ?? DEFAULT_PERMISSION_MODE;
|
|
2458
2496
|
return [
|
|
2459
2497
|
// default モードはプロンプトを引数で渡す(print モード)。herdr モードでは渡さない:
|
|
@@ -2477,6 +2515,9 @@ function buildClaudeArgs({
|
|
|
2477
2515
|
// advisor 未指定(空文字)ならフラグごと省く。値なしの `--advisor` を渡すと
|
|
2478
2516
|
// 後続フラグを値として食われるため、必ずモデル名とセットでのみ付ける。
|
|
2479
2517
|
...advisor === "" ? [] : ["--advisor", advisor],
|
|
2518
|
+
// クラウド環境の指名。値なしの `--environment` は後続フラグを値として食うため、
|
|
2519
|
+
// `--advisor` と同じく ID とセットでのみ付ける。
|
|
2520
|
+
...cloud === true && remoteEnv !== "" ? ["--environment", remoteEnv] : [],
|
|
2480
2521
|
// クラウド実行時は「作成コマンドの共通フラグ」だけをここで返す。`--cloud` 自体は
|
|
2481
2522
|
// 付けない(値として渡す description(=クラウドセッションの初期プロンプト。
|
|
2482
2523
|
// appendCloudDoneInstruction() 適用後のタスクプロンプトそのもの)は
|
|
@@ -3790,7 +3831,7 @@ function createIssuePollingWorker(config) {
|
|
|
3790
3831
|
// config.json の advisor が false なら advisorModel の指定に関わらず渡さない。
|
|
3791
3832
|
advisorModel: isAdvisorEnabled() ? advisorModel : "",
|
|
3792
3833
|
permissionMode: getPermissionMode(),
|
|
3793
|
-
...cloud ? { cloud: true, baseRef: baseBranch } : {}
|
|
3834
|
+
...cloud ? { cloud: true, baseRef: baseBranch, remoteEnvId: getRemoteEnvId() ?? "" } : {}
|
|
3794
3835
|
});
|
|
3795
3836
|
let cwd;
|
|
3796
3837
|
if (cloud) {
|
|
@@ -4058,6 +4099,7 @@ function createPrPollingWorker(config) {
|
|
|
4058
4099
|
advisorModel: isAdvisorEnabled() ? advisorModel : "",
|
|
4059
4100
|
permissionMode: getPermissionMode(),
|
|
4060
4101
|
cloud: isCloud,
|
|
4102
|
+
remoteEnvId: isCloud ? getRemoteEnvId() ?? "" : void 0,
|
|
4061
4103
|
onBranch: isCloud ? pr.headRefName : void 0
|
|
4062
4104
|
});
|
|
4063
4105
|
if (isCloud) {
|
|
@@ -4664,7 +4706,7 @@ function createScheduledWorker(config) {
|
|
|
4664
4706
|
effort,
|
|
4665
4707
|
advisorModel: isAdvisorEnabled() ? advisorModel : "",
|
|
4666
4708
|
permissionMode: getPermissionMode(),
|
|
4667
|
-
...cloud ? { cloud: true, baseRef: defaultBranch } : {}
|
|
4709
|
+
...cloud ? { cloud: true, baseRef: defaultBranch, remoteEnvId: getRemoteEnvId() ?? "" } : {}
|
|
4668
4710
|
});
|
|
4669
4711
|
await publishLastRunPr(config.name, defaultBranch, new Date(now)).catch(
|
|
4670
4712
|
(err) => console.error(`[${config.name}] publishLastRunPr failed: ${err}`)
|
|
@@ -4752,7 +4794,8 @@ var updateDesignMdWorker = createScheduledWorker({
|
|
|
4752
4794
|
init_table();
|
|
4753
4795
|
|
|
4754
4796
|
// src/commands/init.ts
|
|
4755
|
-
import { mkdir as mkdir2, writeFile as writeFile2, access } from "node:fs/promises";
|
|
4797
|
+
import { mkdir as mkdir2, readFile as readFile2, writeFile as writeFile2, access } from "node:fs/promises";
|
|
4798
|
+
import { basename as basename3 } from "node:path";
|
|
4756
4799
|
|
|
4757
4800
|
// src/commands/codegraph.ts
|
|
4758
4801
|
import { mkdir, readFile, writeFile } from "node:fs/promises";
|
|
@@ -4941,6 +4984,22 @@ async function createConfig(force) {
|
|
|
4941
4984
|
const result = await writeFileWithMode(CONFIG_PATH, JSON.stringify(initialConfig, null, 2), force);
|
|
4942
4985
|
logWriteResult(result, CONFIG_PATH);
|
|
4943
4986
|
}
|
|
4987
|
+
async function ensureLocalConfigGitIgnore() {
|
|
4988
|
+
const entry = basename3(LOCAL_CONFIG_PATH);
|
|
4989
|
+
const path2 = ".gitignore";
|
|
4990
|
+
let current = "";
|
|
4991
|
+
try {
|
|
4992
|
+
current = await readFile2(path2, "utf-8");
|
|
4993
|
+
} catch {
|
|
4994
|
+
}
|
|
4995
|
+
const next = appendIgnoreEntry(current, entry);
|
|
4996
|
+
if (next === null) {
|
|
4997
|
+
console.log(`[init] Already ignored: ${entry} (${path2})`);
|
|
4998
|
+
return;
|
|
4999
|
+
}
|
|
5000
|
+
await writeFile2(path2, next, "utf-8");
|
|
5001
|
+
console.log(`[init] Added ${entry} to ${path2}`);
|
|
5002
|
+
}
|
|
4944
5003
|
async function init(options = {}) {
|
|
4945
5004
|
const force = options.force ?? false;
|
|
4946
5005
|
console.log(`[init] Creating labels...${force ? " (force mode)" : ""}`);
|
|
@@ -4962,6 +5021,7 @@ async function init(options = {}) {
|
|
|
4962
5021
|
logWriteResult(await writeFileWithMode(workflowPath, ASSIGN_CREATOR_WORKFLOW, force), workflowPath);
|
|
4963
5022
|
console.log("[init] Creating config file...");
|
|
4964
5023
|
await createConfig(force);
|
|
5024
|
+
await ensureLocalConfigGitIgnore();
|
|
4965
5025
|
console.log("[init] Setting up CodeGraph...");
|
|
4966
5026
|
await ensureCodegraphGitIgnore("init");
|
|
4967
5027
|
await runCodegraphInit("init");
|
|
@@ -5123,7 +5183,7 @@ async function install() {
|
|
|
5123
5183
|
}
|
|
5124
5184
|
|
|
5125
5185
|
// src/commands/cloud-setup.ts
|
|
5126
|
-
import { mkdir as mkdir3, writeFile as writeFile3, readFile as
|
|
5186
|
+
import { mkdir as mkdir3, writeFile as writeFile3, readFile as readFile3 } from "node:fs/promises";
|
|
5127
5187
|
import { homedir as homedir6 } from "node:os";
|
|
5128
5188
|
import { join as join8 } from "node:path";
|
|
5129
5189
|
var LOG_PREFIX = "cloud-setup";
|
|
@@ -5164,7 +5224,7 @@ async function writeClaudeSettings(force) {
|
|
|
5164
5224
|
const path2 = claudeSettingsPath();
|
|
5165
5225
|
let existing;
|
|
5166
5226
|
try {
|
|
5167
|
-
existing = await
|
|
5227
|
+
existing = await readFile3(path2, "utf-8");
|
|
5168
5228
|
} catch {
|
|
5169
5229
|
existing = null;
|
|
5170
5230
|
}
|