pi-harness-runtime 1.1.403 → 1.1.405
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/index.ts +275 -1
- package/package.json +1 -1
- package/packages/a2a-adapter/package.json +1 -1
- package/packages/agent-policy/package.json +1 -1
- 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/package.json +1 -1
- package/packages/config-capture/package.json +1 -1
- package/packages/connection-runtime/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/contracts/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/durable-review/package.json +1 -1
- package/packages/e2e-tester/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-sink/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/dist/auto-continue.d.ts +6 -0
- package/packages/jev-judge/dist/auto-continue.d.ts.map +1 -1
- package/packages/jev-judge/dist/auto-continue.js +13 -3
- package/packages/jev-judge/dist/auto-continue.js.map +1 -1
- package/packages/jev-judge/package.json +1 -1
- package/packages/jev-judge/src/auto-continue.ts +17 -3
- package/packages/jev-judge/tests/auto-continue-context.test.ts +37 -0
- 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/logging/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/line-adapter.d.ts.map +1 -1
- package/packages/notification/dist/adapters/line-adapter.js +6 -1
- package/packages/notification/dist/adapters/line-adapter.js.map +1 -1
- package/packages/notification/dist/notification-center.d.ts.map +1 -1
- package/packages/notification/dist/notification-center.js +32 -0
- package/packages/notification/dist/notification-center.js.map +1 -1
- package/packages/notification/dist/telegram-webhook-handler.d.ts +7 -0
- package/packages/notification/dist/telegram-webhook-handler.d.ts.map +1 -1
- package/packages/notification/dist/telegram-webhook-handler.js +7 -0
- package/packages/notification/dist/telegram-webhook-handler.js.map +1 -1
- package/packages/notification/dist/types.d.ts +1 -1
- package/packages/notification/dist/types.d.ts.map +1 -1
- package/packages/notification/package.json +1 -1
- package/packages/notification/src/adapters/line-adapter.ts +7 -1
- package/packages/notification/src/notification-center.ts +30 -0
- package/packages/notification/src/telegram-webhook-handler.ts +7 -0
- package/packages/notification/src/types.ts +1 -0
- package/packages/notification/test/notification.test.ts +31 -28
- package/packages/notification/test/tooling-proposal-payload.test.ts +212 -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/permission-mode/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/package.json +1 -1
- 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/relay/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/package.json +1 -1
- 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/telegram/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/tooling-preference/dist/detect.d.ts +62 -0
- package/packages/tooling-preference/dist/detect.d.ts.map +1 -0
- package/packages/tooling-preference/dist/detect.js +209 -0
- package/packages/tooling-preference/dist/detect.js.map +1 -0
- package/packages/tooling-preference/dist/index.d.ts +13 -0
- package/packages/tooling-preference/dist/index.d.ts.map +1 -0
- package/packages/tooling-preference/dist/index.js +13 -0
- package/packages/tooling-preference/dist/index.js.map +1 -0
- package/packages/tooling-preference/dist/proposal.d.ts +70 -0
- package/packages/tooling-preference/dist/proposal.d.ts.map +1 -0
- package/packages/tooling-preference/dist/proposal.js +137 -0
- package/packages/tooling-preference/dist/proposal.js.map +1 -0
- package/packages/tooling-preference/dist/registry.d.ts +50 -0
- package/packages/tooling-preference/dist/registry.d.ts.map +1 -0
- package/packages/tooling-preference/dist/registry.js +53 -0
- package/packages/tooling-preference/dist/registry.js.map +1 -0
- package/packages/tooling-preference/dist/store.d.ts +61 -0
- package/packages/tooling-preference/dist/store.d.ts.map +1 -0
- package/packages/tooling-preference/dist/store.js +129 -0
- package/packages/tooling-preference/dist/store.js.map +1 -0
- package/packages/tooling-preference/package.json +21 -0
- package/packages/tooling-preference/src/detect.ts +251 -0
- package/packages/tooling-preference/src/index.ts +44 -0
- package/packages/tooling-preference/src/proposal.ts +173 -0
- package/packages/tooling-preference/src/registry.ts +79 -0
- package/packages/tooling-preference/src/store.ts +162 -0
- package/packages/tooling-preference/tests/detect.test.ts +188 -0
- package/packages/tooling-preference/tests/proposal.test.ts +107 -0
- package/packages/tooling-preference/tests/registry.test.ts +51 -0
- package/packages/tooling-preference/tests/store.test.ts +99 -0
- package/packages/trajectory/package.json +1 -1
- package/packages/tui/package.json +1 -1
- package/packages/types/package.json +1 -1
- package/packages/voice-api/package.json +1 -1
- package/packages/webmcp-tester/package.json +1 -1
- package/packages/wiki/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/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,13 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
|
|
4
4
|
|
|
5
|
+
### [1.1.190](https://github.com/ManotLuijiu/pi-harness-runtime/compare/v1.1.403...v1.1.190) (2026-10-24)
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
### Bug Fixes
|
|
9
|
+
|
|
10
|
+
* **jev:** apply the caution threshold to a cautious approval ([9c6836e](https://github.com/ManotLuijiu/pi-harness-runtime/commit/9c6836e569e70140175a37f62e978d2a08ba27d7))
|
|
11
|
+
|
|
5
12
|
### [1.1.189](https://github.com/ManotLuijiu/pi-harness-runtime/compare/v1.1.402...v1.1.189) (2026-10-24)
|
|
6
13
|
|
|
7
14
|
|
package/index.ts
CHANGED
|
@@ -296,6 +296,240 @@ function waitBelongsToRequest(requestId: string | undefined): boolean {
|
|
|
296
296
|
return active === requestId;
|
|
297
297
|
}
|
|
298
298
|
|
|
299
|
+
// --- tooling-preference: the Biome proposal ---------------------------------
|
|
300
|
+
//
|
|
301
|
+
// The proposal ("use Biome.js instead of ESLint and Prettier") is a decision
|
|
302
|
+
// of its own. It never travels through the task-approval path: a "No" here
|
|
303
|
+
// must not pause the work and a "Yes" must not resume a pending question.
|
|
304
|
+
|
|
305
|
+
/** The proposals of this session - the first answer wins. */
|
|
306
|
+
interface ToolingProposalRequest {
|
|
307
|
+
requestId: string;
|
|
308
|
+
workspaceRoot: string;
|
|
309
|
+
userKey: string;
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
interface ToolingProposalRegistry {
|
|
313
|
+
register(request: ToolingProposalRequest): boolean;
|
|
314
|
+
claim(
|
|
315
|
+
requestId: string,
|
|
316
|
+
choice: "yes" | "no",
|
|
317
|
+
channel?: string,
|
|
318
|
+
): {
|
|
319
|
+
request: ToolingProposalRequest;
|
|
320
|
+
resolution: {
|
|
321
|
+
choice: "yes" | "no";
|
|
322
|
+
preference: "prefer_biome" | "use_project_tools";
|
|
323
|
+
channel?: string;
|
|
324
|
+
};
|
|
325
|
+
} | null;
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
interface ToolingProposalStore {
|
|
329
|
+
read(
|
|
330
|
+
userKey: string,
|
|
331
|
+
workspaceRoot: string,
|
|
332
|
+
): { decision?: "prefer_biome" | "use_project_tools"; askedAt?: string } | undefined;
|
|
333
|
+
markAsked(userKey: string, workspaceRoot: string, requestId: string): void;
|
|
334
|
+
recordDecision(
|
|
335
|
+
userKey: string,
|
|
336
|
+
workspaceRoot: string,
|
|
337
|
+
decision: "prefer_biome" | "use_project_tools",
|
|
338
|
+
requestId: string,
|
|
339
|
+
channel?: string,
|
|
340
|
+
): void;
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
let _toolingRegistry: ToolingProposalRegistry | null = null;
|
|
344
|
+
let _toolingStore: ToolingProposalStore | null = null;
|
|
345
|
+
/** The identity of the person the notifications reach (never logged). */
|
|
346
|
+
let _toolingIdentity = "";
|
|
347
|
+
/**
|
|
348
|
+
* The identity of the person the notifications reach.
|
|
349
|
+
*
|
|
350
|
+
* It is read from the channel key files, so a LINE-only setup is recognized
|
|
351
|
+
* too. The value is hashed before it is stored and never reaches a log.
|
|
352
|
+
*/
|
|
353
|
+
function readToolingIdentity(): string {
|
|
354
|
+
if (_toolingIdentity) return _toolingIdentity;
|
|
355
|
+
const home = process.env.HOME || process.env.USERPROFILE || "";
|
|
356
|
+
if (!home) return "";
|
|
357
|
+
const keysDir = `${home}/.pi-harness-runtime/keys`;
|
|
358
|
+
for (const name of ["telegram-chat-id.txt", "line-user-id.txt"]) {
|
|
359
|
+
try {
|
|
360
|
+
const value = readFileSync(`${keysDir}/${name}`, "utf8").trim();
|
|
361
|
+
if (value) {
|
|
362
|
+
_toolingIdentity = value;
|
|
363
|
+
return value;
|
|
364
|
+
}
|
|
365
|
+
} catch {
|
|
366
|
+
// The key file is optional - the channel may not be configured.
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
return "";
|
|
370
|
+
}
|
|
371
|
+
/** The running extension API - the relay path has no `pi` of its own. */
|
|
372
|
+
let _extensionApi: ExtensionAPI | null = null;
|
|
373
|
+
/** How long an unanswered proposal stays quiet before it is offered again. */
|
|
374
|
+
const TOOLING_PROPOSAL_COOLDOWN_MS = 30 * 24 * 60 * 60 * 1000;
|
|
375
|
+
|
|
376
|
+
/**
|
|
377
|
+
* Load the tooling preference package and watch for the session start.
|
|
378
|
+
*
|
|
379
|
+
* The proposal is offered once per workspace: the answer is stored, and a
|
|
380
|
+
* workspace that already uses Biome is never asked at all.
|
|
381
|
+
*/
|
|
382
|
+
async function initToolingPreference(pi: ExtensionAPI): Promise<void> {
|
|
383
|
+
try {
|
|
384
|
+
const mod = await import("./packages/tooling-preference/dist/index.js");
|
|
385
|
+
_toolingRegistry = new mod.ToolingRequestRegistry();
|
|
386
|
+
_toolingStore = new mod.ToolingPreferenceStore(
|
|
387
|
+
mod.ToolingPreferenceStore.defaultFilePath(),
|
|
388
|
+
);
|
|
389
|
+
} catch (error) {
|
|
390
|
+
logToFile("[ToolingPreference]", `package unavailable: ${oneLineError(error)}`);
|
|
391
|
+
return;
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
pi.on("session_start", () => {
|
|
395
|
+
void offerToolingPreference();
|
|
396
|
+
});
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
/**
|
|
400
|
+
* Offer the tooling proposal for the workspace of this session.
|
|
401
|
+
*
|
|
402
|
+
* The proposal never blocks: it is a message with two buttons, and the work
|
|
403
|
+
* continues while the user decides.
|
|
404
|
+
*/
|
|
405
|
+
async function offerToolingPreference(): Promise<void> {
|
|
406
|
+
const registry = _toolingRegistry;
|
|
407
|
+
const store = _toolingStore;
|
|
408
|
+
const center = _nc?.center as NcCenter | undefined;
|
|
409
|
+
if (!registry || !store || !center?.notifyWithButtons) return;
|
|
410
|
+
|
|
411
|
+
let workspaceRoot: string;
|
|
412
|
+
try {
|
|
413
|
+
workspaceRoot = realpathSync(process.cwd());
|
|
414
|
+
} catch {
|
|
415
|
+
return;
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
try {
|
|
419
|
+
const mod = await import("./packages/tooling-preference/dist/index.js");
|
|
420
|
+
const userKey = mod.buildToolingUserKey(readToolingIdentity());
|
|
421
|
+
const record = store.read(userKey, workspaceRoot);
|
|
422
|
+
if (!mod.shouldAskAgain(record, TOOLING_PROPOSAL_COOLDOWN_MS)) return;
|
|
423
|
+
|
|
424
|
+
const context = mod.detectToolingContext(workspaceRoot);
|
|
425
|
+
const eligibility = mod.evaluateBiomeProposalEligibility(context);
|
|
426
|
+
if (!eligibility.eligible) {
|
|
427
|
+
logToFile("[ToolingPreference]", `no proposal: ${eligibility.reason}`);
|
|
428
|
+
return;
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
const requestId = mod.buildToolingRequestId(userKey, workspaceRoot);
|
|
432
|
+
if (!registry.register({ requestId, workspaceRoot, userKey })) return;
|
|
433
|
+
|
|
434
|
+
await center.notifyWithButtons(
|
|
435
|
+
"ToolingPreferenceProposal",
|
|
436
|
+
{
|
|
437
|
+
jobId: requestId,
|
|
438
|
+
questionId: requestId,
|
|
439
|
+
requirement: mod.buildToolingProposalMessage(context),
|
|
440
|
+
taskTitle: "Biome.js proposal",
|
|
441
|
+
},
|
|
442
|
+
mod.buildToolingButtons(requestId),
|
|
443
|
+
{ additionalDetails: { _actionPrompt: "Use Biome.js in this workspace?" } },
|
|
444
|
+
);
|
|
445
|
+
store.markAsked(userKey, workspaceRoot, requestId);
|
|
446
|
+
logToFile("[ToolingPreference]", `proposal sent (${requestId})`);
|
|
447
|
+
} catch (error) {
|
|
448
|
+
logToFile("[ToolingPreference]", `proposal failed: ${oneLineError(error)}`);
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
/**
|
|
453
|
+
* Apply the answer of the user to the tooling proposal.
|
|
454
|
+
*
|
|
455
|
+
* The first answer wins: a second click finds nothing and changes nothing.
|
|
456
|
+
*/
|
|
457
|
+
async function resolveToolingPreference(
|
|
458
|
+
targetId: string,
|
|
459
|
+
channel: "telegram" | "line",
|
|
460
|
+
pi: ExtensionAPI | null,
|
|
461
|
+
): Promise<{ applied: boolean; reason: string }> {
|
|
462
|
+
const registry = _toolingRegistry;
|
|
463
|
+
const store = _toolingStore;
|
|
464
|
+
if (!registry || !store) {
|
|
465
|
+
return { applied: false, reason: "no proposal is open" };
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
let target: { choice: "yes" | "no"; requestId: string } | null = null;
|
|
469
|
+
try {
|
|
470
|
+
const mod = await import("./packages/tooling-preference/dist/index.js");
|
|
471
|
+
target = mod.parseToolingTarget(targetId);
|
|
472
|
+
} catch (error) {
|
|
473
|
+
logToFile("[ToolingPreference]", `package unavailable: ${oneLineError(error)}`);
|
|
474
|
+
return { applied: false, reason: "the proposal cannot be read" };
|
|
475
|
+
}
|
|
476
|
+
if (!target) {
|
|
477
|
+
return { applied: false, reason: "the button does not belong to a proposal" };
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
const claimed = registry.claim(target.requestId, target.choice, channel);
|
|
481
|
+
if (!claimed) {
|
|
482
|
+
return { applied: false, reason: "the proposal was already answered" };
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
store.recordDecision(
|
|
486
|
+
claimed.request.userKey,
|
|
487
|
+
claimed.request.workspaceRoot,
|
|
488
|
+
claimed.resolution.preference,
|
|
489
|
+
target.requestId,
|
|
490
|
+
channel,
|
|
491
|
+
);
|
|
492
|
+
logToFile(
|
|
493
|
+
"[ToolingPreference]",
|
|
494
|
+
`${channel} answered the proposal: ${claimed.resolution.preference}`,
|
|
495
|
+
);
|
|
496
|
+
|
|
497
|
+
if (claimed.resolution.choice === "yes" && pi) {
|
|
498
|
+
await startBiomeImplementation(claimed.request.workspaceRoot, channel, pi);
|
|
499
|
+
}
|
|
500
|
+
return {
|
|
501
|
+
applied: true,
|
|
502
|
+
reason:
|
|
503
|
+
claimed.resolution.choice === "yes"
|
|
504
|
+
? "Biome.js will be implemented"
|
|
505
|
+
: "the current tools stay",
|
|
506
|
+
};
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
/**
|
|
510
|
+
* Start the Biome implementation after a "Yes".
|
|
511
|
+
*
|
|
512
|
+
* The harness does not change the repository itself: the agent does the
|
|
513
|
+
* work, so the change stays reviewable in the session.
|
|
514
|
+
*/
|
|
515
|
+
async function startBiomeImplementation(
|
|
516
|
+
workspaceRoot: string,
|
|
517
|
+
channel: string,
|
|
518
|
+
pi: ExtensionAPI,
|
|
519
|
+
): Promise<void> {
|
|
520
|
+
try {
|
|
521
|
+
const mod = await import("./packages/tooling-preference/dist/index.js");
|
|
522
|
+
const context = mod.detectToolingContext(workspaceRoot);
|
|
523
|
+
await pi.sendUserMessage(
|
|
524
|
+
mod.buildToolingImplementationPrompt(context, workspaceRoot),
|
|
525
|
+
{ deliverAs: "steer" },
|
|
526
|
+
);
|
|
527
|
+
logToFile("[ToolingPreference]", `agent asked to implement Biome (${channel})`);
|
|
528
|
+
} catch (error) {
|
|
529
|
+
logToFile("[ToolingPreference]", `steer failed: ${oneLineError(error)}`);
|
|
530
|
+
}
|
|
531
|
+
}
|
|
532
|
+
|
|
299
533
|
async function initAutoContinue(pi: ExtensionAPI): Promise<void> {
|
|
300
534
|
addHarnessMessage("Jev", "initializing", "wait");
|
|
301
535
|
try {
|
|
@@ -1656,6 +1890,10 @@ async function initTelegram(pi: ExtensionAPI): Promise<void> {
|
|
|
1656
1890
|
const lineAccessToken = hasLineCredentials ? readFileSync(lineTokenPath, "utf8").trim() : null;
|
|
1657
1891
|
const lineUserId = hasLineCredentials ? readFileSync(lineUserIdPath, "utf8").trim() : null;
|
|
1658
1892
|
|
|
1893
|
+
// The identity of the person the notifications reach. It is hashed
|
|
1894
|
+
// before it is stored and never reaches a log file.
|
|
1895
|
+
_toolingIdentity = chatId || lineUserId || "";
|
|
1896
|
+
|
|
1659
1897
|
if (!botToken || !chatId) {
|
|
1660
1898
|
logStartup("[pi-harness] Telegram: bot token or chat ID is empty — skipping");
|
|
1661
1899
|
const emptyFixes = keyFileFixesOrFallback("Telegram", ["bot token", "chat id"]);
|
|
@@ -1782,6 +2020,21 @@ async function initTelegram(pi: ExtensionAPI): Promise<void> {
|
|
|
1782
2020
|
}
|
|
1783
2021
|
|
|
1784
2022
|
switch (parsed.action) {
|
|
2023
|
+
case CallbackActions.TOOLING_PREFERENCE: {
|
|
2024
|
+
// The proposal is a decision of its own: it never resolves a
|
|
2025
|
+
// pending question and it never pauses the work.
|
|
2026
|
+
const result = await resolveToolingPreference(
|
|
2027
|
+
parsed.targetId,
|
|
2028
|
+
"telegram",
|
|
2029
|
+
pi,
|
|
2030
|
+
);
|
|
2031
|
+
await acknowledge(
|
|
2032
|
+
result.applied
|
|
2033
|
+
? `Saved - ${result.reason}`
|
|
2034
|
+
: `Stale button - ${result.reason}`,
|
|
2035
|
+
);
|
|
2036
|
+
break;
|
|
2037
|
+
}
|
|
1785
2038
|
case CallbackActions.APPROVE: {
|
|
1786
2039
|
// The user clicked Continue. The request ID in the
|
|
1787
2040
|
// callback data is the canonical one, so the click
|
|
@@ -2268,7 +2521,21 @@ async function initRelayStream(): Promise<void> {
|
|
|
2268
2521
|
// A LINE postback is the same decision as a Telegram button
|
|
2269
2522
|
// click: one resolver, the same canonical request ID.
|
|
2270
2523
|
if (callback.type === "line_callback") {
|
|
2271
|
-
|
|
2524
|
+
if (
|
|
2525
|
+
callback.action === "biome" ||
|
|
2526
|
+
callback.action.startsWith("biome_")
|
|
2527
|
+
) {
|
|
2528
|
+
// The tooling proposal is a decision of its own: it never
|
|
2529
|
+
// resolves a pending question and it never pauses the
|
|
2530
|
+
// work. The postback data may arrive split or as one
|
|
2531
|
+
// string - both carry the choice and the request ID.
|
|
2532
|
+
const raw = callback.action.startsWith("biome_")
|
|
2533
|
+
? callback.action.slice("biome_".length)
|
|
2534
|
+
: callback.targetId;
|
|
2535
|
+
await resolveToolingPreference(raw, "line", _extensionApi);
|
|
2536
|
+
} else {
|
|
2537
|
+
applyChannelApproval(callback.action, callback.targetId, "line");
|
|
2538
|
+
}
|
|
2272
2539
|
}
|
|
2273
2540
|
|
|
2274
2541
|
// Forward Telegram callbacks to the adapter
|
|
@@ -3621,6 +3888,9 @@ export default async function (pi: ExtensionAPI) {
|
|
|
3621
3888
|
const tracker = new UsageTracker();
|
|
3622
3889
|
const mirrorStore = new MirrorStore();
|
|
3623
3890
|
ensureHarnessDir();
|
|
3891
|
+
// The relay path has no `pi` of its own - the extension API is kept
|
|
3892
|
+
// here so every path can reach the agent.
|
|
3893
|
+
_extensionApi = pi;
|
|
3624
3894
|
|
|
3625
3895
|
// --- central-logging: ship structured logs to R2 / the webhook server ---
|
|
3626
3896
|
// The pipeline is opt-in by configuration, never by code: without R2
|
|
@@ -3675,6 +3945,10 @@ export default async function (pi: ExtensionAPI) {
|
|
|
3675
3945
|
// Collect promise so we can wait for initialization before showing startup notification
|
|
3676
3946
|
asyncInitPromises.push(initQdrant());
|
|
3677
3947
|
|
|
3948
|
+
// --- tooling-preference: offer Biome.js instead of ESLint/Prettier ------
|
|
3949
|
+
// The proposal is a decision of its own: it never pauses the work.
|
|
3950
|
+
void initToolingPreference(pi);
|
|
3951
|
+
|
|
3678
3952
|
// --- telegram-notifications: Telegram bot for harness event notifications ----
|
|
3679
3953
|
// Collect promise so we can wait for initialization before showing startup notification
|
|
3680
3954
|
asyncInitPromises.push(
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pi-harness/capability-registry",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.405",
|
|
4
4
|
"description": "Capability Registry for pi-harness-runtime — tracks model capabilities and enables capability-based routing",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|