@workermill/agent 0.1.0 β†’ 0.1.2

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/dist/planner.js CHANGED
@@ -51,14 +51,22 @@ async function postProgress(taskId, phase, elapsedSeconds, detail, charsGenerate
51
51
  // Fire and forget
52
52
  }
53
53
  }
54
+ /** Consistent prefix matching local workermill dashboard format */
55
+ const PREFIX = "[πŸ—ΊοΈ planning_agent πŸ€–]";
56
+ /** Format elapsed seconds as human-readable string (e.g. "28s", "1m 25s") */
57
+ function formatElapsed(seconds) {
58
+ const mins = Math.floor(seconds / 60);
59
+ const secs = seconds % 60;
60
+ return mins > 0 ? `${mins}m ${secs}s` : `${secs}s`;
61
+ }
54
62
  function phaseLabel(phase, elapsed) {
55
63
  switch (phase) {
56
- case "initializing": return "Starting planning agent...";
57
- case "reading_repo": return "Reading repository structure...";
58
- case "analyzing": return "Analyzing requirements...";
59
- case "generating_plan": return `Generating execution plan... (${elapsed}s)`;
60
- case "validating": return "Validating plan...";
61
- case "complete": return "Planning complete";
64
+ case "initializing": return `${PREFIX} Starting planning agent...`;
65
+ case "reading_repo": return `${PREFIX} Reading repository structure...`;
66
+ case "analyzing": return `${PREFIX} Analyzing requirements...`;
67
+ case "generating_plan": return `${PREFIX} Planning in progress β€” analyzing requirements and decomposing into steps (${formatElapsed(elapsed)} elapsed)`;
68
+ case "validating": return `${PREFIX} Validating plan...`;
69
+ case "complete": return `${PREFIX} Planning complete`;
62
70
  }
63
71
  }
64
72
  /**
@@ -119,7 +127,7 @@ function runClaudeCli(claudePath, model, prompt, env, taskId, startTime) {
119
127
  // Periodic progress during generation
120
128
  if (currentPhase === "generating_plan" && elapsed - lastProgressLogAt >= 30) {
121
129
  lastProgressLogAt = elapsed;
122
- const msg = `Generating execution plan... (${elapsed}s, ${charsReceived} chars, ${toolCallCount} tool calls)`;
130
+ const msg = `${PREFIX} Planning in progress β€” analyzing requirements and decomposing into steps (${formatElapsed(elapsed)} elapsed)`;
123
131
  postLog(taskId, msg);
124
132
  console.log(`${ts()} ${taskLabel} ${chalk.dim(msg)}`);
125
133
  }
@@ -217,7 +225,7 @@ function runClaudeCli(claudePath, model, prompt, env, taskId, startTime) {
217
225
  export async function planTask(task, config) {
218
226
  const taskLabel = chalk.cyan(task.id.slice(0, 8));
219
227
  console.log(`${ts()} ${taskLabel} Fetching planning prompt...`);
220
- await postLog(task.id, "Fetching planning prompt from cloud API...");
228
+ await postLog(task.id, `${PREFIX} Fetching planning prompt from cloud API...`);
221
229
  // 1. Fetch the assembled planning prompt from the cloud API
222
230
  const promptResponse = await api.get("/api/agent/planning-prompt", {
223
231
  params: { taskId: task.id },
@@ -225,7 +233,7 @@ export async function planTask(task, config) {
225
233
  const { prompt, model } = promptResponse.data;
226
234
  const cliModel = model || "sonnet";
227
235
  console.log(`${ts()} ${taskLabel} Running Claude CLI ${chalk.dim(`(model: ${chalk.yellow(cliModel)})`)}`);
228
- await postLog(task.id, `Starting planning agent (model: ${cliModel})...`);
236
+ await postLog(task.id, `${PREFIX} Starting planning agent using anthropic/${cliModel}`);
229
237
  // 2. Run Claude CLI asynchronously with progress logging
230
238
  const claudePath = process.env.CLAUDE_CLI_PATH || findClaudePath() || "claude";
231
239
  const cleanEnv = { ...process.env };
@@ -239,12 +247,12 @@ export async function planTask(task, config) {
239
247
  const elapsed = Math.round((Date.now() - startTime) / 1000);
240
248
  const errMsg = error instanceof Error ? error.message : String(error);
241
249
  console.error(`${ts()} ${taskLabel} ${chalk.red("βœ—")} Failed after ${elapsed}s: ${errMsg.substring(0, 100)}`);
242
- await postLog(task.id, `Planning agent failed after ${elapsed}s: ${errMsg.substring(0, 200)}`, "error", "error");
250
+ await postLog(task.id, `${PREFIX} Planning failed after ${formatElapsed(elapsed)}: ${errMsg.substring(0, 200)}`, "error", "error");
243
251
  return false;
244
252
  }
245
253
  const elapsed = Math.round((Date.now() - startTime) / 1000);
246
254
  console.log(`${ts()} ${taskLabel} ${chalk.green("βœ“")} Claude CLI done ${chalk.dim(`(${elapsed}s, ${rawOutput.length} chars)`)}`);
247
- await postLog(task.id, `Planning complete (${elapsed}s, ${rawOutput.length} chars). Validating plan...`);
255
+ await postLog(task.id, `${PREFIX} Planning complete (${formatElapsed(elapsed)}). Validating plan...`);
248
256
  // 3. Post raw output back to cloud API for validation
249
257
  try {
250
258
  const result = await api.post("/api/agent/plan-result", {
@@ -254,7 +262,7 @@ export async function planTask(task, config) {
254
262
  });
255
263
  const storyCount = result.data.storyCount;
256
264
  console.log(`${ts()} ${taskLabel} ${chalk.green("βœ“")} Plan validated: ${chalk.bold(storyCount)} stories β†’ ${chalk.green("queued")}`);
257
- await postLog(task.id, `Plan validated: ${storyCount} stories. Task queued for execution.`);
265
+ await postLog(task.id, `${PREFIX} Plan validated: ${storyCount} stories. Task queued for execution.`);
258
266
  await postProgress(task.id, "complete", elapsed, "Planning complete", 0, 0);
259
267
  return true;
260
268
  }
@@ -262,7 +270,7 @@ export async function planTask(task, config) {
262
270
  const err = error;
263
271
  const detail = err.response?.data?.detail || String(error);
264
272
  console.error(`${ts()} ${taskLabel} ${chalk.red("βœ—")} Validation failed: ${detail.substring(0, 100)}`);
265
- await postLog(task.id, `Plan validation failed: ${detail.substring(0, 200)}`, "error", "error");
273
+ await postLog(task.id, `${PREFIX} Plan validation failed: ${detail.substring(0, 200)}`, "error", "error");
266
274
  return false;
267
275
  }
268
276
  }
package/dist/poller.js CHANGED
@@ -149,8 +149,10 @@ async function handleQueuedTask(task, config) {
149
149
  executionPlanV2: task.executionPlanV2,
150
150
  jiraFields: task.jiraFields || {},
151
151
  };
152
+ // Pass org credentials from the claim response to the container
153
+ const credentials = claimData.credentials;
152
154
  // Spawn asynchronously (don't block the poll loop)
153
- spawnWorker(spawnableTask, config, oc).catch((err) => console.error(`${ts()} ${chalk.red("βœ—")} Spawn failed for ${taskLabel}:`, err.message || err));
155
+ spawnWorker(spawnableTask, config, oc, credentials).catch((err) => console.error(`${ts()} ${chalk.red("βœ—")} Spawn failed for ${taskLabel}:`, err.message || err));
154
156
  }
155
157
  /**
156
158
  * Start the poll loop.
package/dist/spawner.d.ts CHANGED
@@ -19,11 +19,26 @@ export interface SpawnableTask {
19
19
  skipManagerReview?: boolean;
20
20
  executionPlanV2: unknown;
21
21
  jiraFields: Record<string, unknown>;
22
+ taskNotes?: string;
23
+ }
24
+ /** Org credentials returned by /api/agent/claim */
25
+ export interface ClaimCredentials {
26
+ jiraBaseUrl?: string;
27
+ jiraEmail?: string;
28
+ jiraApiToken?: string;
29
+ linearApiKey?: string;
30
+ managerProvider?: string;
31
+ managerModelId?: string;
32
+ customerAwsAccessKeyId?: string;
33
+ customerAwsSecretAccessKey?: string;
34
+ customerAwsRegion?: string;
35
+ issueTrackerProvider?: string;
36
+ bitbucketEmail?: string;
22
37
  }
23
38
  /**
24
39
  * Spawn a Docker worker container for a task.
25
40
  */
26
- export declare function spawnWorker(task: SpawnableTask, config: AgentConfig, orgConfig: Record<string, unknown>): Promise<void>;
41
+ export declare function spawnWorker(task: SpawnableTask, config: AgentConfig, orgConfig: Record<string, unknown>, credentials?: ClaimCredentials): Promise<void>;
27
42
  /**
28
43
  * Get count of actively running containers.
29
44
  */
package/dist/spawner.js CHANGED
@@ -104,7 +104,7 @@ function hasSelfReviewLabel(task) {
104
104
  /**
105
105
  * Spawn a Docker worker container for a task.
106
106
  */
107
- export async function spawnWorker(task, config, orgConfig) {
107
+ export async function spawnWorker(task, config, orgConfig, credentials) {
108
108
  const taskLabel = chalk.cyan(task.id.slice(0, 8));
109
109
  if (activeContainers.has(task.id)) {
110
110
  console.log(`${ts()} ${taskLabel} ${chalk.dim("Already running, skipping")}`);
@@ -174,6 +174,25 @@ export async function spawnWorker(task, config, orgConfig) {
174
174
  GITHUB_REPO: task.githubRepo || "",
175
175
  // Worker model
176
176
  WORKER_MODEL: task.workerModel || String(orgConfig.defaultWorkerModel || "sonnet"),
177
+ // Jira credentials (from org Secrets Manager via /api/agent/claim)
178
+ JIRA_BASE_URL: credentials?.jiraBaseUrl || "",
179
+ JIRA_EMAIL: credentials?.jiraEmail || "",
180
+ JIRA_API_TOKEN: credentials?.jiraApiToken || "",
181
+ // Issue tracker system (jira, linear, github-issues)
182
+ TICKET_SYSTEM: credentials?.issueTrackerProvider || "jira",
183
+ LINEAR_API_KEY: credentials?.linearApiKey || "",
184
+ // AWS credentials (from org Secrets Manager for workers that deploy infrastructure)
185
+ AWS_ACCESS_KEY_ID: credentials?.customerAwsAccessKeyId || "",
186
+ AWS_SECRET_ACCESS_KEY: credentials?.customerAwsSecretAccessKey || "",
187
+ AWS_DEFAULT_REGION: credentials?.customerAwsRegion || "",
188
+ AWS_REGION: credentials?.customerAwsRegion || "",
189
+ // Manager provider and model for tech lead review
190
+ MANAGER_PROVIDER: credentials?.managerProvider || "anthropic",
191
+ MANAGER_MODEL: credentials?.managerModelId || "",
192
+ // Bitbucket email (needed for API calls with API tokens)
193
+ BITBUCKET_EMAIL: credentials?.bitbucketEmail || "",
194
+ // Task notes from dashboard
195
+ TASK_NOTES: task.taskNotes || "",
177
196
  // Anthropic API key (if available)
178
197
  ANTHROPIC_API_KEY: process.env.ANTHROPIC_API_KEY || "",
179
198
  // Resilience settings from org config
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@workermill/agent",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "description": "WorkerMill Remote Agent - Run AI workers locally with your Claude Max subscription",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",