ultimate-pi 0.19.0 → 0.20.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/.agents/skills/web-retrieval/SKILL.md +163 -0
- package/.agents/skills/wiki-autoresearch/SKILL.md +6 -6
- package/.pi/SYSTEM.md +30 -12
- package/.pi/agents/harness/planning/implementation-researcher.md +1 -1
- package/.pi/agents/harness/planning/stack-researcher.md +5 -1
- package/.pi/agents/harness/running/executor.md +42 -1
- package/.pi/agents/harness/web-retrieval/web-answerer.md +35 -0
- package/.pi/agents/harness/web-retrieval/web-criteria-verifier.md +28 -0
- package/.pi/agents/harness/web-retrieval/web-gap-analyzer.md +31 -0
- package/.pi/agents/harness/web-retrieval/web-query-expander-fast.md +34 -0
- package/.pi/agents/harness/web-retrieval/web-query-expander.md +60 -0
- package/.pi/agents/harness/web-retrieval/web-summarizer.md +18 -0
- package/.pi/extensions/harness-anchored-edit.ts +141 -0
- package/.pi/extensions/harness-web-guard.ts +2 -1
- package/.pi/extensions/harness-web-tools.ts +689 -51
- package/.pi/harness/agents.manifest.json +30 -6
- package/.pi/harness/agents.policy.yaml +37 -4
- package/.pi/harness/docs/adrs/0050-agentic-web-retrieval-stack.md +46 -0
- package/.pi/harness/docs/adrs/0051-hash-anchored-executor-edits.md +41 -0
- package/.pi/harness/docs/adrs/README.md +2 -0
- package/.pi/harness/docs/harness-web-search.md +97 -0
- package/.pi/harness/docs/practice-map.md +11 -0
- package/.pi/harness/env.harness.template +9 -1
- package/.pi/harness/examples/web-heuristic-angles.project.yaml +22 -0
- package/.pi/harness/web-heuristic-angles.json +278 -0
- package/.pi/harness/web-heuristic-angles.yaml +182 -0
- package/.pi/lib/agents-policy.d.mts +4 -0
- package/.pi/lib/agents-policy.mjs +49 -1
- package/.pi/lib/agents-policy.ts +1 -0
- package/.pi/lib/harness-anchored-edit/.hash_anchors +1721 -0
- package/.pi/lib/harness-anchored-edit/anchor-state.ts +320 -0
- package/.pi/lib/harness-anchored-edit/apply-anchored-edits.ts +161 -0
- package/.pi/lib/harness-anchored-edit/edit-executor.ts +146 -0
- package/.pi/lib/harness-anchored-edit/index.ts +9 -0
- package/.pi/lib/harness-anchored-edit/line-protocol.ts +38 -0
- package/.pi/lib/harness-anchored-edit/settings.ts +1 -0
- package/.pi/lib/harness-anchored-edit/task-id.ts +8 -0
- package/.pi/lib/harness-anchored-edit/types.ts +19 -0
- package/.pi/lib/harness-lens/clients/anchored-edit-autopatch.ts +158 -0
- package/.pi/lib/harness-lens/index.ts +24 -7
- package/.pi/lib/harness-subagent-auth.ts +39 -9
- package/.pi/lib/harness-subagents-bridge.ts +24 -1
- package/.pi/lib/harness-web/artifacts.ts +200 -0
- package/.pi/lib/harness-web/cache.ts +369 -0
- package/.pi/lib/harness-web/run-cli.ts +42 -2
- package/.pi/prompts/harness-plan.md +1 -0
- package/.pi/prompts/harness-setup.md +3 -1
- package/.pi/prompts/harness-steer.md +1 -1
- package/.pi/scripts/gen-web-heuristic-angles-json.mjs +24 -0
- package/.pi/scripts/harness-anchored-edit-smoke.mjs +45 -0
- package/.pi/scripts/harness-cli-verify.sh +5 -0
- package/.pi/scripts/harness-verify.mjs +145 -0
- package/.pi/scripts/harness-web-policy-guard.mjs +1 -1
- package/.pi/scripts/harness-web.py +218 -15
- package/.pi/scripts/harness_web/deep_search.py +55 -0
- package/.pi/scripts/harness_web/evidence_bundle.py +47 -0
- package/.pi/scripts/harness_web/find_similar.py +88 -0
- package/.pi/scripts/harness_web/heuristic_angles_shipped.py +85 -0
- package/.pi/scripts/harness_web/heuristic_config.py +251 -0
- package/.pi/scripts/harness_web/highlights.py +47 -0
- package/.pi/scripts/harness_web/multi_search.py +59 -0
- package/.pi/scripts/harness_web/output.py +24 -0
- package/.pi/scripts/harness_web/query_angles.py +116 -0
- package/.pi/scripts/harness_web/rank.py +163 -0
- package/.pi/scripts/harness_web/scrape.py +30 -0
- package/.pi/scripts/run-tests.mjs +64 -0
- package/.pi/scripts/tests/test_harness_web_heuristic_config.py +132 -0
- package/.pi/scripts/tests/test_harness_web_query_angles.py +45 -0
- package/.pi/scripts/tests/test_harness_web_rank.py +56 -0
- package/AGENTS.md +2 -2
- package/CHANGELOG.md +12 -0
- package/THIRD_PARTY_NOTICES.md +7 -0
- package/package.json +7 -4
- package/vendor/pi-subagents/src/agents.ts +5 -0
- package/vendor/pi-subagents/src/subagents.ts +22 -3
- package/.agents/skills/scrapling-web/SKILL.md +0 -98
- package/.pi/extensions/00-posthog-network-bootstrap.ts +0 -11
- package/.pi/scripts/harness_web/__pycache__/__init__.cpython-314.pyc +0 -0
- package/.pi/scripts/harness_web/__pycache__/config.cpython-314.pyc +0 -0
- package/.pi/scripts/harness_web/__pycache__/output.cpython-314.pyc +0 -0
- package/.pi/scripts/harness_web/__pycache__/scrape.cpython-314.pyc +0 -0
- package/.pi/scripts/harness_web/__pycache__/search.cpython-314.pyc +0 -0
- package/.pi/scripts/harness_web/__pycache__/search_ddg.cpython-314.pyc +0 -0
- package/.pi/scripts/harness_web/__pycache__/search_searxng.cpython-314.pyc +0 -0
- package/.pi/scripts/release.sh +0 -338
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Hash-anchored read/edit — first-class harness read and edit tools (always on).
|
|
3
|
+
* @see .pi/harness/docs/adrs/0051-hash-anchored-executor-edits.md
|
|
4
|
+
*/
|
|
5
|
+
import { resolve } from "node:path";
|
|
6
|
+
import type { TextContent } from "@earendil-works/pi-ai";
|
|
7
|
+
import {
|
|
8
|
+
createReadTool,
|
|
9
|
+
type ExtensionAPI,
|
|
10
|
+
} from "@earendil-works/pi-coding-agent";
|
|
11
|
+
import { Type } from "typebox";
|
|
12
|
+
import {
|
|
13
|
+
anchoredEditTaskId,
|
|
14
|
+
applyAnchoredEditsToFile,
|
|
15
|
+
hashLinesStateful,
|
|
16
|
+
} from "../lib/harness-anchored-edit/index.js";
|
|
17
|
+
import type { AnchoredEdit } from "../lib/harness-anchored-edit/types.js";
|
|
18
|
+
|
|
19
|
+
const anchoredEditEntrySchema = Type.Object({
|
|
20
|
+
anchor: Type.String({
|
|
21
|
+
description:
|
|
22
|
+
"Start anchor from read output, format Word§exact line text (e.g. Apple§const x = 1).",
|
|
23
|
+
}),
|
|
24
|
+
end_anchor: Type.Optional(
|
|
25
|
+
Type.String({
|
|
26
|
+
description: "End anchor for replace ranges (same format as anchor).",
|
|
27
|
+
}),
|
|
28
|
+
),
|
|
29
|
+
edit_type: Type.Optional(
|
|
30
|
+
Type.Union([
|
|
31
|
+
Type.Literal("replace"),
|
|
32
|
+
Type.Literal("insert_after"),
|
|
33
|
+
Type.Literal("insert_before"),
|
|
34
|
+
]),
|
|
35
|
+
),
|
|
36
|
+
text: Type.String({ description: "New text for insert/replace." }),
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
const anchoredEditSchema = Type.Object({
|
|
40
|
+
path: Type.String({ description: "Path to the file to edit." }),
|
|
41
|
+
edits: Type.Array(anchoredEditEntrySchema, {
|
|
42
|
+
description:
|
|
43
|
+
"Batch all edits for this file in one call. Use anchors from the latest read.",
|
|
44
|
+
}),
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
const readSchema = Type.Object({
|
|
48
|
+
path: Type.String({ description: "Path to the file to read." }),
|
|
49
|
+
offset: Type.Optional(Type.Number({ description: "1-based start line." })),
|
|
50
|
+
limit: Type.Optional(Type.Number({ description: "Max lines to read." })),
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
function stripAnchoredFromReadOutput(text: string): string {
|
|
54
|
+
return text
|
|
55
|
+
.split("\n")
|
|
56
|
+
.map((line) => {
|
|
57
|
+
const idx = line.indexOf("§");
|
|
58
|
+
if (idx === -1) return line;
|
|
59
|
+
const prefix = line.slice(0, idx);
|
|
60
|
+
if (/^[A-Z][a-zA-Z]*$/.test(prefix)) {
|
|
61
|
+
return line.slice(idx + 1);
|
|
62
|
+
}
|
|
63
|
+
return line;
|
|
64
|
+
})
|
|
65
|
+
.join("\n");
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export default function harnessAnchoredEdit(pi: ExtensionAPI): void {
|
|
69
|
+
const readToolByCwd = new Map<string, ReturnType<typeof createReadTool>>();
|
|
70
|
+
|
|
71
|
+
function getReadTool(cwd: string) {
|
|
72
|
+
let tool = readToolByCwd.get(cwd);
|
|
73
|
+
if (!tool) {
|
|
74
|
+
tool = createReadTool(cwd);
|
|
75
|
+
readToolByCwd.set(cwd, tool);
|
|
76
|
+
}
|
|
77
|
+
return tool;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
pi.registerTool({
|
|
81
|
+
name: "read",
|
|
82
|
+
label: "read",
|
|
83
|
+
description:
|
|
84
|
+
"Read a file; each line is prefixed with a stable anchor (Word§line). Use those anchors in edit.",
|
|
85
|
+
parameters: readSchema,
|
|
86
|
+
async execute(toolCallId, params, signal, onUpdate, ctx) {
|
|
87
|
+
const base = getReadTool(ctx.cwd);
|
|
88
|
+
const result = await base.execute(
|
|
89
|
+
toolCallId,
|
|
90
|
+
params,
|
|
91
|
+
signal,
|
|
92
|
+
onUpdate,
|
|
93
|
+
ctx,
|
|
94
|
+
);
|
|
95
|
+
const taskId = anchoredEditTaskId(ctx);
|
|
96
|
+
const absolutePath = resolve(ctx.cwd, params.path);
|
|
97
|
+
for (const block of result.content) {
|
|
98
|
+
if (block.type !== "text") continue;
|
|
99
|
+
const plain = stripAnchoredFromReadOutput(block.text);
|
|
100
|
+
block.text = hashLinesStateful(absolutePath, plain, taskId);
|
|
101
|
+
}
|
|
102
|
+
return result;
|
|
103
|
+
},
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
pi.registerTool({
|
|
107
|
+
name: "edit",
|
|
108
|
+
label: "edit",
|
|
109
|
+
description:
|
|
110
|
+
"Edit using line anchors from read. Batch multiple edits per file. For replace, set end_anchor (defaults to anchor for single-line replace).",
|
|
111
|
+
parameters: anchoredEditSchema,
|
|
112
|
+
promptGuidelines: [
|
|
113
|
+
"Use anchors from the latest read output (Word§line).",
|
|
114
|
+
"Batch all edits for one file in a single edit call.",
|
|
115
|
+
"For renames across files: sg -p to locate, then minimal anchored edits — do not use replace_symbol tools.",
|
|
116
|
+
],
|
|
117
|
+
async execute(_toolCallId, params, _signal, _onUpdate, ctx) {
|
|
118
|
+
const absolutePath = resolve(ctx.cwd, params.path);
|
|
119
|
+
const taskId = anchoredEditTaskId(ctx);
|
|
120
|
+
const edits = params.edits as AnchoredEdit[];
|
|
121
|
+
|
|
122
|
+
const result = await applyAnchoredEditsToFile(
|
|
123
|
+
absolutePath,
|
|
124
|
+
edits,
|
|
125
|
+
taskId,
|
|
126
|
+
);
|
|
127
|
+
|
|
128
|
+
if (!result.ok) {
|
|
129
|
+
return {
|
|
130
|
+
content: [{ type: "text", text: result.error }] as TextContent[],
|
|
131
|
+
details: { error: true },
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
return {
|
|
136
|
+
content: [{ type: "text", text: result.message }] as TextContent[],
|
|
137
|
+
details: result.details,
|
|
138
|
+
};
|
|
139
|
+
},
|
|
140
|
+
});
|
|
141
|
+
}
|
|
@@ -5,7 +5,8 @@
|
|
|
5
5
|
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
|
6
6
|
|
|
7
7
|
const BLOCK_REASON =
|
|
8
|
-
"harness-web-guard: use web_search (
|
|
8
|
+
"harness-web-guard: use web_search (tier=deep for research), web_fetch, web_find_similar, or web_contents — " +
|
|
9
|
+
"not raw curl/wget/firecrawl/scrapling fetch. See web-retrieval skill. " +
|
|
9
10
|
"Setup may use harness-web.py status directly.";
|
|
10
11
|
|
|
11
12
|
const ALLOW_PATTERNS = [
|