@pleaseai/work 0.1.4 → 0.1.6
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 +22 -1
- package/dist/index.js +153 -18
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -165,6 +165,7 @@ agent:
|
|
|
165
165
|
|
|
166
166
|
claude:
|
|
167
167
|
permission_mode: acceptEdits
|
|
168
|
+
# setting_sources: [] # default: [project, local, user]; set [] for SDK isolation mode
|
|
168
169
|
turn_timeout_ms: 3600000
|
|
169
170
|
---
|
|
170
171
|
|
|
@@ -224,6 +225,7 @@ agent:
|
|
|
224
225
|
|
|
225
226
|
claude:
|
|
226
227
|
permission_mode: acceptEdits
|
|
228
|
+
# setting_sources: [] # default: [project, local, user]; set [] for SDK isolation mode
|
|
227
229
|
turn_timeout_ms: 3600000
|
|
228
230
|
---
|
|
229
231
|
|
|
@@ -287,6 +289,7 @@ agent:
|
|
|
287
289
|
|
|
288
290
|
claude:
|
|
289
291
|
permission_mode: acceptEdits
|
|
292
|
+
# setting_sources: [] # default: [project, local, user]; set [] for SDK isolation mode
|
|
290
293
|
turn_timeout_ms: 3600000
|
|
291
294
|
---
|
|
292
295
|
|
|
@@ -394,9 +397,18 @@ claude:
|
|
|
394
397
|
- Read
|
|
395
398
|
- Write
|
|
396
399
|
- Bash
|
|
400
|
+
setting_sources: # Optional: filesystem settings to load. Default: [project, local, user]
|
|
401
|
+
- project # load .claude/settings.json + CLAUDE.md from the workspace directory
|
|
402
|
+
- local # load .claude/settings.local.json from the workspace directory
|
|
403
|
+
- user # load ~/.claude/settings.json + global CLAUDE.md
|
|
404
|
+
# Only "project", "local", and "user" are valid — other values are ignored
|
|
397
405
|
turn_timeout_ms: 3600000 # Optional: per-turn timeout in ms, default 3600000
|
|
398
406
|
read_timeout_ms: 5000 # Optional: initial subprocess read timeout in ms, default 5000
|
|
399
407
|
stall_timeout_ms: 300000 # Optional: stall detection timeout, default 300000
|
|
408
|
+
settings:
|
|
409
|
+
attribution:
|
|
410
|
+
commit: "🙏 Generated with [Work Please](https://github.com/pleaseai/work-please)" # Optional: appended to git commit messages. Defaults to Work Please link.
|
|
411
|
+
pr: "🙏 Generated with [Work Please](https://github.com/pleaseai/work-please)" # Optional: appended to PR descriptions. Defaults to Work Please link.
|
|
400
412
|
|
|
401
413
|
server:
|
|
402
414
|
port: 3000 # Optional: enable HTTP dashboard on this port
|
|
@@ -410,9 +422,10 @@ Your prompt template goes here. Available variables:
|
|
|
410
422
|
- {{ issue.description }} — Issue body/description
|
|
411
423
|
- {{ issue.state }} — Current tracker state name
|
|
412
424
|
- {{ issue.url }} — Issue URL
|
|
413
|
-
- {{ issue.
|
|
425
|
+
- {{ issue.assignees }} — Array of assignee logins (GitHub) or emails (Asana)
|
|
414
426
|
- {{ issue.labels }} — Array of label strings (normalized to lowercase)
|
|
415
427
|
- {{ issue.blocked_by }} — Array of blocker refs (each has id, identifier, state)
|
|
428
|
+
- {{ issue.pull_requests }} — Array of linked PRs (each has number, title, url, state, branch_name)
|
|
416
429
|
- {{ issue.priority }} — Numeric priority or null
|
|
417
430
|
- {{ issue.created_at }} — ISO-8601 creation timestamp
|
|
418
431
|
- {{ issue.updated_at }} — ISO-8601 last-updated timestamp
|
|
@@ -437,6 +450,14 @@ Blocked by:
|
|
|
437
450
|
{% endfor %}
|
|
438
451
|
{% endif %}
|
|
439
452
|
|
|
453
|
+
{% if issue.pull_requests.size > 0 %}
|
|
454
|
+
Linked pull requests:
|
|
455
|
+
{% for pr in issue.pull_requests %}
|
|
456
|
+
- PR #{{ pr.number }}: {{ pr.title }} ({{ pr.state }}){% if pr.branch_name %} — branch: {{ pr.branch_name }}{% endif %}{% if pr.url %} — {{ pr.url }}{% endif %}
|
|
457
|
+
|
|
458
|
+
{% endfor %}
|
|
459
|
+
{% endif %}
|
|
460
|
+
|
|
440
461
|
{% if attempt %}
|
|
441
462
|
Retry attempt: {{ attempt }}
|
|
442
463
|
{% endif %}
|
package/dist/index.js
CHANGED
|
@@ -2166,7 +2166,7 @@ var {
|
|
|
2166
2166
|
var package_default = {
|
|
2167
2167
|
name: "@pleaseai/work",
|
|
2168
2168
|
type: "module",
|
|
2169
|
-
version: "0.1.
|
|
2169
|
+
version: "0.1.6",
|
|
2170
2170
|
description: "Symphony-spec orchestrator for Claude Code + Asana/GitHub Projects v2",
|
|
2171
2171
|
license: "FSL-1.1-MIT",
|
|
2172
2172
|
repository: {
|
|
@@ -3088,6 +3088,13 @@ agent:
|
|
|
3088
3088
|
max_turns: 20
|
|
3089
3089
|
claude:
|
|
3090
3090
|
permission_mode: bypassPermissions
|
|
3091
|
+
# claude.settings controls the attribution text written into .claude/settings.local.json
|
|
3092
|
+
# of each workspace. Omit to use the default Work Please attribution.
|
|
3093
|
+
# claude:
|
|
3094
|
+
# settings:
|
|
3095
|
+
# attribution:
|
|
3096
|
+
# commit: "\uD83D\uDE4F Generated with Work Please"
|
|
3097
|
+
# pr: "\uD83D\uDE4F Generated with Work Please"
|
|
3091
3098
|
# server:
|
|
3092
3099
|
# port: 3000
|
|
3093
3100
|
---
|
|
@@ -31679,7 +31686,11 @@ function createToolsMcpServer(config2) {
|
|
|
31679
31686
|
}
|
|
31680
31687
|
|
|
31681
31688
|
// src/agent-runner.ts
|
|
31689
|
+
var UUID_PATTERN = /^[\da-f]{8}-[\da-f]{4}-[\da-f]{4}-[\da-f]{4}-[\da-f]{12}$/i;
|
|
31690
|
+
var NEWLINE_PATTERN = /[\r\n]/g;
|
|
31691
|
+
|
|
31682
31692
|
class AppServerClient {
|
|
31693
|
+
assignedSessionId = null;
|
|
31683
31694
|
sessionId = null;
|
|
31684
31695
|
abortController = null;
|
|
31685
31696
|
workspace;
|
|
@@ -31690,11 +31701,20 @@ class AppServerClient {
|
|
|
31690
31701
|
this.workspace = workspace;
|
|
31691
31702
|
this.queryFn = queryFn;
|
|
31692
31703
|
}
|
|
31693
|
-
async startSession() {
|
|
31704
|
+
async startSession(sessionId) {
|
|
31705
|
+
this.assignedSessionId = null;
|
|
31706
|
+
this.sessionId = null;
|
|
31707
|
+
if (sessionId !== undefined && !UUID_PATTERN.test(sessionId)) {
|
|
31708
|
+
const preview = String(sessionId).slice(0, 64).replace(NEWLINE_PATTERN, " ");
|
|
31709
|
+
return new Error(`invalid_session_id: expected UUID format, got "${preview}"`);
|
|
31710
|
+
}
|
|
31694
31711
|
const validationErr = this.validateWorkspaceCwd();
|
|
31695
31712
|
if (validationErr)
|
|
31696
31713
|
return validationErr;
|
|
31697
|
-
|
|
31714
|
+
const id = sessionId ?? randomUUID();
|
|
31715
|
+
this.assignedSessionId = id;
|
|
31716
|
+
this.sessionId = sessionId ?? null;
|
|
31717
|
+
return { sessionId: id, workspace: this.workspace };
|
|
31698
31718
|
}
|
|
31699
31719
|
async runTurn(session, prompt, _issue, onMessage) {
|
|
31700
31720
|
const controller = new AbortController;
|
|
@@ -31713,16 +31733,30 @@ class AppServerClient {
|
|
|
31713
31733
|
}
|
|
31714
31734
|
if (this.sessionId) {
|
|
31715
31735
|
options.resume = this.sessionId;
|
|
31736
|
+
} else if (this.assignedSessionId) {
|
|
31737
|
+
options.sessionId = this.assignedSessionId;
|
|
31716
31738
|
}
|
|
31717
31739
|
if (this.config.claude.command !== "claude") {
|
|
31718
31740
|
options.pathToClaudeCodeExecutable = this.config.claude.command;
|
|
31719
31741
|
}
|
|
31742
|
+
if (this.config.claude.model) {
|
|
31743
|
+
options.model = this.config.claude.model;
|
|
31744
|
+
}
|
|
31745
|
+
const sp = this.config.claude.system_prompt;
|
|
31746
|
+
if (sp.type === "custom") {
|
|
31747
|
+
options.systemPrompt = sp.value;
|
|
31748
|
+
} else {
|
|
31749
|
+
options.systemPrompt = sp;
|
|
31750
|
+
}
|
|
31720
31751
|
const toolSpecs = getToolSpecs(this.config);
|
|
31721
31752
|
if (toolSpecs.length > 0) {
|
|
31722
31753
|
options.mcpServers = {
|
|
31723
31754
|
"work-please-tools": createToolsMcpServer(this.config)
|
|
31724
31755
|
};
|
|
31725
31756
|
}
|
|
31757
|
+
if (this.config.claude.setting_sources.length > 0) {
|
|
31758
|
+
options.settingSources = this.config.claude.setting_sources;
|
|
31759
|
+
}
|
|
31726
31760
|
const turnId = randomUUID();
|
|
31727
31761
|
let sessionId = null;
|
|
31728
31762
|
let gotError = false;
|
|
@@ -31734,11 +31768,11 @@ class AppServerClient {
|
|
|
31734
31768
|
const initMsg = msg;
|
|
31735
31769
|
sessionId = initMsg.session_id;
|
|
31736
31770
|
this.sessionId = sessionId;
|
|
31771
|
+
this.assignedSessionId = null;
|
|
31737
31772
|
onMessage({
|
|
31738
31773
|
event: "session_started",
|
|
31739
31774
|
timestamp: new Date,
|
|
31740
31775
|
session_id: sessionId,
|
|
31741
|
-
thread_id: session.threadId,
|
|
31742
31776
|
turn_id: turnId
|
|
31743
31777
|
});
|
|
31744
31778
|
} else if (msg.type === "result") {
|
|
@@ -31791,12 +31825,18 @@ class AppServerClient {
|
|
|
31791
31825
|
});
|
|
31792
31826
|
return err;
|
|
31793
31827
|
}
|
|
31794
|
-
return {
|
|
31828
|
+
return { turn_id: turnId, session_id: sessionId };
|
|
31795
31829
|
} catch (err) {
|
|
31796
31830
|
clearTimeout(timeoutHandle);
|
|
31797
31831
|
const error48 = err instanceof Error ? err : new Error(String(err));
|
|
31832
|
+
if (!sessionId) {
|
|
31833
|
+
if (!options.resume) {
|
|
31834
|
+
this.sessionId = null;
|
|
31835
|
+
this.assignedSessionId = null;
|
|
31836
|
+
}
|
|
31837
|
+
}
|
|
31798
31838
|
onMessage({
|
|
31799
|
-
event: "startup_failed",
|
|
31839
|
+
event: sessionId ? "turn_failed" : "startup_failed",
|
|
31800
31840
|
timestamp: new Date,
|
|
31801
31841
|
payload: { reason: error48.message }
|
|
31802
31842
|
});
|
|
@@ -31805,6 +31845,7 @@ class AppServerClient {
|
|
|
31805
31845
|
}
|
|
31806
31846
|
stopSession() {
|
|
31807
31847
|
this.abortController?.abort();
|
|
31848
|
+
this.assignedSessionId = null;
|
|
31808
31849
|
this.sessionId = null;
|
|
31809
31850
|
this.abortController = null;
|
|
31810
31851
|
}
|
|
@@ -31825,6 +31866,7 @@ import { tmpdir } from "os";
|
|
|
31825
31866
|
import { join, sep as sep2 } from "path";
|
|
31826
31867
|
import process4 from "process";
|
|
31827
31868
|
var ENV_VAR_RE = /^\$([A-Z_]\w*)$/i;
|
|
31869
|
+
var VALID_SETTING_SOURCES = new Set(["user", "project", "local"]);
|
|
31828
31870
|
var DEFAULTS2 = {
|
|
31829
31871
|
POLL_INTERVAL_MS: 30000,
|
|
31830
31872
|
WORKSPACE_ROOT: join(tmpdir(), "work-please_workspaces"),
|
|
@@ -31835,6 +31877,7 @@ var DEFAULTS2 = {
|
|
|
31835
31877
|
CLAUDE_COMMAND: "claude",
|
|
31836
31878
|
CLAUDE_PERMISSION_MODE: "bypassPermissions",
|
|
31837
31879
|
CLAUDE_ALLOWED_TOOLS: [],
|
|
31880
|
+
CLAUDE_SETTING_SOURCES: ["project", "local", "user"],
|
|
31838
31881
|
CLAUDE_TURN_TIMEOUT_MS: 3600000,
|
|
31839
31882
|
CLAUDE_READ_TIMEOUT_MS: 5000,
|
|
31840
31883
|
CLAUDE_STALL_TIMEOUT_MS: 300000,
|
|
@@ -31876,19 +31919,33 @@ function buildConfig(workflow) {
|
|
|
31876
31919
|
max_retry_backoff_ms: posIntValue(agent.max_retry_backoff_ms, DEFAULTS2.MAX_RETRY_BACKOFF_MS),
|
|
31877
31920
|
max_concurrent_agents_by_state: stateLimitsValue(agent.max_concurrent_agents_by_state)
|
|
31878
31921
|
},
|
|
31879
|
-
claude:
|
|
31880
|
-
command: commandValue(claude.command) ?? DEFAULTS2.CLAUDE_COMMAND,
|
|
31881
|
-
permission_mode: stringValue(claude.permission_mode) ?? DEFAULTS2.CLAUDE_PERMISSION_MODE,
|
|
31882
|
-
allowed_tools: stringArrayValue(claude.allowed_tools, DEFAULTS2.CLAUDE_ALLOWED_TOOLS),
|
|
31883
|
-
turn_timeout_ms: intValue(claude.turn_timeout_ms, DEFAULTS2.CLAUDE_TURN_TIMEOUT_MS),
|
|
31884
|
-
read_timeout_ms: intValue(claude.read_timeout_ms, DEFAULTS2.CLAUDE_READ_TIMEOUT_MS),
|
|
31885
|
-
stall_timeout_ms: intValue(claude.stall_timeout_ms, DEFAULTS2.CLAUDE_STALL_TIMEOUT_MS)
|
|
31886
|
-
},
|
|
31922
|
+
claude: buildClaudeConfig(claude),
|
|
31887
31923
|
server: {
|
|
31888
31924
|
port: nonNegIntOrNull(server.port)
|
|
31889
31925
|
}
|
|
31890
31926
|
};
|
|
31891
31927
|
}
|
|
31928
|
+
function buildClaudeConfig(claude) {
|
|
31929
|
+
const settingsSec = sectionMap(claude, "settings");
|
|
31930
|
+
const attributionSec = sectionMap(settingsSec, "attribution");
|
|
31931
|
+
return {
|
|
31932
|
+
model: stringValue(claude.model),
|
|
31933
|
+
command: commandValue(claude.command) ?? DEFAULTS2.CLAUDE_COMMAND,
|
|
31934
|
+
permission_mode: stringValue(claude.permission_mode) ?? DEFAULTS2.CLAUDE_PERMISSION_MODE,
|
|
31935
|
+
allowed_tools: stringArrayValue(claude.allowed_tools, DEFAULTS2.CLAUDE_ALLOWED_TOOLS),
|
|
31936
|
+
setting_sources: stringArrayValue(claude.setting_sources, DEFAULTS2.CLAUDE_SETTING_SOURCES).filter((s2) => VALID_SETTING_SOURCES.has(s2)),
|
|
31937
|
+
turn_timeout_ms: intValue(claude.turn_timeout_ms, DEFAULTS2.CLAUDE_TURN_TIMEOUT_MS),
|
|
31938
|
+
read_timeout_ms: intValue(claude.read_timeout_ms, DEFAULTS2.CLAUDE_READ_TIMEOUT_MS),
|
|
31939
|
+
stall_timeout_ms: intValue(claude.stall_timeout_ms, DEFAULTS2.CLAUDE_STALL_TIMEOUT_MS),
|
|
31940
|
+
system_prompt: systemPromptValue(claude.system_prompt),
|
|
31941
|
+
settings: {
|
|
31942
|
+
attribution: {
|
|
31943
|
+
commit: stringValue(attributionSec.commit),
|
|
31944
|
+
pr: stringValue(attributionSec.pr)
|
|
31945
|
+
}
|
|
31946
|
+
}
|
|
31947
|
+
};
|
|
31948
|
+
}
|
|
31892
31949
|
function buildTrackerConfig(kind, tracker) {
|
|
31893
31950
|
const label_prefix = stringValue(tracker.label_prefix) ?? null;
|
|
31894
31951
|
const filter = buildFilterConfig(sectionMap(tracker, "filter"));
|
|
@@ -32002,6 +32059,26 @@ function maxConcurrentForState(config2, state) {
|
|
|
32002
32059
|
const byState = config2.agent.max_concurrent_agents_by_state;
|
|
32003
32060
|
return byState[normalized] ?? config2.agent.max_concurrent_agents;
|
|
32004
32061
|
}
|
|
32062
|
+
var DEFAULT_SYSTEM_PROMPT = { type: "preset", preset: "claude_code" };
|
|
32063
|
+
function systemPromptValue(val) {
|
|
32064
|
+
if (val == null)
|
|
32065
|
+
return DEFAULT_SYSTEM_PROMPT;
|
|
32066
|
+
if (typeof val === "string") {
|
|
32067
|
+
const trimmed = val.trim();
|
|
32068
|
+
return trimmed ? { type: "custom", value: trimmed } : DEFAULT_SYSTEM_PROMPT;
|
|
32069
|
+
}
|
|
32070
|
+
if (typeof val === "object" && !Array.isArray(val)) {
|
|
32071
|
+
const obj = val;
|
|
32072
|
+
if (obj.type === "preset" && obj.preset === "claude_code") {
|
|
32073
|
+
return typeof obj.append === "string" ? { type: "preset", preset: "claude_code", append: obj.append } : { type: "preset", preset: "claude_code" };
|
|
32074
|
+
}
|
|
32075
|
+
if (obj.type === "custom" && typeof obj.value === "string") {
|
|
32076
|
+
const trimmed = obj.value.trim();
|
|
32077
|
+
return trimmed ? { type: "custom", value: trimmed } : DEFAULT_SYSTEM_PROMPT;
|
|
32078
|
+
}
|
|
32079
|
+
}
|
|
32080
|
+
return DEFAULT_SYSTEM_PROMPT;
|
|
32081
|
+
}
|
|
32005
32082
|
function sectionMap(raw, key) {
|
|
32006
32083
|
const val = raw[key];
|
|
32007
32084
|
return val && typeof val === "object" && !Array.isArray(val) ? val : {};
|
|
@@ -32066,7 +32143,7 @@ function csvValue(val) {
|
|
|
32066
32143
|
function stringArrayValue(val, fallback) {
|
|
32067
32144
|
if (!Array.isArray(val))
|
|
32068
32145
|
return fallback;
|
|
32069
|
-
return val.filter((v) => typeof v === "string");
|
|
32146
|
+
return val.filter((v) => typeof v === "string" && v.trim().length > 0);
|
|
32070
32147
|
}
|
|
32071
32148
|
function stateLimitsValue(val) {
|
|
32072
32149
|
if (!val || typeof val !== "object" || Array.isArray(val))
|
|
@@ -36929,6 +37006,7 @@ function issueToTemplateVars(issue2) {
|
|
|
36929
37006
|
url: issue2.url,
|
|
36930
37007
|
labels: issue2.labels,
|
|
36931
37008
|
blocked_by: issue2.blocked_by,
|
|
37009
|
+
pull_requests: issue2.pull_requests,
|
|
36932
37010
|
created_at: issue2.created_at?.toISOString() ?? null,
|
|
36933
37011
|
updated_at: issue2.updated_at?.toISOString() ?? null
|
|
36934
37012
|
};
|
|
@@ -37091,6 +37169,7 @@ function createAsanaAdapter(config2) {
|
|
|
37091
37169
|
assignees: [],
|
|
37092
37170
|
labels: [],
|
|
37093
37171
|
blocked_by: [],
|
|
37172
|
+
pull_requests: [],
|
|
37094
37173
|
created_at: null,
|
|
37095
37174
|
updated_at: null
|
|
37096
37175
|
});
|
|
@@ -37121,6 +37200,7 @@ function normalizeAsanaTask(task, sectionName) {
|
|
|
37121
37200
|
assignees,
|
|
37122
37201
|
labels,
|
|
37123
37202
|
blocked_by: blockedBy,
|
|
37203
|
+
pull_requests: [],
|
|
37124
37204
|
created_at: task.created_at ? new Date(String(task.created_at)) : null,
|
|
37125
37205
|
updated_at: task.modified_at ? new Date(String(task.modified_at)) : null
|
|
37126
37206
|
};
|
|
@@ -37184,12 +37264,16 @@ function createGitHubAdapter(config2) {
|
|
|
37184
37264
|
labels(first: 20) { nodes { name } }
|
|
37185
37265
|
assignees(first: 10) { nodes { login } }
|
|
37186
37266
|
createdAt updatedAt
|
|
37267
|
+
closedByPullRequestsReferences(first: 10, includeClosedPrs: true) {
|
|
37268
|
+
nodes { number title url state headRefName }
|
|
37269
|
+
}
|
|
37187
37270
|
}
|
|
37188
37271
|
... on PullRequest {
|
|
37189
37272
|
number title body url
|
|
37190
37273
|
labels(first: 20) { nodes { name } }
|
|
37191
37274
|
assignees(first: 10) { nodes { login } }
|
|
37192
37275
|
createdAt updatedAt
|
|
37276
|
+
headRefName
|
|
37193
37277
|
}
|
|
37194
37278
|
}
|
|
37195
37279
|
}
|
|
@@ -37216,12 +37300,16 @@ function createGitHubAdapter(config2) {
|
|
|
37216
37300
|
labels(first: 20) { nodes { name } }
|
|
37217
37301
|
assignees(first: 10) { nodes { login } }
|
|
37218
37302
|
createdAt updatedAt
|
|
37303
|
+
closedByPullRequestsReferences(first: 10, includeClosedPrs: true) {
|
|
37304
|
+
nodes { number title url state headRefName }
|
|
37305
|
+
}
|
|
37219
37306
|
}
|
|
37220
37307
|
... on PullRequest {
|
|
37221
37308
|
number title body url
|
|
37222
37309
|
labels(first: 20) { nodes { name } }
|
|
37223
37310
|
assignees(first: 10) { nodes { login } }
|
|
37224
37311
|
createdAt updatedAt
|
|
37312
|
+
headRefName
|
|
37225
37313
|
}
|
|
37226
37314
|
}
|
|
37227
37315
|
}
|
|
@@ -37253,12 +37341,16 @@ function createGitHubAdapter(config2) {
|
|
|
37253
37341
|
labels(first: 20) { nodes { name } }
|
|
37254
37342
|
assignees(first: 10) { nodes { login } }
|
|
37255
37343
|
createdAt updatedAt
|
|
37344
|
+
closedByPullRequestsReferences(first: 10, includeClosedPrs: true) {
|
|
37345
|
+
nodes { number title url state headRefName }
|
|
37346
|
+
}
|
|
37256
37347
|
}
|
|
37257
37348
|
... on PullRequest {
|
|
37258
37349
|
number title body url
|
|
37259
37350
|
labels(first: 20) { nodes { name } }
|
|
37260
37351
|
assignees(first: 10) { nodes { login } }
|
|
37261
37352
|
createdAt updatedAt
|
|
37353
|
+
headRefName
|
|
37262
37354
|
}
|
|
37263
37355
|
}
|
|
37264
37356
|
}
|
|
@@ -37386,6 +37478,10 @@ function buildQueryString(filter2) {
|
|
|
37386
37478
|
parts.push(`label:${filter2.label.join(",")}`);
|
|
37387
37479
|
return parts.join(" ");
|
|
37388
37480
|
}
|
|
37481
|
+
function normalizePrState(raw2) {
|
|
37482
|
+
const s2 = String(raw2 ?? "").toLowerCase();
|
|
37483
|
+
return s2 === "closed" || s2 === "merged" ? s2 : "open";
|
|
37484
|
+
}
|
|
37389
37485
|
function normalizeProjectItem(node, status) {
|
|
37390
37486
|
const content = node.content;
|
|
37391
37487
|
const number4 = content?.number;
|
|
@@ -37393,6 +37489,15 @@ function normalizeProjectItem(node, status) {
|
|
|
37393
37489
|
const labels = Array.isArray(content?.labels?.nodes) ? content.labels.nodes.map((l) => (l.name ?? "").toLowerCase()).filter(Boolean) : [];
|
|
37394
37490
|
const assigneeNodes = content?.assignees?.nodes;
|
|
37395
37491
|
const assignees = Array.isArray(assigneeNodes) ? assigneeNodes.map((n2) => n2.login ?? "").filter(Boolean) : [];
|
|
37492
|
+
const prRefNodes = content?.closedByPullRequestsReferences?.nodes;
|
|
37493
|
+
const pullRequests = Array.isArray(prRefNodes) ? prRefNodes.filter((pr) => pr !== null && typeof pr === "object" && typeof pr.number === "number" && pr.number > 0).map((pr) => ({
|
|
37494
|
+
number: pr.number,
|
|
37495
|
+
title: String(pr.title ?? ""),
|
|
37496
|
+
url: pr.url ? String(pr.url) : null,
|
|
37497
|
+
state: normalizePrState(pr.state),
|
|
37498
|
+
branch_name: pr.headRefName ? String(pr.headRefName) : null
|
|
37499
|
+
})) : [];
|
|
37500
|
+
const headRefName = content?.headRefName ? String(content.headRefName) : null;
|
|
37396
37501
|
return {
|
|
37397
37502
|
id: String(node.id ?? ""),
|
|
37398
37503
|
identifier,
|
|
@@ -37400,11 +37505,12 @@ function normalizeProjectItem(node, status) {
|
|
|
37400
37505
|
description: content?.body ? String(content.body) : null,
|
|
37401
37506
|
priority: null,
|
|
37402
37507
|
state: status,
|
|
37403
|
-
branch_name:
|
|
37508
|
+
branch_name: headRefName,
|
|
37404
37509
|
url: content?.url ? String(content.url) : null,
|
|
37405
37510
|
assignees,
|
|
37406
37511
|
labels,
|
|
37407
37512
|
blocked_by: [],
|
|
37513
|
+
pull_requests: pullRequests,
|
|
37408
37514
|
created_at: content?.createdAt ? new Date(String(content.createdAt)) : null,
|
|
37409
37515
|
updated_at: content?.updatedAt ? new Date(String(content.updatedAt)) : null
|
|
37410
37516
|
};
|
|
@@ -40140,9 +40246,28 @@ function isWorkflowError(result) {
|
|
|
40140
40246
|
}
|
|
40141
40247
|
|
|
40142
40248
|
// src/workspace.ts
|
|
40143
|
-
import { existsSync as existsSync4, lstatSync as lstatSync2, mkdirSync as mkdirSync2, rmSync as rmSync2, statSync as statSync3 } from "fs";
|
|
40144
|
-
import { join as join4, resolve as resolve4, sep as sep4 } from "path";
|
|
40249
|
+
import { existsSync as existsSync4, lstatSync as lstatSync2, mkdirSync as mkdirSync2, rmSync as rmSync2, statSync as statSync3, writeFileSync as writeFileSync2 } from "fs";
|
|
40250
|
+
import { dirname as dirname2, join as join4, resolve as resolve4, sep as sep4 } from "path";
|
|
40145
40251
|
import process6 from "process";
|
|
40252
|
+
var CLAUDE_SETTINGS_PATH = ".claude/settings.local.json";
|
|
40253
|
+
var WORK_PLEASE_URL = "https://github.com/pleaseai/work-please";
|
|
40254
|
+
var ATTRIBUTION_TEXT = `\uD83D\uDE4F Generated with [Work Please](${WORK_PLEASE_URL})`;
|
|
40255
|
+
function generateClaudeSettings(attribution) {
|
|
40256
|
+
return `${JSON.stringify({
|
|
40257
|
+
attribution: {
|
|
40258
|
+
commit: attribution?.commit ?? ATTRIBUTION_TEXT,
|
|
40259
|
+
pr: attribution?.pr ?? ATTRIBUTION_TEXT
|
|
40260
|
+
}
|
|
40261
|
+
}, null, 2)}
|
|
40262
|
+
`;
|
|
40263
|
+
}
|
|
40264
|
+
function ensureClaudeSettings(wsPath, attribution) {
|
|
40265
|
+
const settingsPath = join4(wsPath, CLAUDE_SETTINGS_PATH);
|
|
40266
|
+
if (existsSync4(settingsPath))
|
|
40267
|
+
return;
|
|
40268
|
+
mkdirSync2(dirname2(settingsPath), { recursive: true });
|
|
40269
|
+
writeFileSync2(settingsPath, generateClaudeSettings(attribution), "utf-8");
|
|
40270
|
+
}
|
|
40146
40271
|
var _git = {
|
|
40147
40272
|
spawnSync: (args) => Bun.spawnSync(args)
|
|
40148
40273
|
};
|
|
@@ -40275,6 +40400,11 @@ async function createWorkspace(config2, identifier, issue2) {
|
|
|
40275
40400
|
if (hookErr)
|
|
40276
40401
|
return hookErr;
|
|
40277
40402
|
}
|
|
40403
|
+
try {
|
|
40404
|
+
ensureClaudeSettings(wtPath, config2.claude.settings.attribution);
|
|
40405
|
+
} catch (err) {
|
|
40406
|
+
return err instanceof Error ? err : new Error(String(err));
|
|
40407
|
+
}
|
|
40278
40408
|
return { path: wtPath, workspace_key: key, created_now: createdNow };
|
|
40279
40409
|
}
|
|
40280
40410
|
}
|
|
@@ -40305,6 +40435,11 @@ async function createWorkspace(config2, identifier, issue2) {
|
|
|
40305
40435
|
if (hookErr)
|
|
40306
40436
|
return hookErr;
|
|
40307
40437
|
}
|
|
40438
|
+
try {
|
|
40439
|
+
ensureClaudeSettings(wsPath, config2.claude.settings.attribution);
|
|
40440
|
+
} catch (err) {
|
|
40441
|
+
return err instanceof Error ? err : new Error(String(err));
|
|
40442
|
+
}
|
|
40308
40443
|
return workspace;
|
|
40309
40444
|
}
|
|
40310
40445
|
async function removeWorkspace(config2, identifier, issue2) {
|