@piagent/platform 1.2.7 → 1.2.9
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/CHANGELOG.md +43 -0
- package/README.md +2 -2
- package/docs/command-reference-vietnamese.md +4 -4
- package/docs/context-engine.md +11 -1
- package/docs/distribution-standard.md +7 -7
- package/docs/operator-manual-vietnamese.md +7 -7
- package/docs/publishing-for-teams.md +2 -0
- package/docs/release-install-policy.md +6 -6
- package/docs/security-threat-model.md +2 -1
- package/docs/subagent-orchestration-capabilities.md +2 -2
- package/docs/subagents-and-multiagent.md +5 -5
- package/docs/team-onboarding.md +2 -2
- package/docs-site/architecture.html +1 -1
- package/docs-site/commands.html +1 -1
- package/docs-site/context-engine.html +1 -1
- package/docs-site/index.html +1 -1
- package/docs-site/mcp-approval.html +1 -1
- package/docs-site/mcp-auth.html +1 -1
- package/docs-site/mcp-servers.html +1 -1
- package/docs-site/mcp.html +1 -1
- package/docs-site/permissions.html +1 -1
- package/docs-site/profiles.html +1 -1
- package/docs-site/quickstart.html +1 -1
- package/docs-site/runtime.html +1 -1
- package/docs-site/scope.html +1 -1
- package/docs-site/security.html +1 -1
- package/docs-site/team.html +1 -1
- package/docs-site/workflows.html +1 -1
- package/package.json +1 -1
- package/packages/piagent-core/capabilities/capability-core.js +3 -0
- package/packages/piagent-core/extensions/context-engine.js +149 -71
- package/packages/piagent-core/extensions/context-index-policy.js +136 -0
- package/packages/piagent-core/extensions/piagent-guard.ts +67 -67
- package/packages/piagent-core/package.json +1 -1
- package/scripts/audit-runtime-host.sh +1 -1
- package/scripts/context-engine.mjs +22 -20
- package/scripts/install-global.sh +10 -5
- package/scripts/setup.sh +9 -2
- package/scripts/team-doctor.sh +3 -0
- package/scripts/update-global.mjs +1 -1
- package/scripts/verify-local.sh +4 -2
|
@@ -81,10 +81,15 @@ import {
|
|
|
81
81
|
buildTestImpact,
|
|
82
82
|
classifyContextTask,
|
|
83
83
|
contextIndexV2Status,
|
|
84
|
+
ensureContextIndexV2,
|
|
84
85
|
estimateContextTokens,
|
|
85
86
|
searchContextIndexV2,
|
|
86
87
|
toolResultFingerprint
|
|
87
88
|
} from "./context-engine.js";
|
|
89
|
+
import {
|
|
90
|
+
contextIndexExcludePatterns,
|
|
91
|
+
effectiveProtectedPaths
|
|
92
|
+
} from "./context-index-policy.js";
|
|
88
93
|
|
|
89
94
|
import type { ActionClassification } from "./guard-shell-analysis.ts";
|
|
90
95
|
|
|
@@ -99,7 +104,6 @@ import type {
|
|
|
99
104
|
ContextIndexNodeKind,
|
|
100
105
|
ContextIndexSettings,
|
|
101
106
|
ContextPreflight,
|
|
102
|
-
EffectiveProtectedPaths,
|
|
103
107
|
ExecPolicyConfig,
|
|
104
108
|
ExternalActionPolicyConfig,
|
|
105
109
|
FinalGateConfig,
|
|
@@ -1921,34 +1925,6 @@ function uniqueStrings(values: string[]): string[] {
|
|
|
1921
1925
|
return [...new Set(values.filter((value) => typeof value === "string" && value.trim().length > 0))];
|
|
1922
1926
|
}
|
|
1923
1927
|
|
|
1924
|
-
function effectiveProtectedPaths(policy: BasePolicy, profile: ProjectProfile): EffectiveProtectedPaths {
|
|
1925
|
-
const baseReadProtectedPaths = policy.shellProtectedPaths ?? policy.protectedPaths;
|
|
1926
|
-
const profileProtectedPaths = profile.protectedPaths ?? [];
|
|
1927
|
-
const profileShellProtectedPaths = profile.shellProtectedPaths ?? profile.protectedPaths ?? [];
|
|
1928
|
-
const readOnlyPaths = profile.readOnlyPaths ?? [];
|
|
1929
|
-
const contextIndexStatePath = resolveContextIndexSettings(profile).path;
|
|
1930
|
-
return {
|
|
1931
|
-
readProtectedPaths: uniqueStrings([
|
|
1932
|
-
...baseReadProtectedPaths,
|
|
1933
|
-
...profileProtectedPaths,
|
|
1934
|
-
contextIndexStatePath
|
|
1935
|
-
]),
|
|
1936
|
-
writeProtectedPaths: uniqueStrings([
|
|
1937
|
-
...policy.protectedPaths,
|
|
1938
|
-
...profileProtectedPaths,
|
|
1939
|
-
...readOnlyPaths,
|
|
1940
|
-
contextIndexStatePath
|
|
1941
|
-
]),
|
|
1942
|
-
shellProtectedPaths: uniqueStrings([
|
|
1943
|
-
...baseReadProtectedPaths,
|
|
1944
|
-
...profileShellProtectedPaths,
|
|
1945
|
-
...readOnlyPaths,
|
|
1946
|
-
contextIndexStatePath
|
|
1947
|
-
]),
|
|
1948
|
-
readOnlyPaths: uniqueStrings(readOnlyPaths)
|
|
1949
|
-
};
|
|
1950
|
-
}
|
|
1951
|
-
|
|
1952
1928
|
function classifyExternalAction(toolName: string, input: Record<string, unknown>, policy: BasePolicy): {
|
|
1953
1929
|
decision: "not-external" | "safe-read" | "confirm";
|
|
1954
1930
|
provider?: string;
|
|
@@ -4480,7 +4456,9 @@ export default function piagentGuard(pi: ExtensionAPI) {
|
|
|
4480
4456
|
if (updateNotice) ctx.ui.notify(updateNotice, "info");
|
|
4481
4457
|
let engineStatus: unknown;
|
|
4482
4458
|
try {
|
|
4483
|
-
engineStatus = await contextIndexV2Status(ctx.cwd
|
|
4459
|
+
engineStatus = await contextIndexV2Status(ctx.cwd, {
|
|
4460
|
+
excludePatterns: contextIndexExcludePatterns(policy, profile)
|
|
4461
|
+
});
|
|
4484
4462
|
} catch (error) {
|
|
4485
4463
|
engineStatus = { exists: false, error: error instanceof Error ? error.message : String(error) };
|
|
4486
4464
|
}
|
|
@@ -4590,7 +4568,12 @@ export default function piagentGuard(pi: ExtensionAPI) {
|
|
|
4590
4568
|
autoPackedPrompts.add(signal.promptHash);
|
|
4591
4569
|
if (autoPackedPrompts.size > 50) autoPackedPrompts.delete(autoPackedPrompts.values().next().value as string);
|
|
4592
4570
|
try {
|
|
4593
|
-
const
|
|
4571
|
+
const excludePatterns = contextIndexExcludePatterns(policy, loadProfileFromContext(ctx));
|
|
4572
|
+
const ensured = await ensureContextIndexV2(ctx.cwd, {
|
|
4573
|
+
excludePatterns,
|
|
4574
|
+
rebuildMissing: false
|
|
4575
|
+
});
|
|
4576
|
+
const status = ensured.status;
|
|
4594
4577
|
if (!status.exists || status.stale) {
|
|
4595
4578
|
telemetry(ctx, {
|
|
4596
4579
|
event: "context_pack",
|
|
@@ -4603,7 +4586,12 @@ export default function piagentGuard(pi: ExtensionAPI) {
|
|
|
4603
4586
|
return;
|
|
4604
4587
|
}
|
|
4605
4588
|
const budgetTokens = signal.lane === "high-risk" ? 1_200 : signal.lane === "tiny" ? 500 : 900;
|
|
4606
|
-
const pack = await buildContextPack(ctx.cwd, query, {
|
|
4589
|
+
const pack = await buildContextPack(ctx.cwd, query, {
|
|
4590
|
+
budgetTokens,
|
|
4591
|
+
includeCode: false,
|
|
4592
|
+
limit: 12,
|
|
4593
|
+
excludePatterns
|
|
4594
|
+
});
|
|
4607
4595
|
telemetry(ctx, {
|
|
4608
4596
|
event: "context_pack",
|
|
4609
4597
|
queryHash: pack.queryHash,
|
|
@@ -5029,17 +5017,11 @@ export default function piagentGuard(pi: ExtensionAPI) {
|
|
|
5029
5017
|
}),
|
|
5030
5018
|
async execute(_toolCallId, params, _signal, _onUpdate, ctx) {
|
|
5031
5019
|
const profile = loadProfileFromContext(ctx);
|
|
5032
|
-
const
|
|
5033
|
-
const excludePatterns = Array.from(new Set([
|
|
5034
|
-
...pathPolicy.readProtectedPaths,
|
|
5035
|
-
...pathPolicy.writeProtectedPaths,
|
|
5036
|
-
".pi/context-index.json",
|
|
5037
|
-
".pi/piagent-state/**"
|
|
5038
|
-
]));
|
|
5020
|
+
const excludePatterns = contextIndexExcludePatterns(policy, profile);
|
|
5039
5021
|
let result: unknown;
|
|
5040
5022
|
let text: string;
|
|
5041
5023
|
if (params.action === "status") {
|
|
5042
|
-
result = await contextIndexV2Status(ctx.cwd);
|
|
5024
|
+
result = await contextIndexV2Status(ctx.cwd, { excludePatterns });
|
|
5043
5025
|
const status = result as Awaited<ReturnType<typeof contextIndexV2Status>>;
|
|
5044
5026
|
text = [
|
|
5045
5027
|
`indexV2: ${status.exists ? "ready" : "missing"}`,
|
|
@@ -5062,12 +5044,13 @@ export default function piagentGuard(pi: ExtensionAPI) {
|
|
|
5062
5044
|
].join("\n");
|
|
5063
5045
|
} else if (params.action === "search") {
|
|
5064
5046
|
if (!params.query?.trim()) throw new Error("query is required for context search");
|
|
5065
|
-
|
|
5066
|
-
|
|
5067
|
-
|
|
5068
|
-
|
|
5069
|
-
}
|
|
5070
|
-
|
|
5047
|
+
const ensured = await ensureContextIndexV2(ctx.cwd, {
|
|
5048
|
+
excludePatterns,
|
|
5049
|
+
refresh: params.refresh,
|
|
5050
|
+
rebuildMissing: true
|
|
5051
|
+
});
|
|
5052
|
+
const status = ensured.status;
|
|
5053
|
+
result = await searchContextIndexV2(ctx.cwd, params.query, { limit: 15, excludePatterns });
|
|
5071
5054
|
const search = result as Awaited<ReturnType<typeof searchContextIndexV2>>;
|
|
5072
5055
|
text = [
|
|
5073
5056
|
`confidence: ${search.confidence}`,
|
|
@@ -5076,20 +5059,23 @@ export default function piagentGuard(pi: ExtensionAPI) {
|
|
|
5076
5059
|
].join("\n");
|
|
5077
5060
|
} else if (params.action === "pack") {
|
|
5078
5061
|
if (!params.query?.trim()) throw new Error("query is required for a context pack");
|
|
5079
|
-
|
|
5080
|
-
|
|
5081
|
-
|
|
5082
|
-
|
|
5083
|
-
}
|
|
5062
|
+
const ensured = await ensureContextIndexV2(ctx.cwd, {
|
|
5063
|
+
excludePatterns,
|
|
5064
|
+
refresh: params.refresh,
|
|
5065
|
+
rebuildMissing: true
|
|
5066
|
+
});
|
|
5067
|
+
const status = ensured.status;
|
|
5084
5068
|
const pack = await buildContextPack(ctx.cwd, params.query, {
|
|
5085
5069
|
budgetTokens: params.budgetTokens ?? 6_000,
|
|
5086
5070
|
includeCode: true,
|
|
5087
|
-
limit: 18
|
|
5071
|
+
limit: 18,
|
|
5072
|
+
excludePatterns
|
|
5088
5073
|
});
|
|
5089
5074
|
result = { ...pack, text: undefined, status };
|
|
5090
5075
|
text = pack.text;
|
|
5091
5076
|
} else if (params.action === "impact") {
|
|
5092
|
-
|
|
5077
|
+
await ensureContextIndexV2(ctx.cwd, { excludePatterns, rebuildMissing: false });
|
|
5078
|
+
result = await buildTestImpact(ctx.cwd, params.files ?? [], { excludePatterns });
|
|
5093
5079
|
const impact = result as Awaited<ReturnType<typeof buildTestImpact>>;
|
|
5094
5080
|
text = [
|
|
5095
5081
|
`changed: ${impact.changedFiles.join(", ") || "none"}`,
|
|
@@ -5139,7 +5125,9 @@ export default function piagentGuard(pi: ExtensionAPI) {
|
|
|
5139
5125
|
const contextIndex = buildContextIndexStatus(ctx.cwd, profile);
|
|
5140
5126
|
let contextEngine: Awaited<ReturnType<typeof contextIndexV2Status>> | { exists: false; warnings: string[] };
|
|
5141
5127
|
try {
|
|
5142
|
-
contextEngine = await contextIndexV2Status(ctx.cwd
|
|
5128
|
+
contextEngine = await contextIndexV2Status(ctx.cwd, {
|
|
5129
|
+
excludePatterns: contextIndexExcludePatterns(policy, profile)
|
|
5130
|
+
});
|
|
5143
5131
|
} catch (error) {
|
|
5144
5132
|
contextEngine = { exists: false, warnings: [error instanceof Error ? error.message : String(error)] };
|
|
5145
5133
|
}
|
|
@@ -7232,7 +7220,9 @@ export default function piagentGuard(pi: ExtensionAPI) {
|
|
|
7232
7220
|
|
|
7233
7221
|
async function emitContextEngineStatus(ctx: ExtensionContext): Promise<void> {
|
|
7234
7222
|
try {
|
|
7235
|
-
const status = await contextIndexV2Status(ctx.cwd
|
|
7223
|
+
const status = await contextIndexV2Status(ctx.cwd, {
|
|
7224
|
+
excludePatterns: contextIndexExcludePatterns(policy, loadProfileFromContext(ctx))
|
|
7225
|
+
});
|
|
7236
7226
|
emitRuntimeMessage(ctx, "piagent-context-engine-status", [
|
|
7237
7227
|
`contextEngine: ${status.exists ? "ready" : "missing"}`,
|
|
7238
7228
|
`path: ${status.path}`,
|
|
@@ -7251,15 +7241,10 @@ export default function piagentGuard(pi: ExtensionAPI) {
|
|
|
7251
7241
|
|
|
7252
7242
|
async function rebuildContextEngine(ctx: ExtensionContext): Promise<void> {
|
|
7253
7243
|
const profile = loadProfileFromContext(ctx);
|
|
7254
|
-
const
|
|
7244
|
+
const excludePatterns = contextIndexExcludePatterns(policy, profile);
|
|
7255
7245
|
try {
|
|
7256
7246
|
const result = await buildContextIndexV2(ctx.cwd, {
|
|
7257
|
-
excludePatterns
|
|
7258
|
-
...pathPolicy.readProtectedPaths,
|
|
7259
|
-
...pathPolicy.writeProtectedPaths,
|
|
7260
|
-
".pi/context-index.json",
|
|
7261
|
-
".pi/piagent-state/**"
|
|
7262
|
-
]))
|
|
7247
|
+
excludePatterns
|
|
7263
7248
|
});
|
|
7264
7249
|
telemetry(ctx, { event: "context_engine_action", action: "rebuild", ...result });
|
|
7265
7250
|
emitRuntimeMessage(ctx, "piagent-context-engine-rebuild", [
|
|
@@ -7275,9 +7260,13 @@ export default function piagentGuard(pi: ExtensionAPI) {
|
|
|
7275
7260
|
}
|
|
7276
7261
|
|
|
7277
7262
|
async function emitContextEngineSearch(ctx: ExtensionContext, query: string): Promise<boolean> {
|
|
7278
|
-
const
|
|
7263
|
+
const excludePatterns = contextIndexExcludePatterns(policy, loadProfileFromContext(ctx));
|
|
7264
|
+
const { status } = await ensureContextIndexV2(ctx.cwd, {
|
|
7265
|
+
excludePatterns,
|
|
7266
|
+
rebuildMissing: false
|
|
7267
|
+
});
|
|
7279
7268
|
if (!status.exists || !query.trim()) return false;
|
|
7280
|
-
const search = await searchContextIndexV2(ctx.cwd, query, { limit: 12 });
|
|
7269
|
+
const search = await searchContextIndexV2(ctx.cwd, query, { limit: 12, excludePatterns });
|
|
7281
7270
|
emitRuntimeMessage(ctx, "piagent-context-engine-search", [
|
|
7282
7271
|
`confidence: ${search.confidence}`,
|
|
7283
7272
|
`stale: ${status.stale ? "yes" : "no"}`,
|
|
@@ -7291,12 +7280,21 @@ export default function piagentGuard(pi: ExtensionAPI) {
|
|
|
7291
7280
|
emitRuntimeMessage(ctx, "piagent-context-pack-help", "Usage: /context pack <task or symbol>");
|
|
7292
7281
|
return;
|
|
7293
7282
|
}
|
|
7294
|
-
const
|
|
7283
|
+
const excludePatterns = contextIndexExcludePatterns(policy, loadProfileFromContext(ctx));
|
|
7284
|
+
const { status } = await ensureContextIndexV2(ctx.cwd, {
|
|
7285
|
+
excludePatterns,
|
|
7286
|
+
rebuildMissing: false
|
|
7287
|
+
});
|
|
7295
7288
|
if (!status.exists) {
|
|
7296
7289
|
emitRuntimeMessage(ctx, "piagent-context-pack-help", "Context Engine index is missing. Run /context rebuild first.");
|
|
7297
7290
|
return;
|
|
7298
7291
|
}
|
|
7299
|
-
const pack = await buildContextPack(ctx.cwd, query, {
|
|
7292
|
+
const pack = await buildContextPack(ctx.cwd, query, {
|
|
7293
|
+
budgetTokens: 1_500,
|
|
7294
|
+
includeCode: false,
|
|
7295
|
+
limit: 15,
|
|
7296
|
+
excludePatterns
|
|
7297
|
+
});
|
|
7300
7298
|
telemetry(ctx, {
|
|
7301
7299
|
event: "context_pack",
|
|
7302
7300
|
queryHash: pack.queryHash,
|
|
@@ -7318,7 +7316,9 @@ export default function piagentGuard(pi: ExtensionAPI) {
|
|
|
7318
7316
|
|
|
7319
7317
|
async function emitTestImpact(ctx: ExtensionContext, raw: string): Promise<void> {
|
|
7320
7318
|
const files = raw.split(/\s+/).map((file) => file.trim()).filter(Boolean);
|
|
7321
|
-
const
|
|
7319
|
+
const excludePatterns = contextIndexExcludePatterns(policy, loadProfileFromContext(ctx));
|
|
7320
|
+
await ensureContextIndexV2(ctx.cwd, { excludePatterns, rebuildMissing: false });
|
|
7321
|
+
const impact = await buildTestImpact(ctx.cwd, files, { excludePatterns });
|
|
7322
7322
|
emitRuntimeMessage(ctx, "piagent-context-impact", [
|
|
7323
7323
|
`changed: ${impact.changedFiles.join(", ") || "none"}`,
|
|
7324
7324
|
`impacted: ${impact.impactedFiles.map((item) => `${item.path} via ${item.via}`).join(", ") || "none"}`,
|
|
@@ -29,7 +29,7 @@ PI_AI_VERSION="$(require_exact_peer "@earendil-works/pi-ai")"
|
|
|
29
29
|
TYPEBOX_VERSION="$(require_exact_peer "typebox")"
|
|
30
30
|
PI_MCP_ADAPTER_VERSION="2.15.0"
|
|
31
31
|
PI_SUBAGENTS_VERSION="0.38.0"
|
|
32
|
-
PI_WEB_ACCESS_VERSION="0.
|
|
32
|
+
PI_WEB_ACCESS_VERSION="0.17.0"
|
|
33
33
|
|
|
34
34
|
if [[ "$PI_CODING_VERSION" != "$PI_AI_VERSION" ]]; then
|
|
35
35
|
echo "FAIL: Pi Coding Agent and Pi AI host versions must match." >&2
|
|
@@ -9,9 +9,12 @@ import {
|
|
|
9
9
|
buildContextPack,
|
|
10
10
|
buildTestImpact,
|
|
11
11
|
contextIndexV2Status,
|
|
12
|
+
ensureContextIndexV2,
|
|
12
13
|
searchContextIndexV2
|
|
13
14
|
} from "../packages/piagent-core/extensions/context-engine.js";
|
|
15
|
+
import { loadProjectContextIndexPolicy } from "../packages/piagent-core/extensions/context-index-policy.js";
|
|
14
16
|
|
|
17
|
+
const platformRoot = path.resolve(import.meta.dirname, "..");
|
|
15
18
|
function usage() {
|
|
16
19
|
return [
|
|
17
20
|
"Pi Context Engine",
|
|
@@ -53,21 +56,6 @@ function parseArgs(argv) {
|
|
|
53
56
|
return { command, project, json, tokens, values };
|
|
54
57
|
}
|
|
55
58
|
|
|
56
|
-
function projectExcludes(project) {
|
|
57
|
-
const target = path.join(project, ".pi", "piagent-profile.json");
|
|
58
|
-
try {
|
|
59
|
-
const profile = JSON.parse(fs.readFileSync(target, "utf8"));
|
|
60
|
-
return [
|
|
61
|
-
...(Array.isArray(profile.protectedPaths) ? profile.protectedPaths : []),
|
|
62
|
-
...(Array.isArray(profile.shellProtectedPaths) ? profile.shellProtectedPaths : []),
|
|
63
|
-
".pi/context-index.json",
|
|
64
|
-
".pi/piagent-state/**"
|
|
65
|
-
];
|
|
66
|
-
} catch {
|
|
67
|
-
return [".pi/context-index.json", ".pi/piagent-state/**"];
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
|
|
71
59
|
function print(value, json) {
|
|
72
60
|
if (json || typeof value === "string") {
|
|
73
61
|
process.stdout.write(`${typeof value === "string" ? value : JSON.stringify(value, null, 2)}\n`);
|
|
@@ -88,21 +76,35 @@ if (!fs.existsSync(parsed.project) || !fs.statSync(parsed.project).isDirectory()
|
|
|
88
76
|
}
|
|
89
77
|
|
|
90
78
|
try {
|
|
79
|
+
const contextPolicy = ["status", "show", "rebuild", "build", "refresh", "search", "pack", "impact", "tests"]
|
|
80
|
+
.includes(parsed.command)
|
|
81
|
+
? loadProjectContextIndexPolicy(platformRoot, parsed.project, {
|
|
82
|
+
profilePath: process.env.PIAGENT_PROFILE
|
|
83
|
+
})
|
|
84
|
+
: undefined;
|
|
85
|
+
const excludePatterns = contextPolicy?.excludePatterns ?? [];
|
|
91
86
|
if (["status", "show"].includes(parsed.command)) {
|
|
92
|
-
print(await contextIndexV2Status(parsed.project), parsed.json);
|
|
87
|
+
print(await contextIndexV2Status(parsed.project, { excludePatterns }), parsed.json);
|
|
93
88
|
} else if (["rebuild", "build", "refresh"].includes(parsed.command)) {
|
|
94
|
-
print(await buildContextIndexV2(parsed.project, { excludePatterns
|
|
89
|
+
print(await buildContextIndexV2(parsed.project, { excludePatterns }), parsed.json);
|
|
95
90
|
} else if (parsed.command === "search") {
|
|
96
91
|
const query = parsed.values.join(" ").trim();
|
|
97
92
|
if (!query) throw new Error("search requires a query");
|
|
98
|
-
|
|
93
|
+
await ensureContextIndexV2(parsed.project, { excludePatterns, rebuildMissing: true });
|
|
94
|
+
print(await searchContextIndexV2(parsed.project, query, { limit: 15, excludePatterns }), parsed.json);
|
|
99
95
|
} else if (parsed.command === "pack") {
|
|
100
96
|
const query = parsed.values.join(" ").trim();
|
|
101
97
|
if (!query) throw new Error("pack requires a task or query");
|
|
102
|
-
|
|
98
|
+
await ensureContextIndexV2(parsed.project, { excludePatterns, rebuildMissing: true });
|
|
99
|
+
const pack = await buildContextPack(parsed.project, query, {
|
|
100
|
+
budgetTokens: parsed.tokens,
|
|
101
|
+
includeCode: true,
|
|
102
|
+
excludePatterns
|
|
103
|
+
});
|
|
103
104
|
print(parsed.json ? pack : pack.text, parsed.json);
|
|
104
105
|
} else if (["impact", "tests"].includes(parsed.command)) {
|
|
105
|
-
|
|
106
|
+
await ensureContextIndexV2(parsed.project, { excludePatterns, rebuildMissing: false });
|
|
107
|
+
print(await buildTestImpact(parsed.project, parsed.values, { excludePatterns }), parsed.json);
|
|
106
108
|
} else if (["efficiency", "stats", "waste"].includes(parsed.command)) {
|
|
107
109
|
print(buildContextEfficiencyReport(parsed.project), parsed.json);
|
|
108
110
|
} else {
|
|
@@ -4,7 +4,7 @@ set -euo pipefail
|
|
|
4
4
|
usage() {
|
|
5
5
|
cat <<'USAGE'
|
|
6
6
|
Usage:
|
|
7
|
-
scripts/install-global.sh [--stable|--dev|--local|--channel <stable|dev|local>] [--version <tag>] [--resolve-tag] [--package-source <source>] [--dry-run] [--with-mcp|--no-mcp] [--mcp-preset <preset>] [--with-subagents|--no-subagents] [--subagents-preset <preset>] [--with-web-access] [--with-herdr] [--model-scope <preset>]
|
|
7
|
+
scripts/install-global.sh [--stable|--dev|--local|--channel <stable|dev|local>] [--version <tag>] [--resolve-tag] [--package-source <source>] [--dry-run] [--with-mcp|--no-mcp] [--mcp-preset <preset>] [--with-subagents|--no-subagents] [--subagents-preset <preset>] [--with-web-access|--no-web-access] [--with-herdr] [--model-scope <preset>]
|
|
8
8
|
|
|
9
9
|
Purpose:
|
|
10
10
|
Install the piagent Pi package into the current user's global Pi settings.
|
|
@@ -42,7 +42,7 @@ Notes:
|
|
|
42
42
|
- An existing pi-subagents install is preserved and upgraded automatically.
|
|
43
43
|
New installs remain opt-in with --with-subagents; use --no-subagents to skip an existing install.
|
|
44
44
|
- Subagents preset defaults to safe: compact tool description, bounded concurrency/depth.
|
|
45
|
-
- Web access is
|
|
45
|
+
- Web access is installed by default so the builtin `researcher` subagent can browse/fetch web sources inside Pi. Skip it with --no-web-access.
|
|
46
46
|
USAGE
|
|
47
47
|
}
|
|
48
48
|
|
|
@@ -62,7 +62,7 @@ WITH_SUBAGENTS=false
|
|
|
62
62
|
SUBAGENTS_EXPLICIT=false
|
|
63
63
|
SUBAGENTS_PRESET="safe"
|
|
64
64
|
SUBAGENTS_MODEL_SCOPE="none"
|
|
65
|
-
WITH_WEB_ACCESS=
|
|
65
|
+
WITH_WEB_ACCESS=true
|
|
66
66
|
WITH_HERDR=false
|
|
67
67
|
CONFIGURE_MODEL_SCOPE=true
|
|
68
68
|
MODEL_SCOPE_PRESET="full"
|
|
@@ -76,10 +76,10 @@ RESOLVED_PACKAGE_COMMIT=""
|
|
|
76
76
|
CLI_PACKAGE_SELECTOR=""
|
|
77
77
|
PI_MCP_ADAPTER_SOURCE="npm:pi-mcp-adapter@2.15.0"
|
|
78
78
|
PI_SUBAGENTS_SOURCE="npm:pi-subagents@0.38.0"
|
|
79
|
-
PI_WEB_ACCESS_SOURCE="npm:pi-web-access@0.
|
|
79
|
+
PI_WEB_ACCESS_SOURCE="npm:pi-web-access@0.17.0"
|
|
80
80
|
PI_MCP_ADAPTER_INTEGRITY="sha512-HJAVt2I5IB52pKpSUYbVJnzOmuXYBCc/ZrI9ylHxYQWmE7p75j7aWzsHe734EFN+gL7WaM23CTX3eYHz2THKBA=="
|
|
81
81
|
PI_SUBAGENTS_INTEGRITY="sha512-8wGQiX6rkR5J4V+AnWtQg3+LmC+cHnZIM1f/VWTjCTkVmcoKdeLsTAYG6BS2yKAugyEUjNUGj3vE5d9nj9m61A=="
|
|
82
|
-
PI_WEB_ACCESS_INTEGRITY="sha512-
|
|
82
|
+
PI_WEB_ACCESS_INTEGRITY="sha512-rDAhkIzYtBmCCNgstTJ/zFnw91V64TQqhqLOeGXFxmnJaxE45nj+L4BkUPMYSUb3WFexDDYdGlONyBLLKE4eVw=="
|
|
83
83
|
|
|
84
84
|
require_value() {
|
|
85
85
|
local option="$1"
|
|
@@ -400,6 +400,10 @@ while [[ $# -gt 0 ]]; do
|
|
|
400
400
|
WITH_WEB_ACCESS=true
|
|
401
401
|
shift
|
|
402
402
|
;;
|
|
403
|
+
--no-web-access)
|
|
404
|
+
WITH_WEB_ACCESS=false
|
|
405
|
+
shift
|
|
406
|
+
;;
|
|
403
407
|
--with-herdr)
|
|
404
408
|
WITH_HERDR=true
|
|
405
409
|
shift
|
|
@@ -627,6 +631,7 @@ if [[ "$WITH_WEB_ACCESS" == true ]]; then
|
|
|
627
631
|
if [[ "$DRY_RUN" == false ]]; then
|
|
628
632
|
verify_npm_integrity "$PI_WEB_ACCESS_SOURCE" "$PI_WEB_ACCESS_INTEGRITY"
|
|
629
633
|
fi
|
|
634
|
+
remove_existing_npm_package_sources "pi-web-access"
|
|
630
635
|
run_cmd pi install "$PI_WEB_ACCESS_SOURCE"
|
|
631
636
|
fi
|
|
632
637
|
|
package/scripts/setup.sh
CHANGED
|
@@ -30,7 +30,8 @@ Options:
|
|
|
30
30
|
Configure pi-subagents runtime baseline (default: safe)
|
|
31
31
|
--subagents-model-scope <none|piagent|codex|claude> model family for subagents
|
|
32
32
|
Optional subagent model allowlist (default: none)
|
|
33
|
-
--with-web-access
|
|
33
|
+
--with-web-access / --no-web-access
|
|
34
|
+
Install/skip pi-web-access for builtin `researcher` subagent (default: install)
|
|
34
35
|
--with-herdr / --no-herdr Install/skip Herdr Pi integration if herdr exists (default: install)
|
|
35
36
|
--model-scope <full|codex|claude> model families to enable
|
|
36
37
|
Configure Pi enabledModels for selector/cycling (default: full)
|
|
@@ -73,7 +74,7 @@ MCP_PRESET_EXPLICIT=false
|
|
|
73
74
|
WITH_SUBAGENTS=true
|
|
74
75
|
SUBAGENTS_PRESET="safe"
|
|
75
76
|
SUBAGENTS_MODEL_SCOPE="none"
|
|
76
|
-
WITH_WEB_ACCESS=
|
|
77
|
+
WITH_WEB_ACCESS=true
|
|
77
78
|
WITH_HERDR=true
|
|
78
79
|
CONFIGURE_MODEL_SCOPE=true
|
|
79
80
|
MODEL_SCOPE_PRESET="full"
|
|
@@ -154,6 +155,10 @@ while [[ $# -gt 0 ]]; do
|
|
|
154
155
|
WITH_WEB_ACCESS=true
|
|
155
156
|
shift
|
|
156
157
|
;;
|
|
158
|
+
--no-web-access)
|
|
159
|
+
WITH_WEB_ACCESS=false
|
|
160
|
+
shift
|
|
161
|
+
;;
|
|
157
162
|
--with-herdr)
|
|
158
163
|
WITH_HERDR=true
|
|
159
164
|
shift
|
|
@@ -412,6 +417,8 @@ if [[ "$DO_GLOBAL" == true ]]; then
|
|
|
412
417
|
fi
|
|
413
418
|
if [[ "$WITH_WEB_ACCESS" == true ]]; then
|
|
414
419
|
install_args+=("--with-web-access")
|
|
420
|
+
else
|
|
421
|
+
install_args+=("--no-web-access")
|
|
415
422
|
fi
|
|
416
423
|
if [[ "$WITH_HERDR" == true ]]; then
|
|
417
424
|
install_args+=("--with-herdr")
|
package/scripts/team-doctor.sh
CHANGED
|
@@ -224,13 +224,16 @@ function mcpSummary(file) {
|
|
|
224
224
|
|
|
225
225
|
let piHasMcpAdapter = false;
|
|
226
226
|
let piHasSubagents = false;
|
|
227
|
+
let piHasWebAccess = false;
|
|
227
228
|
if (commandExists("pi")) {
|
|
228
229
|
const piList = spawnSync("pi", ["list"], { encoding: "utf8" });
|
|
229
230
|
const combined = `${piList.stdout ?? ""}\n${piList.stderr ?? ""}`;
|
|
230
231
|
piHasMcpAdapter = combined.includes("pi-mcp-adapter");
|
|
231
232
|
piHasSubagents = combined.includes("pi-subagents");
|
|
233
|
+
piHasWebAccess = combined.includes("pi-web-access");
|
|
232
234
|
if (!piHasMcpAdapter) warnings.push("Pi MCP adapter not found in `pi list`; run setup with --with-mcp or `pi install npm:pi-mcp-adapter@2.15.0`");
|
|
233
235
|
if (!piHasSubagents) warnings.push("Pi subagents package not found in `pi list`; run setup with --with-subagents or `pi install npm:pi-subagents@0.38.0`");
|
|
236
|
+
if (!piHasWebAccess) warnings.push("Pi web access package not found in `pi list`; run `piagent-update --force` or `pi install npm:pi-web-access@0.17.0` so researcher subagents can browse/fetch external sources");
|
|
234
237
|
}
|
|
235
238
|
|
|
236
239
|
const mcpFiles = [
|
|
@@ -302,7 +302,7 @@ function summarizeMigration(report, dryRun) {
|
|
|
302
302
|
|
|
303
303
|
function runProjectMigration(project, options, activePlatformRoot) {
|
|
304
304
|
const migrator = path.join(activePlatformRoot, "scripts/migrate-project-state.mjs");
|
|
305
|
-
if (!
|
|
305
|
+
if (!fs.existsSync(migrator)) {
|
|
306
306
|
fail(`the updated helper has no project migrator at ${migrator}`);
|
|
307
307
|
}
|
|
308
308
|
const args = options.dryRun
|
package/scripts/verify-local.sh
CHANGED
|
@@ -52,6 +52,7 @@ required_files=(
|
|
|
52
52
|
"$ROOT/packages/piagent-core/package.json"
|
|
53
53
|
"$ROOT/packages/piagent-core/extensions/piagent-guard.ts"
|
|
54
54
|
"$ROOT/packages/piagent-core/extensions/context-engine.js"
|
|
55
|
+
"$ROOT/packages/piagent-core/extensions/context-index-policy.js"
|
|
55
56
|
"$ROOT/packages/piagent-core/extensions/policy-core.js"
|
|
56
57
|
"$ROOT/packages/piagent-core/extensions/redaction-core.js"
|
|
57
58
|
"$ROOT/packages/piagent-core/extensions/runtime-evidence.js"
|
|
@@ -346,10 +347,10 @@ require_documented "Subagent orchestration capabilities" "$ROOT/README.md" "$ROO
|
|
|
346
347
|
require_documented "pi-web-access" "$ROOT/README.md" "$ROOT/docs" "$ROOT/scripts/install-global.sh" "$ROOT/scripts/setup.sh"
|
|
347
348
|
grep -F 'PI_MCP_ADAPTER_SOURCE="npm:pi-mcp-adapter@2.15.0"' "$ROOT/scripts/install-global.sh" >/dev/null
|
|
348
349
|
grep -F 'PI_SUBAGENTS_SOURCE="npm:pi-subagents@0.38.0"' "$ROOT/scripts/install-global.sh" >/dev/null
|
|
349
|
-
grep -F 'PI_WEB_ACCESS_SOURCE="npm:pi-web-access@0.
|
|
350
|
+
grep -F 'PI_WEB_ACCESS_SOURCE="npm:pi-web-access@0.17.0"' "$ROOT/scripts/install-global.sh" >/dev/null
|
|
350
351
|
grep -F 'PI_MCP_ADAPTER_VERSION="2.15.0"' "$ROOT/scripts/audit-runtime-host.sh" >/dev/null
|
|
351
352
|
grep -F 'PI_SUBAGENTS_VERSION="0.38.0"' "$ROOT/scripts/audit-runtime-host.sh" >/dev/null
|
|
352
|
-
grep -F 'PI_WEB_ACCESS_VERSION="0.
|
|
353
|
+
grep -F 'PI_WEB_ACCESS_VERSION="0.17.0"' "$ROOT/scripts/audit-runtime-host.sh" >/dev/null
|
|
353
354
|
node --input-type=module - "$ROOT/scripts/install-global.sh" "$ROOT/scripts/audit-runtime-host.sh" <<'NODE'
|
|
354
355
|
import fs from "node:fs";
|
|
355
356
|
|
|
@@ -545,6 +546,7 @@ fi
|
|
|
545
546
|
|
|
546
547
|
node --check "$ROOT/packages/piagent-core/extensions/piagent-guard.ts" >/dev/null
|
|
547
548
|
node --check "$ROOT/packages/piagent-core/extensions/context-engine.js" >/dev/null
|
|
549
|
+
node --check "$ROOT/packages/piagent-core/extensions/context-index-policy.js" >/dev/null
|
|
548
550
|
node --check "$ROOT/packages/piagent-core/extensions/policy-core.js" >/dev/null
|
|
549
551
|
node --check "$ROOT/packages/piagent-core/extensions/redaction-core.js" >/dev/null
|
|
550
552
|
node --check "$ROOT/packages/piagent-core/extensions/runtime-evidence.js" >/dev/null
|