@mknightzzz/stw 0.1.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/LICENSE +21 -0
- package/README.md +277 -0
- package/dist/agentic-fallback.d.ts +3 -0
- package/dist/agentic-fallback.js +32 -0
- package/dist/agentic-fallback.js.map +1 -0
- package/dist/agentic-prompt.d.ts +2 -0
- package/dist/agentic-prompt.js +68 -0
- package/dist/agentic-prompt.js.map +1 -0
- package/dist/agentic-runtime.d.ts +48 -0
- package/dist/agentic-runtime.js +149 -0
- package/dist/agentic-runtime.js.map +1 -0
- package/dist/agentic-types.d.ts +37 -0
- package/dist/agentic-types.js +2 -0
- package/dist/agentic-types.js.map +1 -0
- package/dist/agents.d.ts +7 -0
- package/dist/agents.js +2 -0
- package/dist/agents.js.map +1 -0
- package/dist/assignments.d.ts +7 -0
- package/dist/assignments.js +125 -0
- package/dist/assignments.js.map +1 -0
- package/dist/checkpoint.d.ts +35 -0
- package/dist/checkpoint.js +78 -0
- package/dist/checkpoint.js.map +1 -0
- package/dist/circuit-breaker.d.ts +17 -0
- package/dist/circuit-breaker.js +65 -0
- package/dist/circuit-breaker.js.map +1 -0
- package/dist/claim.d.ts +6 -0
- package/dist/claim.js +135 -0
- package/dist/claim.js.map +1 -0
- package/dist/clarity-gate.d.ts +12 -0
- package/dist/clarity-gate.js +83 -0
- package/dist/clarity-gate.js.map +1 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +38 -0
- package/dist/cli.js.map +1 -0
- package/dist/command-dispatch.d.ts +45 -0
- package/dist/command-dispatch.js +206 -0
- package/dist/command-dispatch.js.map +1 -0
- package/dist/command-parser.d.ts +11 -0
- package/dist/command-parser.js +101 -0
- package/dist/command-parser.js.map +1 -0
- package/dist/commands/clean.d.ts +10 -0
- package/dist/commands/clean.js +133 -0
- package/dist/commands/clean.js.map +1 -0
- package/dist/commands/execution.d.ts +2 -0
- package/dist/commands/execution.js +327 -0
- package/dist/commands/execution.js.map +1 -0
- package/dist/commands/go.d.ts +2 -0
- package/dist/commands/go.js +197 -0
- package/dist/commands/go.js.map +1 -0
- package/dist/commands/helpers.d.ts +44 -0
- package/dist/commands/helpers.js +231 -0
- package/dist/commands/helpers.js.map +1 -0
- package/dist/commands/idea.d.ts +2 -0
- package/dist/commands/idea.js +89 -0
- package/dist/commands/idea.js.map +1 -0
- package/dist/commands/init.d.ts +2 -0
- package/dist/commands/init.js +94 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/integration.d.ts +7 -0
- package/dist/commands/integration.js +139 -0
- package/dist/commands/integration.js.map +1 -0
- package/dist/commands/maintenance.d.ts +2 -0
- package/dist/commands/maintenance.js +301 -0
- package/dist/commands/maintenance.js.map +1 -0
- package/dist/commands/run.d.ts +2 -0
- package/dist/commands/run.js +356 -0
- package/dist/commands/run.js.map +1 -0
- package/dist/commands/setup.d.ts +2 -0
- package/dist/commands/setup.js +198 -0
- package/dist/commands/setup.js.map +1 -0
- package/dist/commands/spec.d.ts +2 -0
- package/dist/commands/spec.js +35 -0
- package/dist/commands/spec.js.map +1 -0
- package/dist/commands/stats.d.ts +2 -0
- package/dist/commands/stats.js +80 -0
- package/dist/commands/stats.js.map +1 -0
- package/dist/commands/task-ops.d.ts +2 -0
- package/dist/commands/task-ops.js +406 -0
- package/dist/commands/task-ops.js.map +1 -0
- package/dist/config.d.ts +18 -0
- package/dist/config.js +338 -0
- package/dist/config.js.map +1 -0
- package/dist/cost.d.ts +30 -0
- package/dist/cost.js +167 -0
- package/dist/cost.js.map +1 -0
- package/dist/crash-recovery.d.ts +9 -0
- package/dist/crash-recovery.js +42 -0
- package/dist/crash-recovery.js.map +1 -0
- package/dist/diagnostic.d.ts +48 -0
- package/dist/diagnostic.js +328 -0
- package/dist/diagnostic.js.map +1 -0
- package/dist/doctor.d.ts +31 -0
- package/dist/doctor.js +225 -0
- package/dist/doctor.js.map +1 -0
- package/dist/drift.d.ts +11 -0
- package/dist/drift.js +57 -0
- package/dist/drift.js.map +1 -0
- package/dist/git-utils.d.ts +20 -0
- package/dist/git-utils.js +206 -0
- package/dist/git-utils.js.map +1 -0
- package/dist/gitlab.d.ts +54 -0
- package/dist/gitlab.js +101 -0
- package/dist/gitlab.js.map +1 -0
- package/dist/idea.d.ts +35 -0
- package/dist/idea.js +251 -0
- package/dist/idea.js.map +1 -0
- package/dist/import-resolution.d.ts +13 -0
- package/dist/import-resolution.js +111 -0
- package/dist/import-resolution.js.map +1 -0
- package/dist/inbox-renderer.d.ts +2 -0
- package/dist/inbox-renderer.js +67 -0
- package/dist/inbox-renderer.js.map +1 -0
- package/dist/init.d.ts +105 -0
- package/dist/init.js +235 -0
- package/dist/init.js.map +1 -0
- package/dist/llm-reviewer.d.ts +14 -0
- package/dist/llm-reviewer.js +109 -0
- package/dist/llm-reviewer.js.map +1 -0
- package/dist/lock.d.ts +26 -0
- package/dist/lock.js +76 -0
- package/dist/lock.js.map +1 -0
- package/dist/logger.d.ts +24 -0
- package/dist/logger.js +40 -0
- package/dist/logger.js.map +1 -0
- package/dist/math-utils.d.ts +2 -0
- package/dist/math-utils.js +7 -0
- package/dist/math-utils.js.map +1 -0
- package/dist/mechanical-review.d.ts +30 -0
- package/dist/mechanical-review.js +76 -0
- package/dist/mechanical-review.js.map +1 -0
- package/dist/merge.d.ts +83 -0
- package/dist/merge.js +363 -0
- package/dist/merge.js.map +1 -0
- package/dist/parallel.d.ts +35 -0
- package/dist/parallel.js +214 -0
- package/dist/parallel.js.map +1 -0
- package/dist/plan-validation.d.ts +19 -0
- package/dist/plan-validation.js +253 -0
- package/dist/plan-validation.js.map +1 -0
- package/dist/planner-prompt.d.ts +33 -0
- package/dist/planner-prompt.js +244 -0
- package/dist/planner-prompt.js.map +1 -0
- package/dist/planner.d.ts +29 -0
- package/dist/planner.js +511 -0
- package/dist/planner.js.map +1 -0
- package/dist/poller.d.ts +34 -0
- package/dist/poller.js +91 -0
- package/dist/poller.js.map +1 -0
- package/dist/progress.d.ts +34 -0
- package/dist/progress.js +122 -0
- package/dist/progress.js.map +1 -0
- package/dist/prompt-builder.d.ts +51 -0
- package/dist/prompt-builder.js +481 -0
- package/dist/prompt-builder.js.map +1 -0
- package/dist/provider.d.ts +14 -0
- package/dist/provider.js +278 -0
- package/dist/provider.js.map +1 -0
- package/dist/question-handler.d.ts +18 -0
- package/dist/question-handler.js +154 -0
- package/dist/question-handler.js.map +1 -0
- package/dist/question-triage.d.ts +31 -0
- package/dist/question-triage.js +175 -0
- package/dist/question-triage.js.map +1 -0
- package/dist/repo-detection.d.ts +8 -0
- package/dist/repo-detection.js +18 -0
- package/dist/repo-detection.js.map +1 -0
- package/dist/retry-context.d.ts +2 -0
- package/dist/retry-context.js +196 -0
- package/dist/retry-context.js.map +1 -0
- package/dist/router.d.ts +18 -0
- package/dist/router.js +137 -0
- package/dist/router.js.map +1 -0
- package/dist/run-artifact-types.d.ts +43 -0
- package/dist/run-artifact-types.js +2 -0
- package/dist/run-artifact-types.js.map +1 -0
- package/dist/run-summary.d.ts +14 -0
- package/dist/run-summary.js +347 -0
- package/dist/run-summary.js.map +1 -0
- package/dist/run-sync.d.ts +11 -0
- package/dist/run-sync.js +110 -0
- package/dist/run-sync.js.map +1 -0
- package/dist/run.d.ts +26 -0
- package/dist/run.js +150 -0
- package/dist/run.js.map +1 -0
- package/dist/scope-expansion.d.ts +10 -0
- package/dist/scope-expansion.js +117 -0
- package/dist/scope-expansion.js.map +1 -0
- package/dist/scope.d.ts +4 -0
- package/dist/scope.js +37 -0
- package/dist/scope.js.map +1 -0
- package/dist/scorecard.d.ts +18 -0
- package/dist/scorecard.js +128 -0
- package/dist/scorecard.js.map +1 -0
- package/dist/spec-templates.d.ts +2 -0
- package/dist/spec-templates.js +285 -0
- package/dist/spec-templates.js.map +1 -0
- package/dist/spec-validator.d.ts +8 -0
- package/dist/spec-validator.js +144 -0
- package/dist/spec-validator.js.map +1 -0
- package/dist/status.d.ts +68 -0
- package/dist/status.js +261 -0
- package/dist/status.js.map +1 -0
- package/dist/storage.d.ts +9 -0
- package/dist/storage.js +35 -0
- package/dist/storage.js.map +1 -0
- package/dist/task-executor-completion.d.ts +12 -0
- package/dist/task-executor-completion.js +67 -0
- package/dist/task-executor-completion.js.map +1 -0
- package/dist/task-executor-fallback.d.ts +20 -0
- package/dist/task-executor-fallback.js +12 -0
- package/dist/task-executor-fallback.js.map +1 -0
- package/dist/task-executor.d.ts +34 -0
- package/dist/task-executor.js +521 -0
- package/dist/task-executor.js.map +1 -0
- package/dist/task-graph.d.ts +11 -0
- package/dist/task-graph.js +226 -0
- package/dist/task-graph.js.map +1 -0
- package/dist/task-pipeline-helpers.d.ts +45 -0
- package/dist/task-pipeline-helpers.js +160 -0
- package/dist/task-pipeline-helpers.js.map +1 -0
- package/dist/task-review.d.ts +51 -0
- package/dist/task-review.js +410 -0
- package/dist/task-review.js.map +1 -0
- package/dist/transitions.d.ts +13 -0
- package/dist/transitions.js +104 -0
- package/dist/transitions.js.map +1 -0
- package/dist/types.d.ts +405 -0
- package/dist/types.js +101 -0
- package/dist/types.js.map +1 -0
- package/dist/utils.d.ts +1 -0
- package/dist/utils.js +23 -0
- package/dist/utils.js.map +1 -0
- package/dist/validation.d.ts +19 -0
- package/dist/validation.js +73 -0
- package/dist/validation.js.map +1 -0
- package/dist/worker-response.d.ts +12 -0
- package/dist/worker-response.js +60 -0
- package/dist/worker-response.js.map +1 -0
- package/dist/worker-runner.d.ts +19 -0
- package/dist/worker-runner.js +347 -0
- package/dist/worker-runner.js.map +1 -0
- package/dist/worktree-cleanup.d.ts +44 -0
- package/dist/worktree-cleanup.js +325 -0
- package/dist/worktree-cleanup.js.map +1 -0
- package/dist/worktree.d.ts +22 -0
- package/dist/worktree.js +213 -0
- package/dist/worktree.js.map +1 -0
- package/examples/spec.md +58 -0
- package/package.json +66 -0
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
import { readFileSync } from 'node:fs';
|
|
2
|
+
import { normalize, relative, resolve } from 'node:path';
|
|
3
|
+
import { fileExists } from './storage.js';
|
|
4
|
+
import { detectRepoLanguage, getImportPattern, isImportGraphSourceFile, isRelativeImport, resolveImportPath, resolvePythonImportPath, } from './import-resolution.js';
|
|
5
|
+
const MAX_IMPORT_GRAPH_EDGES = 150;
|
|
6
|
+
export function buildPlannerPrompt(input) {
|
|
7
|
+
const repoListing = buildRepoListing(input.repoFiles, input.repoRoot);
|
|
8
|
+
const completedTaskSection = buildCompletedTaskSection(input.completedTasks ?? []);
|
|
9
|
+
const extraConstraintsSection = input.extraConstraints ?? '';
|
|
10
|
+
const importGraphSection = buildImportGraphSection(input.importGraph);
|
|
11
|
+
return `You are a software planning agent. Given a spec and repo file listing, decompose the work into tasks.
|
|
12
|
+
|
|
13
|
+
## Spec
|
|
14
|
+
${input.spec}
|
|
15
|
+
|
|
16
|
+
## Repository files
|
|
17
|
+
${repoListing}${importGraphSection}
|
|
18
|
+
${completedTaskSection}
|
|
19
|
+
${extraConstraintsSection}
|
|
20
|
+
|
|
21
|
+
## Output format
|
|
22
|
+
Return a JSON object matching this schema:
|
|
23
|
+
{
|
|
24
|
+
"schema_version": 1,
|
|
25
|
+
"tasks": [
|
|
26
|
+
{
|
|
27
|
+
"id": "T1",
|
|
28
|
+
"description": "what to do",
|
|
29
|
+
"task_type": "mechanical_refactor | api_scaffold | test_generation | integration | final_validation | ...",
|
|
30
|
+
"risk": "low | medium | high",
|
|
31
|
+
"state": "pending",
|
|
32
|
+
"scope": {
|
|
33
|
+
"files": ["exact/paths.ts"],
|
|
34
|
+
"new_files": ["path/to/new-file.ts"],
|
|
35
|
+
"allow_shared_files": false
|
|
36
|
+
},
|
|
37
|
+
"dependencies": [],
|
|
38
|
+
"acceptance_checks": ["<language-appropriate check command>"],
|
|
39
|
+
"model_tier": "cheap | medium | strong",
|
|
40
|
+
"max_retries": 2,
|
|
41
|
+
"timeout_minutes": 15,
|
|
42
|
+
"planner_metadata": {
|
|
43
|
+
"planner_eligible": true,
|
|
44
|
+
"planner_reason": "small focused implementation task",
|
|
45
|
+
"execution_mode": "conservative | agentic",
|
|
46
|
+
"consolidation_signals": ["optional advisory note"]
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
]
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
## Rules
|
|
53
|
+
- Aim for 5-10 tasks total. Plans with more than 12 tasks are almost always over-decomposed. Hard limit: 15 tasks.
|
|
54
|
+
- Each task must have a unique ID (T1, T2, T3, ...)
|
|
55
|
+
- Scope overlap between non-serialized tasks is a validation ERROR — set allow_shared_files: true on both tasks or add a dependency to serialize them
|
|
56
|
+
- Keep task scope tight — target 5 or fewer scope files per task (rejection at 8 files)
|
|
57
|
+
- Dependencies must reference existing task IDs
|
|
58
|
+
- If multiple tasks touch the same shared registration or configuration file, add explicit dependencies to serialize access
|
|
59
|
+
- Scope files must be exact paths relative to repo root
|
|
60
|
+
- If a task creates a new file, list it in both scope.files AND scope.new_files so validation knows it doesn't exist yet
|
|
61
|
+
- Downstream tasks can reference files created by upstream dependencies in scope.files without adding them to new_files
|
|
62
|
+
- Acceptance checks must be runnable shell commands that exit 0 on success
|
|
63
|
+
- Acceptance checks must provide concrete proof, not only generic or manual validation language
|
|
64
|
+
- NEVER use grep/sed/awk as acceptance checks — they are brittle and reject valid implementations that use different naming. Use the repo's actual test runner and type checker instead.
|
|
65
|
+
- Every implementation task MUST include the repo's type checker and test runner as acceptance checks (e.g., "npx tsc --noEmit" and "npx vitest run" for TypeScript repos). These are the minimum bar; add more specific checks only if they add value beyond what tests already cover.
|
|
66
|
+
- Prefer cheap tier unless the task requires reasoning (medium) or is high-risk (strong)
|
|
67
|
+
- Keep tasks small and focused - one logical change per task
|
|
68
|
+
- Bundle tests WITH the implementation they test — do NOT create separate tasks for individual test cases
|
|
69
|
+
- Choose acceptance checks appropriate to the repo's language:
|
|
70
|
+
- TypeScript/JavaScript: "npx tsc --noEmit", "npx vitest run" (always both; optionally add "npx vitest run tests/specific.test.ts" for targeted coverage)
|
|
71
|
+
- Python: "python -m pytest tests/", "ruff check ." (always both)
|
|
72
|
+
- Go: "go vet ./...", "go test ./..." (always both)
|
|
73
|
+
- Rust: "cargo check", "cargo test" (always both)
|
|
74
|
+
- If completed task context is provided, preserve that completed work by planning only the remaining work
|
|
75
|
+
- Use the import graph to understand relationships between files, including unresolved local imports that may indicate missing or renamed modules
|
|
76
|
+
- IMPORTANT: If a task modifies a function's signature or adds a parameter that callers must pass, include those caller files in scope. Similarly, if the task changes behavior in a module, include the files that directly import and invoke that module. Check the import graph for these relationships. Missing scope files is the #1 cause of task failure.
|
|
77
|
+
- Do not reintroduce already-completed tasks into the new plan unless they are required as dependencies for remaining tasks
|
|
78
|
+
- Task descriptions must be self-contained — do not reference other task IDs (e.g., "T2", "T3") in the description; use dependencies instead
|
|
79
|
+
- Mark planner_metadata.planner_eligible=false for tasks that are too broad, ambiguous, or require heavy cross-cutting coordination
|
|
80
|
+
- Use execution_mode="conservative" for integration/final-validation tasks, shared-file coordination, or any task with elevated merge/conflict risk
|
|
81
|
+
- Integration/final-validation tasks should usually be narrowly scoped, depend on prior implementation tasks, and avoid catch-all ownership of many unrelated files
|
|
82
|
+
- When two non-serialized tasks touch the same file, either consolidate them into one task or emit a consolidation_signals note explaining the overlap
|
|
83
|
+
- Files over 400 lines should be scoped carefully. Prefer narrowing the task description to specific functions or sections rather than including the entire file
|
|
84
|
+
|
|
85
|
+
## Common mistakes to avoid
|
|
86
|
+
- Do NOT use source files as test runner targets (e.g., "npx vitest run src/foo.ts" is wrong — vitest runs test files, not source files). Use "npx vitest run" or "npx vitest run tests/foo.test.ts" instead.
|
|
87
|
+
- Only reference test files in acceptance checks if they already exist on disk or are listed in scope.new_files. If unsure, use the generic runner ("npx vitest run") — it runs all tests and catches regressions.
|
|
88
|
+
- If a task creates a new test file AND a new source file, put both in scope.files and scope.new_files.
|
|
89
|
+
- Each task description must fully explain what to implement WITHOUT reading other tasks. A worker sees only its own task — never write "implement the remaining parts" or "finish what T1 started" without specifying exactly what that means.
|
|
90
|
+
- When splitting work across tasks, prefer splitting by module/file rather than by layer (e.g., "add feature X to module A" + "add feature X to module B" is better than "add interfaces" + "add implementations").
|
|
91
|
+
- Avoid creating "final validation" or "integration" tasks that just re-run the same checks as prior tasks. These waste compute and rarely catch real issues. Only create them if they run a genuinely different validation (e.g., an end-to-end test that requires all prior work).
|
|
92
|
+
- NEVER create one task per test case. Group all tests for a module or feature into one task alongside the implementation. A spec with 18 tests should NOT produce 18 test tasks — it should produce 5-8 implementation tasks that each include their related tests.
|
|
93
|
+
- NEVER create standalone tasks for trivial type changes (adding optional fields to interfaces). Bundle type additions with the task that first uses them.`;
|
|
94
|
+
}
|
|
95
|
+
export function buildReplanPrompt(input) {
|
|
96
|
+
const constraintLines = input.oversizedTasks.map((t) => `- Task ${t.taskId}: estimated ${t.estimatedTokens} tokens exceeds limit of ${t.maxTokens}. ` +
|
|
97
|
+
`Split this task into smaller subtasks or reduce the number of files in scope.`);
|
|
98
|
+
const constraintSection = [
|
|
99
|
+
'',
|
|
100
|
+
'## Re-plan Constraints (Attempt ' + String(input.attemptNumber) + ')',
|
|
101
|
+
'The following tasks were rejected because their worker prompts exceeded the maximum token limit.',
|
|
102
|
+
"You MUST split or simplify these tasks so that each task's prompt fits within the token budget:",
|
|
103
|
+
...constraintLines,
|
|
104
|
+
'- Strengthen acceptance checks so they show concrete local proof of completion.',
|
|
105
|
+
'- Reconsider integration/final-validation tasks that are acting as catch-all work buckets.',
|
|
106
|
+
'- If multiple tasks overlap on the same shared file, prefer consolidation or explicit serialization.',
|
|
107
|
+
].join('\n');
|
|
108
|
+
return buildPlannerPrompt({
|
|
109
|
+
spec: input.spec,
|
|
110
|
+
repoFiles: input.repoFiles,
|
|
111
|
+
repoRoot: input.repoRoot,
|
|
112
|
+
completedTasks: input.completedTasks,
|
|
113
|
+
extraConstraints: constraintSection,
|
|
114
|
+
importGraph: input.importGraph,
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
export function buildImportGraph(repoRoot, repoFiles) {
|
|
118
|
+
const resolvedEdges = [];
|
|
119
|
+
const unresolvedEdges = [];
|
|
120
|
+
const language = detectRepoLanguage(repoFiles);
|
|
121
|
+
const importPattern = getImportPattern(language);
|
|
122
|
+
for (const repoFile of repoFiles) {
|
|
123
|
+
if (!isImportGraphSourceFile(repoFile, language)) {
|
|
124
|
+
continue;
|
|
125
|
+
}
|
|
126
|
+
const absolutePath = resolve(repoRoot, repoFile);
|
|
127
|
+
if (!fileExists(absolutePath)) {
|
|
128
|
+
continue;
|
|
129
|
+
}
|
|
130
|
+
let content = '';
|
|
131
|
+
try {
|
|
132
|
+
content = readFileSync(absolutePath, 'utf-8');
|
|
133
|
+
}
|
|
134
|
+
catch {
|
|
135
|
+
continue;
|
|
136
|
+
}
|
|
137
|
+
for (const match of content.matchAll(importPattern)) {
|
|
138
|
+
const specifier = match[1] ?? match[2];
|
|
139
|
+
if (!specifier || !isRelativeImport(specifier, language)) {
|
|
140
|
+
continue;
|
|
141
|
+
}
|
|
142
|
+
const resolvedImport = language === 'python'
|
|
143
|
+
? resolvePythonImportPath(repoRoot, absolutePath, specifier)
|
|
144
|
+
: resolveImportPath(repoRoot, absolutePath, specifier);
|
|
145
|
+
const edge = {
|
|
146
|
+
importer: repoFile,
|
|
147
|
+
specifier,
|
|
148
|
+
resolved: resolvedImport ? normalize(relative(repoRoot, resolvedImport)) : null,
|
|
149
|
+
};
|
|
150
|
+
if (edge.resolved) {
|
|
151
|
+
resolvedEdges.push(edge);
|
|
152
|
+
}
|
|
153
|
+
else {
|
|
154
|
+
unresolvedEdges.push(edge);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
return {
|
|
159
|
+
resolvedEdges,
|
|
160
|
+
unresolvedEdges,
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
export function selectImportGraphEdgesForPrompt(importGraph) {
|
|
164
|
+
const unresolvedEdges = [...importGraph.unresolvedEdges];
|
|
165
|
+
const remainingSlots = Math.max(0, MAX_IMPORT_GRAPH_EDGES - unresolvedEdges.length);
|
|
166
|
+
const resolvedEdges = importGraph.resolvedEdges.slice(0, remainingSlots);
|
|
167
|
+
return {
|
|
168
|
+
resolvedEdges,
|
|
169
|
+
unresolvedEdges,
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
function buildImportGraphSection(importGraph) {
|
|
173
|
+
if (!importGraph) {
|
|
174
|
+
return '';
|
|
175
|
+
}
|
|
176
|
+
const selected = selectImportGraphEdgesForPrompt(importGraph);
|
|
177
|
+
const lines = [
|
|
178
|
+
'',
|
|
179
|
+
'## Import graph',
|
|
180
|
+
`Resolved local dependencies found: ${String(importGraph.resolvedEdges.length)}`,
|
|
181
|
+
`Unresolved local dependencies found: ${String(importGraph.unresolvedEdges.length)}`,
|
|
182
|
+
`Edges shown below: ${String(selected.resolvedEdges.length + selected.unresolvedEdges.length)} (capped at ${String(MAX_IMPORT_GRAPH_EDGES)}; unresolved edges are always included)`,
|
|
183
|
+
];
|
|
184
|
+
if (selected.resolvedEdges.length > 0) {
|
|
185
|
+
lines.push('', '### Resolved local imports');
|
|
186
|
+
for (const edge of selected.resolvedEdges) {
|
|
187
|
+
lines.push(`- ${edge.importer} -> ${edge.resolved} (${edge.specifier})`);
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
if (selected.unresolvedEdges.length > 0) {
|
|
191
|
+
lines.push('', '### Unresolved local imports');
|
|
192
|
+
for (const edge of selected.unresolvedEdges) {
|
|
193
|
+
lines.push(`- ${edge.importer} -> UNRESOLVED (${edge.specifier})`);
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
if (selected.resolvedEdges.length === 0 && selected.unresolvedEdges.length === 0) {
|
|
197
|
+
lines.push('', '- No local import edges found');
|
|
198
|
+
}
|
|
199
|
+
return lines.join('\n');
|
|
200
|
+
}
|
|
201
|
+
function buildCompletedTaskSection(completedTasks) {
|
|
202
|
+
if (completedTasks.length === 0) {
|
|
203
|
+
return '';
|
|
204
|
+
}
|
|
205
|
+
const lines = ['', '## Already completed tasks'];
|
|
206
|
+
for (const task of completedTasks) {
|
|
207
|
+
lines.push(`- ${task.task_id}: ${task.description}`);
|
|
208
|
+
lines.push(` - status: ${task.status}`);
|
|
209
|
+
if (task.notes.trim()) {
|
|
210
|
+
lines.push(` - notes: ${task.notes.trim()}`);
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
return lines.join('\n');
|
|
214
|
+
}
|
|
215
|
+
export { validatePlanScope } from './plan-validation.js';
|
|
216
|
+
export const TEST_FILE_PATTERN = /\.(test|spec)\.(ts|js|tsx|jsx)$|^tests?\//;
|
|
217
|
+
export function isTestFile(filePath) {
|
|
218
|
+
return TEST_FILE_PATTERN.test(filePath);
|
|
219
|
+
}
|
|
220
|
+
function buildRepoListing(repoFiles, repoRoot) {
|
|
221
|
+
if (repoFiles.length === 0) {
|
|
222
|
+
return '(no tracked files)';
|
|
223
|
+
}
|
|
224
|
+
const lines = [];
|
|
225
|
+
for (const file of repoFiles) {
|
|
226
|
+
const testMarker = isTestFile(file) ? ' [test]' : '';
|
|
227
|
+
if (repoRoot) {
|
|
228
|
+
const absolutePath = resolve(repoRoot, file);
|
|
229
|
+
try {
|
|
230
|
+
const content = readFileSync(absolutePath, 'utf-8');
|
|
231
|
+
const lineCount = content.split('\n').length;
|
|
232
|
+
lines.push(`${file} (${lineCount} lines)${testMarker}`);
|
|
233
|
+
}
|
|
234
|
+
catch {
|
|
235
|
+
lines.push(`${file}${testMarker}`);
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
else {
|
|
239
|
+
lines.push(`${file}${testMarker}`);
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
return lines.join('\n');
|
|
243
|
+
}
|
|
244
|
+
//# sourceMappingURL=planner-prompt.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"planner-prompt.js","sourceRoot":"","sources":["../src/planner-prompt.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { CompletedTaskContext, PromptSizeCheckResult, StwConfig, Task, TaskGraph } from './types.js';
|
|
2
|
+
export { buildPlannerPrompt, buildReplanPrompt, buildImportGraph, validatePlanScope } from './planner-prompt.js';
|
|
3
|
+
export type { ImportGraphEdge, ImportGraph, PlanScopeValidationResult } from './planner-prompt.js';
|
|
4
|
+
export interface PlannerOptions {
|
|
5
|
+
spec: string;
|
|
6
|
+
repoRoot: string;
|
|
7
|
+
config: StwConfig;
|
|
8
|
+
runId: string;
|
|
9
|
+
completedTasks?: CompletedTaskContext[];
|
|
10
|
+
}
|
|
11
|
+
export interface PlannerResult {
|
|
12
|
+
task_graph: TaskGraph;
|
|
13
|
+
raw_response: string;
|
|
14
|
+
warnings: string[];
|
|
15
|
+
usage?: {
|
|
16
|
+
input_tokens: number;
|
|
17
|
+
output_tokens: number;
|
|
18
|
+
};
|
|
19
|
+
model?: string;
|
|
20
|
+
latency_ms?: number;
|
|
21
|
+
}
|
|
22
|
+
export declare function checkPromptSizes(tasks: Task[], repoRoot: string, maxPromptTokens: number): PromptSizeCheckResult;
|
|
23
|
+
export declare function generatePlan(options: PlannerOptions): Promise<PlannerResult>;
|
|
24
|
+
export declare function validateGeneratedGraph(graph: TaskGraph): {
|
|
25
|
+
valid: boolean;
|
|
26
|
+
errors: string[];
|
|
27
|
+
warnings: string[];
|
|
28
|
+
};
|
|
29
|
+
export declare function sanitizeBrittleAcceptanceChecks(graph: TaskGraph): void;
|