@developerz.ai/aitm
Advanced tools
| import type { FileManifestEntry } from './worker.ts'; | ||
| export declare function dirOf(path: string): string; | ||
| export type EditorAssignment = { | ||
@@ -7,3 +6,2 @@ editor?: string; | ||
| }; | ||
| export declare function groupManifestByDir(files: readonly FileManifestEntry[], maxPerGroup: number): FileManifestEntry[][]; | ||
| export declare function assignEditors(files: readonly FileManifestEntry[], maxPerGroup: number): EditorAssignment[]; | ||
| export declare function assignEditors(files: readonly FileManifestEntry[]): EditorAssignment[]; |
@@ -1,25 +0,2 @@ | ||
| export function dirOf(path) { | ||
| const slash = path.lastIndexOf('/'); | ||
| return slash === -1 ? '.' : path.slice(0, slash); | ||
| } | ||
| export function groupManifestByDir(files, maxPerGroup) { | ||
| const byDir = new Map(); | ||
| for (const file of files) { | ||
| const dir = dirOf(file.path); | ||
| const bucket = byDir.get(dir); | ||
| if (bucket) | ||
| bucket.push(file); | ||
| else | ||
| byDir.set(dir, [file]); | ||
| } | ||
| const size = Math.max(1, Math.floor(maxPerGroup) || 1); | ||
| const groups = []; | ||
| for (const bucket of byDir.values()) { | ||
| for (let i = 0; i < bucket.length; i += size) { | ||
| groups.push(bucket.slice(i, i + size)); | ||
| } | ||
| } | ||
| return groups; | ||
| } | ||
| export function assignEditors(files, maxPerGroup) { | ||
| export function assignEditors(files) { | ||
| const byEditor = new Map(); | ||
@@ -43,4 +20,3 @@ const untagged = []; | ||
| })); | ||
| const fallback = groupManifestByDir(untagged, maxPerGroup).map((group) => ({ files: group })); | ||
| return [...assigned, ...fallback]; | ||
| return untagged.length > 0 ? [...assigned, { files: untagged }] : assigned; | ||
| } |
@@ -8,3 +8,2 @@ import type { BashInput, BashOutput } from '@developerz.ai/ai-claude-compat'; | ||
| export declare const EDITOR_MAX_STEPS = 1000; | ||
| export declare const MAX_FILES_PER_EDITOR = 6; | ||
| export declare const FANOUT_FLOOR_FILES = 4; | ||
@@ -11,0 +10,0 @@ export declare const FANOUT_FLOOR_PURPOSE_CHARS = 240; |
@@ -8,3 +8,3 @@ import { randomUUID } from 'node:crypto'; | ||
| import { isAsyncIterable, requireExec, shQuote } from "./bash-exec.js"; | ||
| import { assignEditors, dirOf } from "./editor-assignment.js"; | ||
| import { assignEditors } from "./editor-assignment.js"; | ||
| import { AGENT_STEP_BACKSTOP, reportUsage } from "./factory.js"; | ||
@@ -15,3 +15,2 @@ import { capText, MANIFEST_FIELD_MAX, ROLLING_CONTEXT_MAX } from "./prompt-caps.js"; | ||
| export const EDITOR_MAX_STEPS = AGENT_STEP_BACKSTOP; | ||
| export const MAX_FILES_PER_EDITOR = 6; | ||
| export const FANOUT_FLOOR_FILES = 4; | ||
@@ -39,2 +38,6 @@ export const FANOUT_FLOOR_PURPOSE_CHARS = 240; | ||
| } | ||
| function dirOf(path) { | ||
| const slash = path.lastIndexOf('/'); | ||
| return slash === -1 ? '.' : path.slice(0, slash); | ||
| } | ||
| function editorGroupLabel(assignment) { | ||
@@ -124,3 +127,3 @@ const named = assignment.editor?.trim(); | ||
| ? [{ label: collapsedLeafLabel(files), files: [...files] }] | ||
| : labelEditorGroups(assignEditors(files, MAX_FILES_PER_EDITOR)); | ||
| : labelEditorGroups(assignEditors(files)); | ||
| const isTeam = leaves.length > 1; | ||
@@ -127,0 +130,0 @@ const teamBrief = isTeam ? buildTeamBrief(input, files) : ''; |
@@ -74,4 +74,5 @@ export const PLANNER_SYSTEM_PREFIX = [ | ||
| 'a label go to one editor as a whole assignment. Group by what must be written TOGETHER — a route,', | ||
| 'its service and its test are one editor even though they sit in three directories. Leave `editor`', | ||
| 'off and the harness falls back to grouping by directory, which cannot see that.', | ||
| 'its service and its test are one editor even though they sit in three directories. There is no', | ||
| 'grouping rule behind you: entries you leave untagged are ONE editor, because work you did not', | ||
| 'divide is not divided.', | ||
| '- Judge each assignment before you send it. TOO BIG if it spans work that does not inform itself —', | ||
@@ -78,0 +79,0 @@ ' split it. TOO SMALL if it is a file another editor is already opening, or a one-line change — merge', |
@@ -20,3 +20,3 @@ import { randomUUID } from 'node:crypto'; | ||
| .optional() | ||
| .describe('Short label for the teammate owning this file (e.g. "auth-routes"). Files sharing a label go to one editor. Group by what must be written together, not by directory; omit to let the harness group by directory.'), | ||
| .describe('Short label for the teammate owning this file (e.g. "auth-routes"). Files sharing a label go to one editor. Group by what must be written together, not by directory; everything you leave untagged becomes a single editor.'), | ||
| }); | ||
@@ -23,0 +23,0 @@ export const FileManifestSchema = z.object({ |
+2
-2
| { | ||
| "name": "@developerz.ai/aitm", | ||
| "version": "0.0.51", | ||
| "version": "0.0.52", | ||
| "description": "Autonomous task orchestrator. Goal in, merged PRs out.", | ||
@@ -46,3 +46,3 @@ "license": "MIT", | ||
| "@ai-sdk/mcp": "^1.0.42", | ||
| "@developerz.ai/ai-claude-compat": "0.0.51", | ||
| "@developerz.ai/ai-claude-compat": "0.0.52", | ||
| "@openrouter/ai-sdk-provider": "^2.9.0", | ||
@@ -49,0 +49,0 @@ "ai": "^6.0.182", |
AI-detected potential code anomaly
Supply chain riskAI has identified unusual behaviors that may pose a security risk.
Found 2 instances
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
AI-detected potential code anomaly
Supply chain riskAI has identified unusual behaviors that may pose a security risk.
Found 2 instances
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
808564
-0.11%19974
-0.12%+ Added
- Removed