@supaku/agentfactory-nextjs 0.4.8 → 0.5.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.
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=poll-project-filter.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"poll-project-filter.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/poll-project-filter.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,83 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ /**
3
+ * Tests for project-based work filtering in the poll handler.
4
+ *
5
+ * The poll handler filters work items based on the worker's `projects` field.
6
+ * This test validates the filtering logic independently of Redis/HTTP.
7
+ */
8
+ function filterWorkForProjects(allWork, workerProjects, desiredCount) {
9
+ const hasProjectFilter = workerProjects && workerProjects.length > 0;
10
+ if (hasProjectFilter) {
11
+ // Accept: matching project OR untagged items (backward compat)
12
+ return allWork
13
+ .filter(w => !w.projectName || workerProjects.includes(w.projectName))
14
+ .slice(0, desiredCount);
15
+ }
16
+ return allWork.slice(0, desiredCount);
17
+ }
18
+ function makeWork(overrides = {}) {
19
+ return {
20
+ sessionId: `session-${Math.random().toString(36).slice(2, 8)}`,
21
+ issueId: 'issue-1',
22
+ issueIdentifier: 'TEST-1',
23
+ priority: 3,
24
+ queuedAt: Date.now(),
25
+ ...overrides,
26
+ };
27
+ }
28
+ describe('poll handler project filtering', () => {
29
+ it('worker with projects: ["Social"] receives only Social + untagged work', () => {
30
+ const allWork = [
31
+ makeWork({ projectName: 'Social', issueIdentifier: 'SUP-1' }),
32
+ makeWork({ projectName: 'Agent', issueIdentifier: 'SUP-2' }),
33
+ makeWork({ projectName: undefined, issueIdentifier: 'SUP-3' }),
34
+ makeWork({ projectName: 'Art', issueIdentifier: 'SUP-4' }),
35
+ ];
36
+ const result = filterWorkForProjects(allWork, ['Social'], 5);
37
+ expect(result).toHaveLength(2);
38
+ expect(result[0].issueIdentifier).toBe('SUP-1');
39
+ expect(result[1].issueIdentifier).toBe('SUP-3');
40
+ });
41
+ it('worker with projects: undefined receives all work', () => {
42
+ const allWork = [
43
+ makeWork({ projectName: 'Social' }),
44
+ makeWork({ projectName: 'Agent' }),
45
+ makeWork({ projectName: undefined }),
46
+ ];
47
+ const result = filterWorkForProjects(allWork, undefined, 5);
48
+ expect(result).toHaveLength(3);
49
+ });
50
+ it('worker with projects: ["Social", "Agent"] receives both + untagged', () => {
51
+ const allWork = [
52
+ makeWork({ projectName: 'Social', issueIdentifier: 'SUP-1' }),
53
+ makeWork({ projectName: 'Agent', issueIdentifier: 'SUP-2' }),
54
+ makeWork({ projectName: 'Art', issueIdentifier: 'SUP-3' }),
55
+ makeWork({ projectName: undefined, issueIdentifier: 'SUP-4' }),
56
+ ];
57
+ const result = filterWorkForProjects(allWork, ['Social', 'Agent'], 5);
58
+ expect(result).toHaveLength(3);
59
+ expect(result.map(w => w.issueIdentifier)).toEqual(['SUP-1', 'SUP-2', 'SUP-4']);
60
+ });
61
+ it('empty queue returns empty regardless of filter', () => {
62
+ expect(filterWorkForProjects([], ['Social'], 5)).toEqual([]);
63
+ expect(filterWorkForProjects([], undefined, 5)).toEqual([]);
64
+ });
65
+ it('respects desiredCount limit', () => {
66
+ const allWork = [
67
+ makeWork({ projectName: 'Social' }),
68
+ makeWork({ projectName: 'Social' }),
69
+ makeWork({ projectName: 'Social' }),
70
+ makeWork({ projectName: 'Social' }),
71
+ ];
72
+ const result = filterWorkForProjects(allWork, ['Social'], 2);
73
+ expect(result).toHaveLength(2);
74
+ });
75
+ it('empty projects array is treated as no filter', () => {
76
+ const allWork = [
77
+ makeWork({ projectName: 'Social' }),
78
+ makeWork({ projectName: 'Agent' }),
79
+ ];
80
+ const result = filterWorkForProjects(allWork, [], 5);
81
+ expect(result).toHaveLength(2);
82
+ });
83
+ });
@@ -11,6 +11,7 @@ export interface PublicSessionResponse {
11
11
  workType: string;
12
12
  startedAt: string;
13
13
  duration: number;
14
+ costUsd?: number;
14
15
  }
15
16
  export declare function createPublicSessionsListHandler(): () => Promise<NextResponse<{
16
17
  sessions: PublicSessionResponse[];
@@ -1 +1 @@
1
- {"version":3,"file":"sessions-list.d.ts","sourceRoot":"","sources":["../../../../src/handlers/public/sessions-list.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAW1C,MAAM,WAAW,qBAAqB;IACpC,EAAE,EAAE,MAAM,CAAA;IACV,UAAU,EAAE,MAAM,CAAA;IAClB,MAAM,EAAE,QAAQ,GAAG,QAAQ,GAAG,SAAS,GAAG,WAAW,GAAG,QAAQ,GAAG,SAAS,CAAA;IAC5E,QAAQ,EAAE,MAAM,CAAA;IAChB,SAAS,EAAE,MAAM,CAAA;IACjB,QAAQ,EAAE,MAAM,CAAA;CACjB;AAmDD,wBAAgB,+BAA+B;;;;IA6B9C"}
1
+ {"version":3,"file":"sessions-list.d.ts","sourceRoot":"","sources":["../../../../src/handlers/public/sessions-list.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAW1C,MAAM,WAAW,qBAAqB;IACpC,EAAE,EAAE,MAAM,CAAA;IACV,UAAU,EAAE,MAAM,CAAA;IAClB,MAAM,EAAE,QAAQ,GAAG,QAAQ,GAAG,SAAS,GAAG,WAAW,GAAG,QAAQ,GAAG,SAAS,CAAA;IAC5E,QAAQ,EAAE,MAAM,CAAA;IAChB,SAAS,EAAE,MAAM,CAAA;IACjB,QAAQ,EAAE,MAAM,CAAA;IAChB,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB;AAoDD,wBAAgB,+BAA+B;;;;IA6B9C"}
@@ -44,6 +44,7 @@ async function toPublicSession(session) {
44
44
  workType: session.workType || 'development',
45
45
  startedAt: new Date(startTime * 1000).toISOString(),
46
46
  duration: endTime - startTime,
47
+ costUsd: session.totalCostUsd,
47
48
  };
48
49
  }
49
50
  export function createPublicSessionsListHandler() {
@@ -10,6 +10,7 @@ export interface PublicStatsResponse {
10
10
  queueDepth: number;
11
11
  completedToday: number;
12
12
  availableCapacity: number;
13
+ totalCostToday: number;
13
14
  }
14
15
  export declare function createPublicStatsHandler(): () => Promise<NextResponse<{
15
16
  timestamp: string;
@@ -18,5 +19,6 @@ export declare function createPublicStatsHandler(): () => Promise<NextResponse<{
18
19
  queueDepth: number;
19
20
  completedToday: number;
20
21
  availableCapacity: number;
22
+ totalCostToday: number;
21
23
  }>>;
22
24
  //# sourceMappingURL=stats.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"stats.d.ts","sourceRoot":"","sources":["../../../../src/handlers/public/stats.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAK1C,MAAM,WAAW,mBAAmB;IAClC,aAAa,EAAE,MAAM,CAAA;IACrB,aAAa,EAAE,MAAM,CAAA;IACrB,UAAU,EAAE,MAAM,CAAA;IAClB,cAAc,EAAE,MAAM,CAAA;IACtB,iBAAiB,EAAE,MAAM,CAAA;CAC1B;AAUD,wBAAgB,wBAAwB;;mBAfvB,MAAM;mBACN,MAAM;gBACT,MAAM;oBACF,MAAM;uBACH,MAAM;IAgE1B"}
1
+ {"version":3,"file":"stats.d.ts","sourceRoot":"","sources":["../../../../src/handlers/public/stats.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAK1C,MAAM,WAAW,mBAAmB;IAClC,aAAa,EAAE,MAAM,CAAA;IACrB,aAAa,EAAE,MAAM,CAAA;IACrB,UAAU,EAAE,MAAM,CAAA;IAClB,cAAc,EAAE,MAAM,CAAA;IACtB,iBAAiB,EAAE,MAAM,CAAA;IACzB,cAAc,EAAE,MAAM,CAAA;CACvB;AAUD,wBAAgB,wBAAwB;;mBAhBvB,MAAM;mBACN,MAAM;gBACT,MAAM;oBACF,MAAM;uBACH,MAAM;oBACT,MAAM;IAsEvB"}
@@ -24,6 +24,9 @@ export function createPublicStatsHandler() {
24
24
  const agentsWorking = allSessions.filter((s) => s.status === 'running' || s.status === 'claimed').length;
25
25
  const completedToday = allSessions.filter((s) => s.status === 'completed' &&
26
26
  s.updatedAt >= todayStart).length;
27
+ const totalCostToday = allSessions
28
+ .filter((s) => s.updatedAt >= todayStart)
29
+ .reduce((sum, s) => sum + (s.totalCostUsd ?? 0), 0);
27
30
  const workersOnline = workers.filter((w) => w.status === 'active').length;
28
31
  const stats = {
29
32
  workersOnline,
@@ -31,6 +34,7 @@ export function createPublicStatsHandler() {
31
34
  queueDepth: queueLength,
32
35
  completedToday,
33
36
  availableCapacity: capacity.availableCapacity,
37
+ totalCostToday: Math.round(totalCostToday * 10000) / 10000,
34
38
  };
35
39
  return NextResponse.json({
36
40
  ...stats,
@@ -45,6 +49,7 @@ export function createPublicStatsHandler() {
45
49
  queueDepth: 0,
46
50
  completedToday: 0,
47
51
  availableCapacity: 0,
52
+ totalCostToday: 0,
48
53
  error: 'Failed to fetch stats',
49
54
  timestamp: new Date().toISOString(),
50
55
  }, { status: 500 });
@@ -1 +1 @@
1
- {"version":3,"file":"poll.d.ts","sourceRoot":"","sources":["../../../../src/handlers/workers/poll.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAavD,UAAU,WAAW;IACnB,MAAM,EAAE,OAAO,CAAC;QAAE,EAAE,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CAChC;AAED,wBAAgB,uBAAuB,KACX,SAAS,WAAW,EAAE,YAAY,WAAW,oCAmFxE"}
1
+ {"version":3,"file":"poll.d.ts","sourceRoot":"","sources":["../../../../src/handlers/workers/poll.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAavD,UAAU,WAAW;IACnB,MAAM,EAAE,OAAO,CAAC;QAAE,EAAE,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CAChC;AAED,wBAAgB,uBAAuB,KACX,SAAS,WAAW,EAAE,YAAY,WAAW,oCAkGxE"}
@@ -24,8 +24,21 @@ export function createWorkerPollHandler() {
24
24
  const availableCapacity = worker.capacity - worker.activeCount;
25
25
  let work = [];
26
26
  if (availableCapacity > 0) {
27
- const limit = Math.min(availableCapacity, 5);
28
- work = await peekWork(limit);
27
+ const desiredCount = Math.min(availableCapacity, 5);
28
+ const workerProjects = worker.projects;
29
+ const hasProjectFilter = workerProjects && workerProjects.length > 0;
30
+ // Over-fetch when filtering, since some items may not match
31
+ const fetchLimit = hasProjectFilter ? Math.min(desiredCount * 4, 50) : desiredCount;
32
+ const allWork = await peekWork(fetchLimit);
33
+ if (hasProjectFilter) {
34
+ // Accept: matching project OR untagged items (backward compat)
35
+ work = allWork
36
+ .filter(w => !w.projectName || workerProjects.includes(w.projectName))
37
+ .slice(0, desiredCount);
38
+ }
39
+ else {
40
+ work = allWork.slice(0, desiredCount);
41
+ }
29
42
  }
30
43
  const pendingPrompts = {};
31
44
  let totalPendingPrompts = 0;
@@ -47,6 +60,7 @@ export function createWorkerPollHandler() {
47
60
  sessionId: w.sessionId,
48
61
  issueIdentifier: w.issueIdentifier,
49
62
  workType: w.workType,
63
+ projectName: w.projectName,
50
64
  })),
51
65
  activeSessionCount: worker.activeSessions.length,
52
66
  pendingPromptsCount: totalPendingPrompts,
@@ -1 +1 @@
1
- {"version":3,"file":"register.d.ts","sourceRoot":"","sources":["../../../../src/handlers/workers/register.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAMvD,wBAAgB,2BAA2B,KACd,SAAS,WAAW,oCA8ChD"}
1
+ {"version":3,"file":"register.d.ts","sourceRoot":"","sources":["../../../../src/handlers/workers/register.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAMvD,wBAAgB,2BAA2B,KACd,SAAS,WAAW,oCAwDhD"}
@@ -15,14 +15,17 @@ export function createWorkerRegisterHandler() {
15
15
  return authError;
16
16
  try {
17
17
  const body = await request.json();
18
- const { hostname, capacity, version } = body;
18
+ const { hostname, capacity, version, projects } = body;
19
19
  if (!hostname || typeof hostname !== 'string') {
20
20
  return NextResponse.json({ error: 'Bad Request', message: 'hostname is required' }, { status: 400 });
21
21
  }
22
22
  if (!capacity || typeof capacity !== 'number' || capacity < 1) {
23
23
  return NextResponse.json({ error: 'Bad Request', message: 'capacity must be a positive number' }, { status: 400 });
24
24
  }
25
- const result = await registerWorker(hostname, capacity, version);
25
+ if (projects !== undefined && !Array.isArray(projects)) {
26
+ return NextResponse.json({ error: 'Bad Request', message: 'projects must be an array of strings' }, { status: 400 });
27
+ }
28
+ const result = await registerWorker(hostname, capacity, version, projects);
26
29
  if (!result) {
27
30
  return NextResponse.json({ error: 'Service Unavailable', message: 'Failed to register worker' }, { status: 503 });
28
31
  }
@@ -30,6 +33,7 @@ export function createWorkerRegisterHandler() {
30
33
  workerId: result.workerId,
31
34
  hostname,
32
35
  capacity,
36
+ projects: projects?.length ? projects : 'all',
33
37
  });
34
38
  return NextResponse.json(result, { status: 201 });
35
39
  }
@@ -1 +1 @@
1
- {"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../../../src/middleware/factory.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AACvD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAA;AA0GlD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,4BAA4B,CAAC,UAAU,CAAC,EAAE,gBAAgB;0BAO3C,WAAW,KAAG,YAAY,GAAG,SAAS;;;;EAgHpE"}
1
+ {"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../../../src/middleware/factory.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AACvD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAA;AA0GlD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,4BAA4B,CAAC,UAAU,CAAC,EAAE,gBAAgB;0BAO3C,WAAW,KAAG,YAAY,GAAG,SAAS;;;;EAkHpE"}
@@ -75,7 +75,7 @@ function timingSafeEqual(a, b) {
75
75
  return result === 0;
76
76
  }
77
77
  // === Route defaults ===
78
- const DEFAULT_PUBLIC_ROUTES = ['/api/public/', '/dashboard', '/'];
78
+ const DEFAULT_PUBLIC_ROUTES = ['/api/public/', '/dashboard', '/pipeline', '/settings', '/'];
79
79
  const DEFAULT_PROTECTED_ROUTES = ['/api/sessions', '/api/workers'];
80
80
  const DEFAULT_SESSION_PAGES = ['/sessions/'];
81
81
  const DEFAULT_WEBHOOK_ROUTE = '/webhook';
@@ -175,6 +175,8 @@ export function createAgentFactoryMiddleware(userConfig) {
175
175
  '/api/:path*',
176
176
  webhookRoute,
177
177
  '/dashboard',
178
+ '/pipeline',
179
+ '/settings',
178
180
  '/sessions/:path*',
179
181
  '/',
180
182
  ],
@@ -1 +1 @@
1
- {"version":3,"file":"issue-updated.d.ts","sourceRoot":"","sources":["../../../../src/webhook/handlers/issue-updated.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAC1C,OAAO,KAAK,EAAE,oBAAoB,EAAiB,MAAM,6BAA6B,CAAA;AAsBtF,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAA;AAQ3D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAA;AAE/D,wBAAsB,kBAAkB,CACtC,MAAM,EAAE,qBAAqB,EAC7B,OAAO,EAAE,oBAAoB,EAC7B,GAAG,EAAE,UAAU,CAAC,OAAO,YAAY,CAAC,GACnC,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAmhB9B"}
1
+ {"version":3,"file":"issue-updated.d.ts","sourceRoot":"","sources":["../../../../src/webhook/handlers/issue-updated.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAC1C,OAAO,KAAK,EAAE,oBAAoB,EAAiB,MAAM,6BAA6B,CAAA;AAsBtF,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAA;AAQ3D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAA;AAE/D,wBAAsB,kBAAkB,CACtC,MAAM,EAAE,qBAAqB,EAC7B,OAAO,EAAE,oBAAoB,EAC7B,GAAG,EAAE,UAAU,CAAC,OAAO,YAAY,CAAC,GACnC,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CA0hB9B"}
@@ -150,6 +150,7 @@ export async function handleIssueUpdated(config, payload, log) {
150
150
  priority: 2,
151
151
  organizationId: payload.organizationId,
152
152
  workType: qaWorkType,
153
+ projectName,
153
154
  });
154
155
  const qaWork = {
155
156
  sessionId: qaSessionId,
@@ -159,6 +160,7 @@ export async function handleIssueUpdated(config, payload, log) {
159
160
  queuedAt: Date.now(),
160
161
  prompt: qaPrompt,
161
162
  workType: qaWorkType,
163
+ projectName,
162
164
  };
163
165
  const qaResult = await dispatchWork(qaWork);
164
166
  if (qaResult.dispatched || qaResult.parked) {
@@ -251,6 +253,7 @@ export async function handleIssueUpdated(config, payload, log) {
251
253
  issueLog.warn('Failed to check if issue is parent', { error: err });
252
254
  }
253
255
  const prompt = config.generatePrompt(issueIdentifier, workType);
256
+ const projectName = data.project?.name;
254
257
  await storeSessionState(devSessionId, {
255
258
  issueId,
256
259
  issueIdentifier,
@@ -262,6 +265,7 @@ export async function handleIssueUpdated(config, payload, log) {
262
265
  priority: 3,
263
266
  organizationId: payload.organizationId,
264
267
  workType,
268
+ projectName,
265
269
  });
266
270
  const devWork = {
267
271
  sessionId: devSessionId,
@@ -271,6 +275,7 @@ export async function handleIssueUpdated(config, payload, log) {
271
275
  queuedAt: Date.now(),
272
276
  prompt,
273
277
  workType,
278
+ projectName,
274
279
  };
275
280
  const devResult = await dispatchWork(devWork);
276
281
  if (devResult.dispatched || devResult.parked) {
@@ -417,6 +422,7 @@ export async function handleIssueUpdated(config, payload, log) {
417
422
  priority: 2,
418
423
  organizationId: payload.organizationId,
419
424
  workType: acceptanceWorkType,
425
+ projectName,
420
426
  });
421
427
  const acceptanceWork = {
422
428
  sessionId: acceptanceSessionId,
@@ -426,6 +432,7 @@ export async function handleIssueUpdated(config, payload, log) {
426
432
  queuedAt: Date.now(),
427
433
  prompt: acceptancePrompt,
428
434
  workType: acceptanceWorkType,
435
+ projectName,
429
436
  };
430
437
  const accResult = await dispatchWork(acceptanceWork);
431
438
  if (accResult.dispatched || accResult.parked) {
@@ -1 +1 @@
1
- {"version":3,"file":"session-created.d.ts","sourceRoot":"","sources":["../../../../src/webhook/handlers/session-created.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAC1C,OAAO,KAAK,EAAE,oBAAoB,EAAiB,MAAM,6BAA6B,CAAA;AAiBtF,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAA;AAQ3D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAA;AAE/D,wBAAsB,oBAAoB,CACxC,MAAM,EAAE,qBAAqB,EAC7B,OAAO,EAAE,oBAAoB,EAC7B,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACnC,GAAG,EAAE,UAAU,CAAC,OAAO,YAAY,CAAC,GACnC,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CA0Q9B"}
1
+ {"version":3,"file":"session-created.d.ts","sourceRoot":"","sources":["../../../../src/webhook/handlers/session-created.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAC1C,OAAO,KAAK,EAAE,oBAAoB,EAAiB,MAAM,6BAA6B,CAAA;AAiBtF,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAA;AAQ3D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAA;AAE/D,wBAAsB,oBAAoB,CACxC,MAAM,EAAE,qBAAqB,EAC7B,OAAO,EAAE,oBAAoB,EAC7B,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACnC,GAAG,EAAE,UAAU,CAAC,OAAO,YAAY,CAAC,GACnC,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAiR9B"}
@@ -59,6 +59,7 @@ export async function handleSessionCreated(config, payload, rawPayload, log) {
59
59
  // Determine work type
60
60
  let workType = 'development';
61
61
  let currentStatus;
62
+ let projectName;
62
63
  let workTypeSource = 'status';
63
64
  // Fetch current issue status
64
65
  try {
@@ -67,6 +68,9 @@ export async function handleSessionCreated(config, payload, rawPayload, log) {
67
68
  const currentState = await issueDetails.state;
68
69
  currentStatus = currentState?.name;
69
70
  sessionLog.debug('Fetched current issue status', { currentStatus });
71
+ // Extract project name for routing
72
+ const project = await issueDetails.project;
73
+ projectName = project?.name;
70
74
  }
71
75
  catch (err) {
72
76
  sessionLog.warn('Failed to fetch issue status', { error: err });
@@ -179,6 +183,7 @@ export async function handleSessionCreated(config, payload, rawPayload, log) {
179
183
  organizationId: payload.organizationId,
180
184
  workType,
181
185
  agentId,
186
+ projectName,
182
187
  });
183
188
  // Queue work
184
189
  const work = {
@@ -189,6 +194,7 @@ export async function handleSessionCreated(config, payload, rawPayload, log) {
189
194
  queuedAt: Date.now(),
190
195
  workType,
191
196
  prompt: config.generatePrompt(issueIdentifier, workType, promptContext),
197
+ projectName,
192
198
  };
193
199
  const result = await dispatchWork(work);
194
200
  if (result.dispatched || result.parked) {
@@ -1 +1 @@
1
- {"version":3,"file":"session-prompted.d.ts","sourceRoot":"","sources":["../../../../src/webhook/handlers/session-prompted.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAC1C,OAAO,KAAK,EAAE,oBAAoB,EAAiB,MAAM,6BAA6B,CAAA;AAatF,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAA;AAE3D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAA;AAE/D,wBAAsB,qBAAqB,CACzC,MAAM,EAAE,qBAAqB,EAC7B,OAAO,EAAE,oBAAoB,EAC7B,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACnC,GAAG,EAAE,UAAU,CAAC,OAAO,YAAY,CAAC,GACnC,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAkP9B"}
1
+ {"version":3,"file":"session-prompted.d.ts","sourceRoot":"","sources":["../../../../src/webhook/handlers/session-prompted.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAC1C,OAAO,KAAK,EAAE,oBAAoB,EAAiB,MAAM,6BAA6B,CAAA;AAatF,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAA;AAE3D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAA;AAE/D,wBAAsB,qBAAqB,CACzC,MAAM,EAAE,qBAAqB,EAC7B,OAAO,EAAE,oBAAoB,EAC7B,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACnC,GAAG,EAAE,UAAU,CAAC,OAAO,YAAY,CAAC,GACnC,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAoP9B"}
@@ -84,6 +84,7 @@ export async function handleSessionPrompted(config, payload, rawPayload, log) {
84
84
  prompt: resumePrompt,
85
85
  claudeSessionId: existingSession?.claudeSessionId || undefined,
86
86
  workType,
87
+ projectName: existingSession?.projectName,
87
88
  };
88
89
  await dispatchWork(work);
89
90
  try {
@@ -168,6 +169,7 @@ export async function handleSessionPrompted(config, payload, rawPayload, log) {
168
169
  prompt: effectivePrompt,
169
170
  claudeSessionId: existingSession?.claudeSessionId || undefined,
170
171
  workType: existingSession?.workType || 'inflight',
172
+ projectName: existingSession?.projectName,
171
173
  };
172
174
  const dispatchResult = await dispatchWork(work);
173
175
  if (dispatchResult.dispatched || dispatchResult.parked) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@supaku/agentfactory-nextjs",
3
- "version": "0.4.8",
3
+ "version": "0.5.0",
4
4
  "type": "module",
5
5
  "description": "Next.js API route handlers for AgentFactory — webhook processor, worker/session management, public stats",
6
6
  "author": "Supaku (https://supaku.com)",
@@ -48,9 +48,9 @@
48
48
  "LICENSE"
49
49
  ],
50
50
  "dependencies": {
51
- "@supaku/agentfactory-server": "0.4.8",
52
- "@supaku/agentfactory": "0.4.8",
53
- "@supaku/agentfactory-linear": "0.4.8"
51
+ "@supaku/agentfactory": "0.5.0",
52
+ "@supaku/agentfactory-server": "0.5.0",
53
+ "@supaku/agentfactory-linear": "0.5.0"
54
54
  },
55
55
  "peerDependencies": {
56
56
  "next": ">=14.0.0"