pi-orchestrator-config 4.6.2 → 4.6.4
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/github-expert.md +3 -9
- package/extensions/orchestrator/async-agents.ts +1 -0
- package/extensions/orchestrator/enforcement-helpers.ts +46 -12
- package/extensions/orchestrator/enforcement.ts +4 -4
- package/extensions/orchestrator/subagent-tool.ts +1 -1
- package/extensions/pidiff/pidiff-ui/package.json +1 -1
- package/package.json +9 -8
package/agents/github-expert.md
CHANGED
|
@@ -27,16 +27,10 @@ This agent does NOT run tests. When tests are required (e.g., before creating a
|
|
|
27
27
|
1. Ask orchestrator: "Have all tests passed?"
|
|
28
28
|
2. If NO/UNKNOWN: "Please delegate to test-runner, then call me again"
|
|
29
29
|
|
|
30
|
-
##
|
|
30
|
+
## Attribution
|
|
31
31
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
- If `comment_signature` is `true`: append a signature to every GitHub body you write —
|
|
35
|
-
PR/issue **create**, **edit --body**, and **comment**.
|
|
36
|
-
Format: `\n\n---\n*Assisted-by: PI (<model>)*` using `$PI_MODEL` for model.
|
|
37
|
-
If `$PI_COMMENT_SIGNATURE` is set, use: `\n\n---\n*$PI_COMMENT_SIGNATURE*`.
|
|
38
|
-
Skip if the body already contains `Assisted-by`.
|
|
39
|
-
Runtime enforcement also injects this on `gh pr|issue create|comment|edit` `--body` / heredoc.
|
|
32
|
+
Runtime owns attribution for `gh pr` and `gh issue` create, edit, and comment bodies passed with `--body`.
|
|
33
|
+
Never manually add a signature, including raw `$PI_MODEL`, or use a manual fallback.
|
|
40
34
|
|
|
41
35
|
## Core Operations
|
|
42
36
|
|
|
@@ -1041,6 +1041,7 @@ export function registerAsyncAgents(
|
|
|
1041
1041
|
// Resolve base branch for reviewers so they diff against the correct target
|
|
1042
1042
|
const spawnEnv: Record<string, string | undefined> = {
|
|
1043
1043
|
...process.env,
|
|
1044
|
+
PI_MODEL: effectiveModel || undefined,
|
|
1044
1045
|
PI_SUBAGENT_CHILD: "1",
|
|
1045
1046
|
PI_AGENT_NAME: agentName,
|
|
1046
1047
|
PI_PRIMARY_MODEL: process.env.PI_PRIMARY_MODEL || process.env.PI_MODEL || "",
|
|
@@ -806,17 +806,38 @@ function commentSignatureFooter(signature: string): string {
|
|
|
806
806
|
return `\n\n---\n*${signature}*`;
|
|
807
807
|
}
|
|
808
808
|
|
|
809
|
+
const ghSignatureModel = /^[\w:./+@-]+(?: [\w:./+@-]+)*$/;
|
|
810
|
+
const ghSignatureLine = /(^|\n|\\n)(?:(?:\n|\\n)---(?:\n|\\n))?\*Assisted-by: PI \(([^\r\n]*?)\)\*(?=\r?\n|\\n|$)/g;
|
|
811
|
+
|
|
809
812
|
function bodyAlreadySigned(text: string): boolean {
|
|
810
|
-
|
|
813
|
+
const lines = text.matchAll(ghSignatureLine);
|
|
814
|
+
for (const line of lines) {
|
|
815
|
+
if (ghSignatureModel.test(line[2])) return true;
|
|
816
|
+
}
|
|
817
|
+
return false;
|
|
811
818
|
}
|
|
812
819
|
|
|
813
|
-
/**
|
|
814
|
-
function
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
+
/** Keep the first standalone valid footer, but use the current operation's model. */
|
|
821
|
+
function normalizeGhBodyFooters(payload: string, signature: string): string {
|
|
822
|
+
let signed = false;
|
|
823
|
+
return payload.replace(ghSignatureLine, (block, _prefix: string, model: string) => {
|
|
824
|
+
if (model.includes("PI_MODEL")) {
|
|
825
|
+
enfLog.debug("injectGhBodySignature removed unresolved PI_MODEL footer");
|
|
826
|
+
return "";
|
|
827
|
+
}
|
|
828
|
+
if (ghSignatureModel.test(model)) {
|
|
829
|
+
if (signed) {
|
|
830
|
+
enfLog.debug("injectGhBodySignature removed duplicate valid footer", model);
|
|
831
|
+
return "";
|
|
832
|
+
}
|
|
833
|
+
signed = true;
|
|
834
|
+
if (`Assisted-by: PI (${model})` !== signature) {
|
|
835
|
+
enfLog.debug("injectGhBodySignature replaced stale footer", model);
|
|
836
|
+
return block.replace(`*Assisted-by: PI (${model})*`, `*${signature}*`);
|
|
837
|
+
}
|
|
838
|
+
}
|
|
839
|
+
return block;
|
|
840
|
+
});
|
|
820
841
|
}
|
|
821
842
|
|
|
822
843
|
/** Index of the matching closer for a quote at `openIdx`, honoring POSIX escapes. */
|
|
@@ -829,6 +850,17 @@ function matchingQuoteIndex(s: string, openIdx: number): number | null {
|
|
|
829
850
|
return close < 0 ? null : close;
|
|
830
851
|
}
|
|
831
852
|
for (let i = openIdx + 1; i < s.length; i++) {
|
|
853
|
+
if (s.startsWith("<<", i)) {
|
|
854
|
+
const opener = /^<<(-?)[ \t]*(['"]?)([\w-]+)\2[^\n]*\n/.exec(s.slice(i));
|
|
855
|
+
if (opener) {
|
|
856
|
+
const closer = new RegExp(String.raw`\n${opener[1] ? "\\t*" : ""}${opener[3]}\r?(?=\n|$)`).exec(s.slice(i + opener[0].length - 1));
|
|
857
|
+
if (closer) {
|
|
858
|
+
enfLog.debug("matchingQuoteIndex skip heredoc", opener[3]);
|
|
859
|
+
i += opener[0].length - 1 + closer.index + closer[0].length - 1;
|
|
860
|
+
continue;
|
|
861
|
+
}
|
|
862
|
+
}
|
|
863
|
+
}
|
|
832
864
|
if (s[i] === "\\") {
|
|
833
865
|
i++;
|
|
834
866
|
continue;
|
|
@@ -873,7 +905,7 @@ function lastHeredocInSpan(
|
|
|
873
905
|
spanStart: number,
|
|
874
906
|
spanEnd: number,
|
|
875
907
|
): RegExpExecArray | null {
|
|
876
|
-
const heredocRe =
|
|
908
|
+
const heredocRe = /<<-?[ \t]*(['"]?)([\w-]+)\1[^\n]*\n([\s\S]*?)\n([ \t]*)\2\r?(?=\n|$)/g;
|
|
877
909
|
let last: RegExpExecArray | null = null;
|
|
878
910
|
let m: RegExpExecArray | null;
|
|
879
911
|
while ((m = heredocRe.exec(command)) !== null) {
|
|
@@ -905,9 +937,9 @@ export function injectGhBodySignature(command: string, signature: string): strin
|
|
|
905
937
|
}
|
|
906
938
|
|
|
907
939
|
const payload = command.slice(span.open + 1, span.close);
|
|
908
|
-
const normalizedPayload =
|
|
940
|
+
const normalizedPayload = normalizeGhBodyFooters(payload, signature);
|
|
909
941
|
if (normalizedPayload !== payload) {
|
|
910
|
-
// Re-parse positions after
|
|
942
|
+
// Re-parse positions after cleanup so command-substitution heredocs still
|
|
911
943
|
// receive their footer before the closing delimiter.
|
|
912
944
|
const normalizedCommand = command.slice(0, span.open + 1) + normalizedPayload + command.slice(span.close);
|
|
913
945
|
return injectGhBodySignature(normalizedCommand, signature);
|
|
@@ -925,7 +957,9 @@ export function injectGhBodySignature(command: string, signature: string): strin
|
|
|
925
957
|
const closeIdx = last.index + last[0].lastIndexOf(closeToken);
|
|
926
958
|
if (closeIdx >= last.index) {
|
|
927
959
|
enfLog.debug("injectGhBodySignature heredoc in --body", delim);
|
|
928
|
-
|
|
960
|
+
const crlf = command[closeIdx - 1] === "\r";
|
|
961
|
+
const insertAt = crlf ? closeIdx - 1 : closeIdx;
|
|
962
|
+
return command.slice(0, insertAt) + (crlf ? footer.replaceAll("\n", "\r\n") : footer) + command.slice(insertAt);
|
|
929
963
|
}
|
|
930
964
|
}
|
|
931
965
|
|
|
@@ -389,7 +389,7 @@ export function registerEnforcement(pi: ExtensionAPI, inContainer?: boolean): vo
|
|
|
389
389
|
cachedTrailerSelection = null;
|
|
390
390
|
// Set comment signature env var for CLI tools to read
|
|
391
391
|
if (getSetting(ctx.cwd, "comment_signature")) {
|
|
392
|
-
const modelId = (
|
|
392
|
+
const modelId = ((ctx as any).model?.id || process.env.PI_MODEL || process.env.PI_PRIMARY_MODEL || "unknown").replace(/[^a-zA-Z0-9._:@/ -]/g, "").trim() || "unknown";
|
|
393
393
|
process.env.PI_COMMENT_SIGNATURE = `Assisted-by: PI (${modelId})`;
|
|
394
394
|
} else {
|
|
395
395
|
delete process.env.PI_COMMENT_SIGNATURE;
|
|
@@ -535,12 +535,12 @@ export function registerEnforcement(pi: ExtensionAPI, inContainer?: boolean): vo
|
|
|
535
535
|
// comment_signature: inject Assisted-by footer into gh pr/issue create|comment|edit bodies
|
|
536
536
|
if (getSetting(ctx.cwd, "comment_signature")) {
|
|
537
537
|
const modelId = (
|
|
538
|
-
process.env.PI_PRIMARY_MODEL ||
|
|
539
|
-
process.env.PI_MODEL ||
|
|
540
538
|
(ctx as any).model?.id ||
|
|
539
|
+
process.env.PI_MODEL ||
|
|
540
|
+
process.env.PI_PRIMARY_MODEL ||
|
|
541
541
|
"unknown"
|
|
542
542
|
).replace(/[^a-zA-Z0-9._:@/ -]/g, "").trim() || "unknown";
|
|
543
|
-
const signature =
|
|
543
|
+
const signature = `Assisted-by: PI (${modelId})`;
|
|
544
544
|
const injected = injectGhBodySignature(event.input.command, signature);
|
|
545
545
|
if (injected !== event.input.command) {
|
|
546
546
|
log.info("comment_signature injected into gh body command", signature);
|
|
@@ -485,7 +485,7 @@ export async function runSingleAgent(
|
|
|
485
485
|
cwd: cwd,
|
|
486
486
|
shell: false,
|
|
487
487
|
stdio: ["ignore", "pipe", "pipe"],
|
|
488
|
-
env: { ...process.env, PI_SUBAGENT_CHILD: "1", PI_AGENT_NAME: agentName, PI_PRIMARY_MODEL: process.env.PI_PRIMARY_MODEL || process.env.PI_MODEL || "", __PI_CONFIG_SESSION_ID: (globalThis as any).__piConfigSessionId || "", __PI_PARENT_SESSION_ID: (globalThis as any).__piConfigSessionId || "" },
|
|
488
|
+
env: { ...process.env, PI_MODEL: effectiveModel || undefined, PI_SUBAGENT_CHILD: "1", PI_AGENT_NAME: agentName, PI_PRIMARY_MODEL: process.env.PI_PRIMARY_MODEL || process.env.PI_MODEL || "", __PI_CONFIG_SESSION_ID: (globalThis as any).__piConfigSessionId || "", __PI_PARENT_SESSION_ID: (globalThis as any).__piConfigSessionId || "" },
|
|
489
489
|
});
|
|
490
490
|
let buf = "";
|
|
491
491
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-orchestrator-config",
|
|
3
|
-
"version": "4.6.
|
|
3
|
+
"version": "4.6.4",
|
|
4
4
|
"description": "Orchestrator pattern for pi: specialist subagents, enforcement, code review loop, workflow commands",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"pi-package"
|
|
@@ -59,11 +59,14 @@
|
|
|
59
59
|
"skills/",
|
|
60
60
|
"settings-keys.json"
|
|
61
61
|
],
|
|
62
|
+
"peerDependencies": {
|
|
63
|
+
"@earendil-works/pi-agent-core": "*",
|
|
64
|
+
"@earendil-works/pi-ai": "*",
|
|
65
|
+
"@earendil-works/pi-coding-agent": "*",
|
|
66
|
+
"@earendil-works/pi-tui": "*",
|
|
67
|
+
"typebox": "*"
|
|
68
|
+
},
|
|
62
69
|
"dependencies": {
|
|
63
|
-
"@earendil-works/pi-agent-core": ">=0.87.0",
|
|
64
|
-
"@earendil-works/pi-ai": ">=0.87.0",
|
|
65
|
-
"@earendil-works/pi-coding-agent": ">=0.87.0",
|
|
66
|
-
"@earendil-works/pi-tui": ">=0.87.0",
|
|
67
70
|
"@huggingface/transformers": "^4.2.0",
|
|
68
71
|
"acpx": ">=0.12.0 <1",
|
|
69
72
|
"chokidar": "^5.0.0",
|
|
@@ -87,9 +90,7 @@
|
|
|
87
90
|
},
|
|
88
91
|
"overrides": {
|
|
89
92
|
"undici": ">=6.27.0 <9.0.0",
|
|
90
|
-
"
|
|
91
|
-
"protobufjs": "7.6.5",
|
|
92
|
-
"sharp": "0.35.3"
|
|
93
|
+
"protobufjs": "7.6.5"
|
|
93
94
|
},
|
|
94
95
|
"pi": {
|
|
95
96
|
"extensions": [
|