pi-harness-runtime 1.1.150 → 1.1.153
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 +7 -0
- package/harness/key-loader.ts +84 -0
- package/harness/langchain/agents.ts +65 -15
- package/harness/langchain/daemon.ts +58 -30
- package/harness/langchain/graph.ts +55 -7
- package/harness/langchain/planner-logger.ts +275 -0
- package/harness/langchain/run.ts +64 -161
- package/harness/langchain/surge.test.ts +42 -0
- package/harness/langchain/surge.ts +22 -1
- package/harness/service-diagnostics.ts +217 -0
- package/index.ts +54 -6
- package/package.json +1 -1
- package/packages/a2a-adapter/package.json +1 -1
- package/packages/agent-policy/dist/extension.d.ts +19 -0
- package/packages/agent-policy/dist/extension.d.ts.map +1 -0
- package/packages/agent-policy/dist/extension.js +322 -0
- package/packages/agent-policy/dist/extension.js.map +1 -0
- package/packages/agent-policy/dist/index.d.ts +25 -0
- package/packages/agent-policy/dist/index.d.ts.map +1 -0
- package/packages/agent-policy/dist/index.js +27 -0
- package/packages/agent-policy/dist/index.js.map +1 -0
- package/packages/agent-policy/dist/policy-loader.d.ts +90 -0
- package/packages/agent-policy/dist/policy-loader.d.ts.map +1 -0
- package/packages/agent-policy/dist/policy-loader.js +331 -0
- package/packages/agent-policy/dist/policy-loader.js.map +1 -0
- package/packages/agent-policy/dist/policy-renderer.d.ts +42 -0
- package/packages/agent-policy/dist/policy-renderer.d.ts.map +1 -0
- package/packages/agent-policy/dist/policy-renderer.js +295 -0
- package/packages/agent-policy/dist/policy-renderer.js.map +1 -0
- package/packages/agent-policy/dist/policy-store.d.ts +99 -0
- package/packages/agent-policy/dist/policy-store.d.ts.map +1 -0
- package/packages/agent-policy/dist/policy-store.js +244 -0
- package/packages/agent-policy/dist/policy-store.js.map +1 -0
- package/packages/agent-policy/dist/types.d.ts +237 -0
- package/packages/agent-policy/dist/types.d.ts.map +1 -0
- package/packages/agent-policy/dist/types.js +130 -0
- package/packages/agent-policy/dist/types.js.map +1 -0
- package/packages/agent-policy/package.json +45 -0
- package/packages/agent-policy/src/extension.ts +413 -0
- package/packages/agent-policy/src/index.ts +52 -0
- package/packages/agent-policy/src/policy-loader.ts +398 -0
- package/packages/agent-policy/src/policy-renderer.ts +362 -0
- package/packages/agent-policy/src/policy-store.ts +319 -0
- package/packages/agent-policy/src/types.ts +385 -0
- package/packages/agent-policy/test/policy.test.ts +383 -0
- package/packages/architecture-generator/package.json +1 -1
- package/packages/auth/package.json +1 -1
- package/packages/autonomous-refactor/package.json +1 -1
- package/packages/autonomous-runtime/package.json +1 -1
- package/packages/cache-strategy/package.json +1 -1
- package/packages/capability-registry/package.json +1 -1
- package/packages/checkpoint/package.json +1 -1
- package/packages/cli-plugin-sdk/package.json +1 -1
- package/packages/clipboard/package.json +1 -1
- package/packages/clipboard-plugin/package.json +1 -1
- package/packages/code-generation/package.json +1 -1
- package/packages/code-review/package.json +1 -1
- package/packages/codex-adapter/package.json +1 -1
- package/packages/codex-watcher/dist/src/parser.d.ts.map +1 -1
- package/packages/codex-watcher/dist/src/parser.js +35 -0
- package/packages/codex-watcher/dist/src/parser.js.map +1 -1
- package/packages/codex-watcher/package.json +1 -1
- package/packages/codex-watcher/src/parser.ts +41 -0
- package/packages/config-capture/package.json +1 -1
- package/packages/context-compiler/package.json +1 -1
- package/packages/context-discovery/package.json +1 -1
- package/packages/context-manager/package.json +1 -1
- package/packages/cookie-sanitizer/package.json +1 -1
- package/packages/cost-optimizer/package.json +1 -1
- package/packages/dependency-analyzer/package.json +1 -1
- package/packages/django-plugin/package.json +1 -1
- package/packages/doc-generator/package.json +1 -1
- package/packages/evaluation-engine/package.json +1 -1
- package/packages/evaluation-runner/package.json +1 -1
- package/packages/event-bus/package.json +1 -1
- package/packages/event-store/package.json +1 -1
- package/packages/experience-replay/package.json +1 -1
- package/packages/feedback-collector/package.json +1 -1
- package/packages/file-copy-helper/package.json +1 -1
- package/packages/framework-detector/package.json +1 -1
- package/packages/framework-plugin-sdk/package.json +1 -1
- package/packages/frappe-plugin/package.json +1 -1
- package/packages/generic-web-plugin/package.json +1 -1
- package/packages/health-monitor/package.json +1 -1
- package/packages/intent-analyzer/package.json +1 -1
- package/packages/jev-judge/package.json +1 -1
- package/packages/knowledge-graph/package.json +1 -1
- package/packages/knowledge-retrieval/package.json +1 -1
- package/packages/laravel-plugin/package.json +1 -1
- package/packages/learning-engine/package.json +1 -1
- package/packages/mcp-adapter/package.json +1 -1
- package/packages/memory-engine/package.json +1 -1
- package/packages/milestone-manager/package.json +1 -1
- package/packages/model-registry/package.json +1 -1
- package/packages/nextjs-plugin/package.json +1 -1
- package/packages/notification/dist/adapters/telegram-adapter.d.ts +5 -0
- package/packages/notification/dist/adapters/telegram-adapter.d.ts.map +1 -1
- package/packages/notification/dist/adapters/telegram-adapter.js +54 -0
- package/packages/notification/dist/adapters/telegram-adapter.js.map +1 -1
- package/packages/notification/dist/notification-center.d.ts +13 -0
- package/packages/notification/dist/notification-center.d.ts.map +1 -1
- package/packages/notification/dist/notification-center.js +36 -0
- package/packages/notification/dist/notification-center.js.map +1 -1
- package/packages/notification/package.json +1 -1
- package/packages/notification/src/adapters/telegram-adapter.ts +71 -0
- package/packages/notification/src/notification-center.ts +53 -0
- package/packages/observability/package.json +1 -1
- package/packages/okf-indexer/package.json +1 -1
- package/packages/paperclip-integration/package.json +1 -1
- package/packages/performance-optimizer/package.json +1 -1
- package/packages/privilege-broker/package.json +1 -1
- package/packages/project-analyzer/package.json +1 -1
- package/packages/project-bootstrap/package.json +1 -1
- package/packages/projection-engine/package.json +1 -1
- package/packages/prompt-compiler/package.json +1 -1
- package/packages/prompt-versioning/package.json +1 -1
- package/packages/provider-adapter-sdk/package.json +1 -1
- package/packages/provider-router/package.json +1 -1
- package/packages/provider-selector/package.json +1 -1
- package/packages/providers/package.json +1 -1
- package/packages/qdrant-skills/dist/client.d.ts.map +1 -1
- package/packages/qdrant-skills/dist/client.js +4 -3
- package/packages/qdrant-skills/dist/client.js.map +1 -1
- package/packages/qdrant-skills/package.json +1 -1
- package/packages/qdrant-skills/src/client.ts +14 -17
- package/packages/quota-manager/package.json +1 -1
- package/packages/rate-limiter/package.json +1 -1
- package/packages/react-vite-plugin/package.json +1 -1
- package/packages/release-manager/package.json +1 -1
- package/packages/requirement-compiler/package.json +1 -1
- package/packages/runtime/package.json +1 -1
- package/packages/scheduler/package.json +1 -1
- package/packages/scheduler-adapter/package.json +1 -1
- package/packages/session/package.json +1 -1
- package/packages/session-api/package.json +1 -1
- package/packages/session-export/package.json +1 -1
- package/packages/shared-context/package.json +1 -1
- package/packages/skill-mcp-client/package.json +1 -1
- package/packages/skill-registry/package.json +1 -1
- package/packages/skills/dist/loader.d.ts +9 -2
- package/packages/skills/dist/loader.d.ts.map +1 -1
- package/packages/skills/dist/loader.js +24 -7
- package/packages/skills/dist/loader.js.map +1 -1
- package/packages/skills/package.json +1 -1
- package/packages/skills/src/loader.ts +27 -7
- package/packages/sprint-planner/package.json +1 -1
- package/packages/subscription-engine/package.json +1 -1
- package/packages/task-compiler/package.json +1 -1
- package/packages/tencentdb-memory/package.json +1 -1
- package/packages/tencentdb-sync/package.json +1 -1
- package/packages/test-data-generator/package.json +1 -1
- package/packages/test-generator/package.json +1 -1
- package/packages/todo-bd-sync/package.json +1 -1
- package/packages/token-estimation/package.json +1 -1
- package/packages/token-optimizer/package.json +1 -1
- package/packages/trajectory/package.json +1 -1
- package/packages/tui/package.json +1 -1
- package/packages/types/package.json +1 -1
- package/packages/workflow-events/package.json +1 -1
- package/packages/workspace-scanner/package.json +1 -1
- package/packages/worktree/package.json +1 -1
- package/packages/write-review/package.json +1 -1
- package/proactive-compact.ts +2 -2
- package/scripts/debug-codex-integration.ts +203 -0
- package/scripts/sync-keys-from-pi.ts +188 -0
- package/scripts/test-codex-session.ts +23 -0
- package/scripts/test-openai.ts +14 -0
- package/scripts/test-telegram.ts +34 -0
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Service Diagnostics - Structured logging for harness services
|
|
3
|
+
*
|
|
4
|
+
* Logs service events to ~/.pi-harness-runtime/logs/services.jsonl
|
|
5
|
+
* with structured data for observability.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { appendFileSync, existsSync, mkdirSync } from "node:fs";
|
|
9
|
+
import { join } from "node:path";
|
|
10
|
+
import { homedir } from "node:os";
|
|
11
|
+
|
|
12
|
+
export type ServiceLevel = "info" | "warn" | "error" | "debug";
|
|
13
|
+
export type ServiceName = "jev" | "honcho" | "qdrant";
|
|
14
|
+
|
|
15
|
+
export interface ServiceEvent {
|
|
16
|
+
ts: string;
|
|
17
|
+
level: ServiceLevel;
|
|
18
|
+
service: ServiceName;
|
|
19
|
+
operation: string;
|
|
20
|
+
phase: "start" | "completed" | "failed";
|
|
21
|
+
sessionId?: string;
|
|
22
|
+
requestId?: string;
|
|
23
|
+
durationMs?: number;
|
|
24
|
+
[key: string]: unknown;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const LOG_DIR = join(homedir(), ".pi-harness-runtime", "logs");
|
|
28
|
+
const LOG_FILE = join(LOG_DIR, "services.jsonl");
|
|
29
|
+
let _initialized = false;
|
|
30
|
+
|
|
31
|
+
function ensureLogDir(): void {
|
|
32
|
+
if (_initialized) return;
|
|
33
|
+
if (!existsSync(LOG_DIR)) {
|
|
34
|
+
mkdirSync(LOG_DIR, { recursive: true });
|
|
35
|
+
}
|
|
36
|
+
_initialized = true;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Log a structured service event.
|
|
41
|
+
* Sensitive fields (keys, tokens, full content) are never logged.
|
|
42
|
+
*/
|
|
43
|
+
export function logServiceEvent(event: ServiceEvent): void {
|
|
44
|
+
ensureLogDir();
|
|
45
|
+
|
|
46
|
+
// Redact sensitive fields
|
|
47
|
+
const safeEvent = redactSensitive(event);
|
|
48
|
+
|
|
49
|
+
try {
|
|
50
|
+
appendFileSync(LOG_FILE, JSON.stringify(safeEvent) + "\n");
|
|
51
|
+
} catch {
|
|
52
|
+
// Silently fail if logging fails - don't crash the service
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Redact sensitive fields from event data.
|
|
58
|
+
* Never log: apiKey, token, secret, chatId, content, vectors, embeddings
|
|
59
|
+
*/
|
|
60
|
+
function redactSensitive(event: ServiceEvent): Record<string, unknown> {
|
|
61
|
+
const sensitiveKeys = [
|
|
62
|
+
"apiKey",
|
|
63
|
+
"token",
|
|
64
|
+
"secret",
|
|
65
|
+
"bearerToken",
|
|
66
|
+
"chatId",
|
|
67
|
+
"content",
|
|
68
|
+
"vectors",
|
|
69
|
+
"embeddings",
|
|
70
|
+
"prompt",
|
|
71
|
+
"messages",
|
|
72
|
+
"raw",
|
|
73
|
+
];
|
|
74
|
+
|
|
75
|
+
const result: Record<string, unknown> = { ...event };
|
|
76
|
+
|
|
77
|
+
for (const key of Object.keys(result)) {
|
|
78
|
+
if (sensitiveKeys.some((sk) => key.toLowerCase().includes(sk.toLowerCase()))) {
|
|
79
|
+
result[key] = "[REDACTED]";
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
return result;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Create a service status tracker.
|
|
88
|
+
*/
|
|
89
|
+
export class ServiceStatus {
|
|
90
|
+
private _configured = false;
|
|
91
|
+
private _initialized = false;
|
|
92
|
+
private _connected = false;
|
|
93
|
+
private _lastSuccessAt: string | null = null;
|
|
94
|
+
private _lastFailureAt: string | null = null;
|
|
95
|
+
private _lastErrorCode: string | null = null;
|
|
96
|
+
private _requests = 0;
|
|
97
|
+
private _successes = 0;
|
|
98
|
+
private _failures = 0;
|
|
99
|
+
private _featureEnabled = false;
|
|
100
|
+
private _service: ServiceName;
|
|
101
|
+
|
|
102
|
+
constructor(service: ServiceName) {
|
|
103
|
+
this._service = service;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
get configured() { return this._configured; }
|
|
107
|
+
get initialized() { return this._initialized; }
|
|
108
|
+
get connected() { return this._connected; }
|
|
109
|
+
get lastSuccessAt() { return this._lastSuccessAt; }
|
|
110
|
+
get lastFailureAt() { return this._lastFailureAt; }
|
|
111
|
+
get lastErrorCode() { return this._lastErrorCode; }
|
|
112
|
+
get requests() { return this._requests; }
|
|
113
|
+
get successes() { return this._successes; }
|
|
114
|
+
get failures() { return this._failures; }
|
|
115
|
+
get featureEnabled() { return this._featureEnabled; }
|
|
116
|
+
|
|
117
|
+
setConfigured(v: boolean): this {
|
|
118
|
+
this._configured = v;
|
|
119
|
+
logServiceEvent({
|
|
120
|
+
ts: new Date().toISOString(),
|
|
121
|
+
level: "info",
|
|
122
|
+
service: this._service,
|
|
123
|
+
operation: "config_checked",
|
|
124
|
+
phase: "completed",
|
|
125
|
+
configured: v,
|
|
126
|
+
});
|
|
127
|
+
return this;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
setInitialized(v: boolean): this {
|
|
131
|
+
this._initialized = v;
|
|
132
|
+
if (v) {
|
|
133
|
+
logServiceEvent({
|
|
134
|
+
ts: new Date().toISOString(),
|
|
135
|
+
level: "info",
|
|
136
|
+
service: this._service,
|
|
137
|
+
operation: "initialized",
|
|
138
|
+
phase: "completed",
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
return this;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
setConnected(v: boolean): this {
|
|
145
|
+
this._connected = v;
|
|
146
|
+
logServiceEvent({
|
|
147
|
+
ts: new Date().toISOString(),
|
|
148
|
+
level: "info",
|
|
149
|
+
service: this._service,
|
|
150
|
+
operation: "connected",
|
|
151
|
+
phase: v ? "completed" : "failed",
|
|
152
|
+
connected: v,
|
|
153
|
+
});
|
|
154
|
+
return this;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
setFeatureEnabled(v: boolean): this {
|
|
158
|
+
this._featureEnabled = v;
|
|
159
|
+
return this;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
recordSuccess(operation: string, durationMs?: number, extra?: Record<string, unknown>): void {
|
|
163
|
+
this._requests++;
|
|
164
|
+
this._successes++;
|
|
165
|
+
this._lastSuccessAt = new Date().toISOString();
|
|
166
|
+
logServiceEvent({
|
|
167
|
+
ts: new Date().toISOString(),
|
|
168
|
+
level: "info",
|
|
169
|
+
service: this._service,
|
|
170
|
+
operation,
|
|
171
|
+
phase: "completed",
|
|
172
|
+
durationMs,
|
|
173
|
+
requests: this._requests,
|
|
174
|
+
successes: this._successes,
|
|
175
|
+
...extra,
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
recordFailure(operation: string, errorCode: string, extra?: Record<string, unknown>): void {
|
|
180
|
+
this._requests++;
|
|
181
|
+
this._failures++;
|
|
182
|
+
this._lastFailureAt = new Date().toISOString();
|
|
183
|
+
this._lastErrorCode = errorCode;
|
|
184
|
+
logServiceEvent({
|
|
185
|
+
ts: new Date().toISOString(),
|
|
186
|
+
level: "error",
|
|
187
|
+
service: this._service,
|
|
188
|
+
operation,
|
|
189
|
+
phase: "failed",
|
|
190
|
+
errorCode,
|
|
191
|
+
requests: this._requests,
|
|
192
|
+
failures: this._failures,
|
|
193
|
+
...extra,
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
toJSON(): Record<string, unknown> {
|
|
198
|
+
return {
|
|
199
|
+
service: this._service,
|
|
200
|
+
configured: this._configured,
|
|
201
|
+
initialized: this._initialized,
|
|
202
|
+
connected: this._connected,
|
|
203
|
+
lastSuccessAt: this._lastSuccessAt,
|
|
204
|
+
lastFailureAt: this._lastFailureAt,
|
|
205
|
+
lastErrorCode: this._lastErrorCode,
|
|
206
|
+
requests: this._requests,
|
|
207
|
+
successes: this._successes,
|
|
208
|
+
failures: this._failures,
|
|
209
|
+
featureEnabled: this._featureEnabled,
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
// Export service status instances
|
|
215
|
+
export const jevStatus = new ServiceStatus("jev");
|
|
216
|
+
export const honchoStatus = new ServiceStatus("honcho");
|
|
217
|
+
export const qdrantStatus = new ServiceStatus("qdrant");
|
package/index.ts
CHANGED
|
@@ -103,6 +103,11 @@ async function initAutoContinue(pi: ExtensionAPI): Promise<void> {
|
|
|
103
103
|
return;
|
|
104
104
|
}
|
|
105
105
|
|
|
106
|
+
// Resolve the actual API key: env takes priority, file is fallback
|
|
107
|
+
const resolvedApiKey = process.env.TYPESAFE_API_KEY ||
|
|
108
|
+
process.env.OPENROUTER_API_KEY ||
|
|
109
|
+
readFileSync(`${keysDir}/jev-api-key.txt`, "utf8").trim();
|
|
110
|
+
|
|
106
111
|
const mod = await import("./packages/jev-judge/src/auto-continue.js");
|
|
107
112
|
|
|
108
113
|
// Track waiting state
|
|
@@ -111,10 +116,22 @@ async function initAutoContinue(pi: ExtensionAPI): Promise<void> {
|
|
|
111
116
|
|
|
112
117
|
// Detect when agent asks for continuation
|
|
113
118
|
pi.on("message_end", async (event) => {
|
|
114
|
-
const msg = event.message as { role?: string; content?: string } | undefined;
|
|
119
|
+
const msg = event.message as { role?: string; content?: string | Array<{ type?: string; text?: string }> } | undefined;
|
|
115
120
|
if (!msg || msg.role !== "assistant") return;
|
|
116
121
|
|
|
117
|
-
|
|
122
|
+
// Extract text from array content (TextContent blocks) or legacy string
|
|
123
|
+
let content = "";
|
|
124
|
+
if (typeof msg.content === "string") {
|
|
125
|
+
content = msg.content;
|
|
126
|
+
} else if (Array.isArray(msg.content)) {
|
|
127
|
+
// Extract text from TextContent blocks only; ignore thinking/tool calls
|
|
128
|
+
content = msg.content
|
|
129
|
+
.filter((block): block is { type: "text"; text: string } =>
|
|
130
|
+
block.type === "text" && typeof block.text === "string"
|
|
131
|
+
)
|
|
132
|
+
.map(block => block.text)
|
|
133
|
+
.join("\n");
|
|
134
|
+
}
|
|
118
135
|
const hasContinuation = /continue|proceed|next phase|next step/i.test(content);
|
|
119
136
|
|
|
120
137
|
if (hasContinuation && !waitingForUserSince) {
|
|
@@ -154,7 +171,7 @@ async function initAutoContinue(pi: ExtensionAPI): Promise<void> {
|
|
|
154
171
|
|
|
155
172
|
try {
|
|
156
173
|
const judge = new mod.AutoContinueJudge({
|
|
157
|
-
apiKey:
|
|
174
|
+
apiKey: resolvedApiKey,
|
|
158
175
|
proceedThreshold: 0.7,
|
|
159
176
|
maxWaitMinutes: 30,
|
|
160
177
|
});
|
|
@@ -336,7 +353,7 @@ async function initHoncho(pi: { events: { emit(name: string, data: unknown): voi
|
|
|
336
353
|
const keyPath = `${home}/.pi-harness-runtime/keys/honcho-api-key.txt`;
|
|
337
354
|
|
|
338
355
|
if (!existsSync(keyPath)) {
|
|
339
|
-
logStartup("[pi-harness] Honcho
|
|
356
|
+
logStartup("[pi-harness] Honcho not configured:");
|
|
340
357
|
logStartup("[pi-harness] Get key: https://app.honcho.dev/api-keys");
|
|
341
358
|
logStartup(`[pi-harness] Then: echo "{api-key}" > ~/.pi-harness-runtime/keys/honcho-api-key.txt`);
|
|
342
359
|
return;
|
|
@@ -356,12 +373,19 @@ async function initHoncho(pi: { events: { emit(name: string, data: unknown): voi
|
|
|
356
373
|
name: "honcho",
|
|
357
374
|
definition: {
|
|
358
375
|
url: "https://mcp.honcho.dev",
|
|
359
|
-
auth:
|
|
376
|
+
auth: "bearer" as const,
|
|
377
|
+
bearerToken: apiKey,
|
|
360
378
|
},
|
|
361
379
|
};
|
|
380
|
+
|
|
381
|
+
// Emit registration request — pi-mcp-adapter will respond with
|
|
382
|
+
// pi-mcp-adapter:runtime-register-result event on completion
|
|
362
383
|
pi.events.emit("pi-mcp-adapter:runtime-register:v1", request);
|
|
384
|
+
console.log("[honcho] MCP registration emitted (awaiting adapter ack)");
|
|
363
385
|
});
|
|
364
|
-
|
|
386
|
+
|
|
387
|
+
// Report pending state — actual memory active requires explicit lifecycle
|
|
388
|
+
logStartup("[pi-harness] Honcho registered (awaiting adapter connection)");
|
|
365
389
|
} catch (err) {
|
|
366
390
|
logStartup("[pi-harness] Honcho: init failed:", err instanceof Error ? err.message : String(err));
|
|
367
391
|
}
|
|
@@ -648,6 +672,27 @@ async function initFileCopyHelper(pi: ExtensionAPI): Promise<void> {
|
|
|
648
672
|
}
|
|
649
673
|
}
|
|
650
674
|
|
|
675
|
+
// --- agent-policy: Mandatory rule delivery and mutation gating ------------------
|
|
676
|
+
// Lazy import - only loads when packages/agent-policy exists
|
|
677
|
+
// This replaces firstAgentStart-only injection with:
|
|
678
|
+
// - System prompt injection on EVERY agent start (not just first)
|
|
679
|
+
// - Policy receipt tracking per session
|
|
680
|
+
// - Mutation gating until policy revision is confirmed received
|
|
681
|
+
// - harness_rules tool for rule retrieval and acknowledgement
|
|
682
|
+
async function initAgentPolicy(pi: ExtensionAPI): Promise<void> {
|
|
683
|
+
try {
|
|
684
|
+
const { registerAgentPolicy } = await import("./packages/agent-policy/src/extension.js");
|
|
685
|
+
registerAgentPolicy(pi, {
|
|
686
|
+
harnessRulesPath: new URL("./AGENTS.md", import.meta.url),
|
|
687
|
+
requireReceiptBeforeMutation: true,
|
|
688
|
+
lspMode: "pi-lens",
|
|
689
|
+
});
|
|
690
|
+
logStartup("[pi-harness] Agent policy initialized");
|
|
691
|
+
} catch (err) {
|
|
692
|
+
logStartup(`[pi-harness] Agent policy init failed: ${err}`);
|
|
693
|
+
}
|
|
694
|
+
}
|
|
695
|
+
|
|
651
696
|
// --- SSH detach interceptor: Auto-transform bare ssh ... & to detached pattern ---
|
|
652
697
|
// Prevents 2000+ second hangs when SSH background commands aren't detached.
|
|
653
698
|
// Intercepts every bash tool call before execution and rewrites risky SSH commands.
|
|
@@ -1173,6 +1218,9 @@ export default function (pi: ExtensionAPI) {
|
|
|
1173
1218
|
// --- file-copy-helper: Inject cp rule when mimicking files -------------
|
|
1174
1219
|
void initFileCopyHelper(pi);
|
|
1175
1220
|
|
|
1221
|
+
// --- agent-policy: Mandatory rule delivery and mutation gating -------------
|
|
1222
|
+
void initAgentPolicy(pi);
|
|
1223
|
+
|
|
1176
1224
|
// --- ssh-detach-interceptor: Auto-fix bare ssh & → nohup pattern ---------
|
|
1177
1225
|
void initSshDetachInterceptor(pi);
|
|
1178
1226
|
|
package/package.json
CHANGED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agent Policy Extension
|
|
3
|
+
*
|
|
4
|
+
* Registers the policy runtime with Pi's event system:
|
|
5
|
+
* - before_agent_start: inject system contract
|
|
6
|
+
* - tool_call: gate mutations until policy received
|
|
7
|
+
* - harness_rules tool: retrieve and acknowledge rules
|
|
8
|
+
*/
|
|
9
|
+
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
|
10
|
+
import type { AgentPolicyConfig } from "./types.js";
|
|
11
|
+
/**
|
|
12
|
+
* Register the agent policy runtime with Pi.
|
|
13
|
+
*/
|
|
14
|
+
export declare function registerAgentPolicy(pi: ExtensionAPI, config: AgentPolicyConfig): void;
|
|
15
|
+
/**
|
|
16
|
+
* Register with default configuration pointing to harness AGENTS.md.
|
|
17
|
+
*/
|
|
18
|
+
export declare function registerDefault(pi: ExtensionAPI): void;
|
|
19
|
+
//# sourceMappingURL=extension.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"extension.d.ts","sourceRoot":"","sources":["../src/extension.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EACV,YAAY,EAIb,MAAM,iCAAiC,CAAC;AACzC,OAAO,KAAK,EACV,iBAAiB,EAElB,MAAM,YAAY,CAAC;AAapB;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,EAAE,EAAE,YAAY,EAChB,MAAM,EAAE,iBAAiB,GACxB,IAAI,CA8SN;AA8DD;;GAEG;AACH,wBAAgB,eAAe,CAAC,EAAE,EAAE,YAAY,GAAG,IAAI,CAQtD"}
|