@evo-dev/core 0.0.1-alpha.5 → 0.0.1-alpha.7
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/dist/config/index.js +6 -36
- package/dist/index.js +724 -1590
- package/package.json +1 -1
- package/src/agents/index.ts +0 -264
- package/src/code-agent-traces/index.ts +8 -2
- package/src/daemon/index.ts +0 -40
- package/src/evolution/candidates/index.ts +77 -18
- package/src/evolution/evidence/session-memory/storage.ts +50 -0
- package/src/evolution/evidence/session-memory/updater.ts +8 -1
- package/src/evolution/review/index.ts +3 -9
- package/src/evolution/schema.ts +0 -1
- package/src/hooks/index.ts +112 -179
- package/src/index.ts +1 -2
- package/src/projects/index.ts +453 -0
- package/src/workflow/index.ts +3 -21
- package/src/project/index.ts +0 -507
- package/src/task/index.ts +0 -840
package/src/hooks/index.ts
CHANGED
|
@@ -14,13 +14,8 @@ import {
|
|
|
14
14
|
enqueueEvolutionTrigger,
|
|
15
15
|
resolveEvolutionTriggerDecision,
|
|
16
16
|
} from "../evolution/triggers/index.ts";
|
|
17
|
-
import {
|
|
18
|
-
import {
|
|
19
|
-
type TaskContract,
|
|
20
|
-
createTaskContract,
|
|
21
|
-
routeTaskContract,
|
|
22
|
-
writeTaskContract,
|
|
23
|
-
} from "../task/index.ts";
|
|
17
|
+
import { recordDiscoveredProject } from "../projects/index.ts";
|
|
18
|
+
import { resolveTraceSessionKey, resolveTraceTeamContext } from "../runtime-logs/index.ts";
|
|
24
19
|
import {
|
|
25
20
|
type TeamMessageRecord,
|
|
26
21
|
createTeamRoleRuntimeContext,
|
|
@@ -159,10 +154,7 @@ export interface HookRuntimeSessionBinding {
|
|
|
159
154
|
version: 1;
|
|
160
155
|
target: CodeAgentHookTarget;
|
|
161
156
|
sessionKey: string;
|
|
162
|
-
taskId: string | null;
|
|
163
|
-
contractPath: string | null;
|
|
164
157
|
cwd: string | null;
|
|
165
|
-
route: TaskContract["route"] | null;
|
|
166
158
|
teamRuntimeContextDeliveredAt?: string | null;
|
|
167
159
|
updatedAt: string;
|
|
168
160
|
}
|
|
@@ -234,6 +226,12 @@ const CODEX_STOP_EVENTS_WITHOUT_ADDITIONAL_CONTEXT = new Set<CanonicalHookEventT
|
|
|
234
226
|
"Stop",
|
|
235
227
|
"SubagentStop",
|
|
236
228
|
]);
|
|
229
|
+
const COMPLETION_EVENTS_WITHOUT_DEVELOPMENT_DIAGNOSTICS = new Set<CanonicalHookEventType>([
|
|
230
|
+
"Stop",
|
|
231
|
+
"SubagentStop",
|
|
232
|
+
"TaskCompleted",
|
|
233
|
+
"TeammateIdle",
|
|
234
|
+
]);
|
|
237
235
|
|
|
238
236
|
export function createDefaultHookSettings(): HookSettings {
|
|
239
237
|
return {
|
|
@@ -424,12 +422,11 @@ export function formatHookEventDryRun(event: HookEventV1): string {
|
|
|
424
422
|
export function resolveHookRuntimeSessionPaths(input: {
|
|
425
423
|
homeDir: string;
|
|
426
424
|
sessionKey: string;
|
|
427
|
-
}): { sessionDir: string; bindingPath: string
|
|
425
|
+
}): { sessionDir: string; bindingPath: string } {
|
|
428
426
|
const sessionDir = join(input.homeDir, ".evodev", "STATE", "hooks", "sessions", input.sessionKey);
|
|
429
427
|
return {
|
|
430
428
|
sessionDir,
|
|
431
429
|
bindingPath: join(sessionDir, "binding.json"),
|
|
432
|
-
contractPath: join(sessionDir, "contract.json"),
|
|
433
430
|
};
|
|
434
431
|
}
|
|
435
432
|
|
|
@@ -447,7 +444,14 @@ export async function handleHookRuntime(input: HandleHookRuntimeInput): Promise<
|
|
|
447
444
|
};
|
|
448
445
|
}
|
|
449
446
|
|
|
447
|
+
if (isActiveClaudeStopHook(input)) {
|
|
448
|
+
return createRuntimeResult(input, null, {
|
|
449
|
+
summary: `${input.event.type} re-entry allowed to complete without hook output.`,
|
|
450
|
+
});
|
|
451
|
+
}
|
|
452
|
+
|
|
450
453
|
const diagnostics = await recordTeamNativeSessionFromHook(input);
|
|
454
|
+
const projectDiagnostics = await recordDiscoveredProjectFromHook(input);
|
|
451
455
|
let result: HookRuntimeResult | undefined;
|
|
452
456
|
if (input.event.type === "SessionStart") result = await handleSessionStart(input);
|
|
453
457
|
else if (input.event.type === "UserPromptSubmit") result = await handleUserPromptSubmit(input);
|
|
@@ -485,12 +489,15 @@ export async function handleHookRuntime(input: HandleHookRuntimeInput): Promise<
|
|
|
485
489
|
const messageDiagnostics = await deliverPendingTeamMessagesFromHook(input, result);
|
|
486
490
|
const scopedContextDiagnostics = await injectScopedKnowledgeContextFromHook(input, result);
|
|
487
491
|
const teamStateDiagnostics = await recordTeamAgentHookStateFromHook(input);
|
|
488
|
-
|
|
492
|
+
const completed = appendRuntimeDiagnostics(
|
|
489
493
|
appendRuntimeDiagnostics(
|
|
490
494
|
appendRuntimeDiagnostics(
|
|
491
495
|
appendRuntimeDiagnostics(
|
|
492
496
|
appendRuntimeDiagnostics(
|
|
493
|
-
appendRuntimeDiagnostics(
|
|
497
|
+
appendRuntimeDiagnostics(
|
|
498
|
+
appendRuntimeDiagnostics(result, diagnostics),
|
|
499
|
+
projectDiagnostics,
|
|
500
|
+
),
|
|
494
501
|
sessionMemoryDiagnostics,
|
|
495
502
|
),
|
|
496
503
|
evolutionDiagnostics,
|
|
@@ -501,6 +508,7 @@ export async function handleHookRuntime(input: HandleHookRuntimeInput): Promise<
|
|
|
501
508
|
),
|
|
502
509
|
teamStateDiagnostics,
|
|
503
510
|
);
|
|
511
|
+
return appendDevelopmentHookDiagnostics(input, completed);
|
|
504
512
|
}
|
|
505
513
|
|
|
506
514
|
export function formatHookRuntimeOutput(result: HookRuntimeResult): string {
|
|
@@ -524,6 +532,41 @@ interface HookRuntimeDiagnostics {
|
|
|
524
532
|
warnings: string[];
|
|
525
533
|
}
|
|
526
534
|
|
|
535
|
+
async function recordDiscoveredProjectFromHook(
|
|
536
|
+
input: HandleHookRuntimeInput,
|
|
537
|
+
): Promise<HookRuntimeDiagnostics> {
|
|
538
|
+
if (
|
|
539
|
+
input.event.type !== "SessionStart" &&
|
|
540
|
+
input.event.type !== "UserPromptSubmit" &&
|
|
541
|
+
input.event.type !== "CwdChanged"
|
|
542
|
+
) {
|
|
543
|
+
return { stateWrites: [], warnings: [] };
|
|
544
|
+
}
|
|
545
|
+
const cwd = optionalPayloadString(input.rawPayload.cwd);
|
|
546
|
+
if (cwd === null) return { stateWrites: [], warnings: [] };
|
|
547
|
+
|
|
548
|
+
try {
|
|
549
|
+
const result = await recordDiscoveredProject({
|
|
550
|
+
homeDir: input.homeDir,
|
|
551
|
+
cwd,
|
|
552
|
+
target: input.target,
|
|
553
|
+
sessionKey: resolveTraceSessionKey(input.rawPayload),
|
|
554
|
+
now:
|
|
555
|
+
input.receivedAt === undefined || input.receivedAt === "dry-run"
|
|
556
|
+
? undefined
|
|
557
|
+
: input.receivedAt,
|
|
558
|
+
});
|
|
559
|
+
return result === null
|
|
560
|
+
? { stateWrites: [], warnings: [] }
|
|
561
|
+
: { stateWrites: [result.path], warnings: [] };
|
|
562
|
+
} catch {
|
|
563
|
+
return {
|
|
564
|
+
stateWrites: [],
|
|
565
|
+
warnings: ["Local project discovery could not be updated at this hook safe point."],
|
|
566
|
+
};
|
|
567
|
+
}
|
|
568
|
+
}
|
|
569
|
+
|
|
527
570
|
async function recordTeamNativeSessionFromHook(
|
|
528
571
|
input: HandleHookRuntimeInput,
|
|
529
572
|
): Promise<HookRuntimeDiagnostics> {
|
|
@@ -825,17 +868,14 @@ async function handleSessionStart(input: HandleHookRuntimeInput): Promise<HookRu
|
|
|
825
868
|
}
|
|
826
869
|
|
|
827
870
|
async function handleUserPromptSubmit(input: HandleHookRuntimeInput): Promise<HookRuntimeResult> {
|
|
828
|
-
const classification = classifyUserPrompt(input.rawPayload.prompt ?? input.rawPayload.userPrompt);
|
|
829
871
|
const sessionKey = resolveHookSessionKey(input.rawPayload);
|
|
830
872
|
const paths = resolveHookRuntimeSessionPaths({ homeDir: input.homeDir, sessionKey });
|
|
831
|
-
const contract = routeTaskContract(createHookTaskContract(input, classification));
|
|
832
873
|
const previousBinding = await readSessionBinding(input.homeDir, input.rawPayload);
|
|
833
874
|
const teamRuntimeContext =
|
|
834
875
|
previousBinding?.teamRuntimeContextDeliveredAt === undefined ||
|
|
835
876
|
previousBinding.teamRuntimeContextDeliveredAt === null
|
|
836
877
|
? await createTeamRuntimeContextForUserPrompt(input)
|
|
837
878
|
: null;
|
|
838
|
-
const shouldShowDiagnostics = input.teamRuntimeDisplayMode === "development";
|
|
839
879
|
const teamRuntimeContextDeliveredAt =
|
|
840
880
|
teamRuntimeContext !== null
|
|
841
881
|
? (input.receivedAt ?? new Date().toISOString())
|
|
@@ -844,35 +884,21 @@ async function handleUserPromptSubmit(input: HandleHookRuntimeInput): Promise<Ho
|
|
|
844
884
|
version: 1,
|
|
845
885
|
target: input.target,
|
|
846
886
|
sessionKey,
|
|
847
|
-
taskId: contract.taskId,
|
|
848
|
-
contractPath: paths.contractPath,
|
|
849
887
|
cwd: optionalPayloadString(input.rawPayload.cwd),
|
|
850
|
-
route: contract.route,
|
|
851
888
|
teamRuntimeContextDeliveredAt,
|
|
852
889
|
updatedAt: input.receivedAt ?? new Date().toISOString(),
|
|
853
890
|
};
|
|
854
891
|
|
|
855
|
-
await writeTaskContract(paths.contractPath, contract, { overwrite: true });
|
|
856
892
|
await writeJsonFile(paths.bindingPath, binding);
|
|
857
893
|
|
|
858
|
-
|
|
859
|
-
classification,
|
|
860
|
-
contract,
|
|
861
|
-
contractPath: paths.contractPath,
|
|
862
|
-
});
|
|
863
|
-
let output =
|
|
864
|
-
visibleContext === null || !shouldShowDiagnostics
|
|
865
|
-
? null
|
|
866
|
-
: hookOutput(input.event.type, {
|
|
867
|
-
additionalContext: visibleContext,
|
|
868
|
-
});
|
|
894
|
+
let output: Record<string, unknown> | null = null;
|
|
869
895
|
if (teamRuntimeContext !== null) {
|
|
870
896
|
output = appendAdditionalContext(output, input.event.type, teamRuntimeContext);
|
|
871
897
|
}
|
|
872
898
|
|
|
873
899
|
return createRuntimeResult(input, output, {
|
|
874
|
-
summary: "User prompt observed;
|
|
875
|
-
stateWrites: [paths.
|
|
900
|
+
summary: "User prompt observed; session binding updated.",
|
|
901
|
+
stateWrites: [paths.bindingPath],
|
|
876
902
|
});
|
|
877
903
|
}
|
|
878
904
|
|
|
@@ -909,46 +935,14 @@ async function handlePreToolUse(input: HandleHookRuntimeInput): Promise<HookRunt
|
|
|
909
935
|
}
|
|
910
936
|
|
|
911
937
|
async function handlePostToolUse(input: HandleHookRuntimeInput): Promise<HookRuntimeResult> {
|
|
912
|
-
|
|
913
|
-
const binding = await readSessionBinding(input.homeDir, input.rawPayload);
|
|
914
|
-
if (contract === null || binding?.contractPath === null || binding?.contractPath === undefined) {
|
|
915
|
-
return handleAdditionalContext(input, input.event.type);
|
|
916
|
-
}
|
|
917
|
-
|
|
918
|
-
const status = optionalPayloadNumber(input.rawPayload.exit_code ?? input.rawPayload.exitCode);
|
|
919
|
-
const nextContract: TaskContract = {
|
|
920
|
-
...contract,
|
|
921
|
-
evidence: {
|
|
922
|
-
metadataOnly: true,
|
|
923
|
-
items: [
|
|
924
|
-
...contract.evidence.items,
|
|
925
|
-
{
|
|
926
|
-
type: "command-result",
|
|
927
|
-
id: input.event.eventId,
|
|
928
|
-
status: status === 0 ? "pass" : status === null ? "unknown" : "fail",
|
|
929
|
-
summary: input.event.payload.summary,
|
|
930
|
-
rawOutputStored: false,
|
|
931
|
-
sourceContentStored: false,
|
|
932
|
-
},
|
|
933
|
-
],
|
|
934
|
-
},
|
|
935
|
-
};
|
|
936
|
-
await writeTaskContract(binding.contractPath, nextContract, { overwrite: true });
|
|
937
|
-
|
|
938
|
-
return createRuntimeResult(input, null, {
|
|
939
|
-
summary: "Post-tool metadata evidence recorded.",
|
|
940
|
-
stateWrites: [binding.contractPath],
|
|
941
|
-
});
|
|
938
|
+
return handleAdditionalContext(input, input.event.type);
|
|
942
939
|
}
|
|
943
940
|
|
|
944
941
|
async function handleCompletionObservation(
|
|
945
942
|
input: HandleHookRuntimeInput,
|
|
946
943
|
): Promise<HookRuntimeResult> {
|
|
947
|
-
const contract = await readActiveContract(input.homeDir, input.rawPayload);
|
|
948
|
-
const suffix =
|
|
949
|
-
contract === null ? "without an active Task Contract" : `for Task Contract ${contract.taskId}`;
|
|
950
944
|
return createRuntimeResult(input, null, {
|
|
951
|
-
summary: `${input.event.type} observed
|
|
945
|
+
summary: `${input.event.type} observed as metadata-only hook context.`,
|
|
952
946
|
});
|
|
953
947
|
}
|
|
954
948
|
|
|
@@ -1038,6 +1032,56 @@ function appendAdditionalContext(
|
|
|
1038
1032
|
};
|
|
1039
1033
|
}
|
|
1040
1034
|
|
|
1035
|
+
function appendDevelopmentHookDiagnostics(
|
|
1036
|
+
input: HandleHookRuntimeInput,
|
|
1037
|
+
result: HookRuntimeResult,
|
|
1038
|
+
): HookRuntimeResult {
|
|
1039
|
+
if (
|
|
1040
|
+
input.teamRuntimeDisplayMode !== "development" ||
|
|
1041
|
+
COMPLETION_EVENTS_WITHOUT_DEVELOPMENT_DIAGNOSTICS.has(input.event.type) ||
|
|
1042
|
+
!canDeliverTeamMessagesFromHook(input.target, input.event.type)
|
|
1043
|
+
) {
|
|
1044
|
+
return result;
|
|
1045
|
+
}
|
|
1046
|
+
return {
|
|
1047
|
+
...result,
|
|
1048
|
+
output: appendAdditionalContext(
|
|
1049
|
+
result.output,
|
|
1050
|
+
input.event.type,
|
|
1051
|
+
formatDevelopmentHookDiagnostics(input),
|
|
1052
|
+
),
|
|
1053
|
+
};
|
|
1054
|
+
}
|
|
1055
|
+
|
|
1056
|
+
function isActiveClaudeStopHook(input: HandleHookRuntimeInput): boolean {
|
|
1057
|
+
return (
|
|
1058
|
+
input.target === "claude" &&
|
|
1059
|
+
(input.event.type === "Stop" || input.event.type === "SubagentStop") &&
|
|
1060
|
+
input.rawPayload.stop_hook_active === true
|
|
1061
|
+
);
|
|
1062
|
+
}
|
|
1063
|
+
|
|
1064
|
+
function formatDevelopmentHookDiagnostics(input: HandleHookRuntimeInput): string {
|
|
1065
|
+
const metadata = Object.entries(input.event.payload.metadata);
|
|
1066
|
+
const inputFields = Object.keys(input.rawPayload)
|
|
1067
|
+
.map((field) => field.replace(/[^A-Za-z0-9._-]/g, "-").slice(0, 80))
|
|
1068
|
+
.filter((field) => field.length > 0)
|
|
1069
|
+
.slice(0, 30);
|
|
1070
|
+
return [
|
|
1071
|
+
"EvoDev hook development diagnostics",
|
|
1072
|
+
`Target: ${input.target}`,
|
|
1073
|
+
`Event: ${input.event.type}`,
|
|
1074
|
+
`Summary: ${input.event.payload.summary}`,
|
|
1075
|
+
`Input fields: ${inputFields.join(", ") || "none"}`,
|
|
1076
|
+
"Normalized metadata:",
|
|
1077
|
+
...(metadata.length === 0
|
|
1078
|
+
? ["- none"]
|
|
1079
|
+
: metadata.map(([key, value]) => `- ${key}: ${formatMetadataValue(value)}`)),
|
|
1080
|
+
`Redactions: ${input.event.payload.redactions.join(", ") || "none"}`,
|
|
1081
|
+
"Raw payload included: false",
|
|
1082
|
+
].join("\n");
|
|
1083
|
+
}
|
|
1084
|
+
|
|
1041
1085
|
function formatTeamInboxContext(messages: TeamMessageRecord[]): string {
|
|
1042
1086
|
const blocks = messages.map((message) =>
|
|
1043
1087
|
[
|
|
@@ -1061,113 +1105,6 @@ function truncateTeamMessageBody(value: string): string {
|
|
|
1061
1105
|
return `${value.slice(0, 4000)}...[truncated:${value.length - 4000}]`;
|
|
1062
1106
|
}
|
|
1063
1107
|
|
|
1064
|
-
function createUserPromptVisibleContext(input: {
|
|
1065
|
-
classification: ReturnType<typeof classifyUserPrompt>;
|
|
1066
|
-
contract: TaskContract;
|
|
1067
|
-
contractPath: string;
|
|
1068
|
-
}): string | null {
|
|
1069
|
-
if (!input.classification.needsClarification) return null;
|
|
1070
|
-
return [
|
|
1071
|
-
"EvoDev advisory: clarification may be needed before broad changes.",
|
|
1072
|
-
`Task Contract: ${input.contractPath}`,
|
|
1073
|
-
`Suggested mode: ${input.contract.route.mode ?? "unknown"}`,
|
|
1074
|
-
`Suggested workflow: ${input.contract.route.workflowId ?? "none"}`,
|
|
1075
|
-
`Reason: ${input.contract.route.rationale}`,
|
|
1076
|
-
].join(" ");
|
|
1077
|
-
}
|
|
1078
|
-
|
|
1079
|
-
function createHookTaskContract(
|
|
1080
|
-
input: HandleHookRuntimeInput,
|
|
1081
|
-
classification: ReturnType<typeof classifyUserPrompt>,
|
|
1082
|
-
): TaskContract {
|
|
1083
|
-
const sessionKey = resolveHookSessionKey(input.rawPayload);
|
|
1084
|
-
const targetName = formatHookTargetName(input.target);
|
|
1085
|
-
const contract = createTaskContract({
|
|
1086
|
-
title: `${targetName} hook task ${sessionKey}`,
|
|
1087
|
-
summary: `${targetName} prompt classified as ${classification.kind}; raw prompt is not stored by EvoDev.`,
|
|
1088
|
-
projectId: null,
|
|
1089
|
-
});
|
|
1090
|
-
|
|
1091
|
-
return {
|
|
1092
|
-
...contract,
|
|
1093
|
-
currentState: {
|
|
1094
|
-
summary: `UserPromptSubmit received through ${targetName} hooks; raw prompt omitted from Task Contract.`,
|
|
1095
|
-
evidenceRefs: [],
|
|
1096
|
-
},
|
|
1097
|
-
targetState: {
|
|
1098
|
-
summary: `Complete the ${classification.kind} task through EvoDev-controlled workflow.`,
|
|
1099
|
-
nonGoals: ["Do not store raw prompts, transcripts, source content, secrets, or raw output."],
|
|
1100
|
-
constraints: [
|
|
1101
|
-
`prompt-kind:${classification.kind}`,
|
|
1102
|
-
...classification.riskTerms.map((term) => `risk:${term}`),
|
|
1103
|
-
],
|
|
1104
|
-
},
|
|
1105
|
-
scope: {
|
|
1106
|
-
...contract.scope,
|
|
1107
|
-
requiresUserConfirmation: classification.riskTerms,
|
|
1108
|
-
},
|
|
1109
|
-
context: {
|
|
1110
|
-
...contract.context,
|
|
1111
|
-
assumptions: [
|
|
1112
|
-
`hook-session:${sessionKey}`,
|
|
1113
|
-
`cwd:${optionalPayloadString(input.rawPayload.cwd) ?? "unknown"}`,
|
|
1114
|
-
],
|
|
1115
|
-
openQuestions: classification.needsClarification
|
|
1116
|
-
? ["User request may need clarification before broad changes."]
|
|
1117
|
-
: [],
|
|
1118
|
-
},
|
|
1119
|
-
};
|
|
1120
|
-
}
|
|
1121
|
-
|
|
1122
|
-
function formatHookTargetName(target: CodeAgentHookTarget): string {
|
|
1123
|
-
return target === "codex" ? "Codex" : "Claude";
|
|
1124
|
-
}
|
|
1125
|
-
|
|
1126
|
-
function classifyUserPrompt(value: unknown): {
|
|
1127
|
-
kind: string;
|
|
1128
|
-
riskTerms: string[];
|
|
1129
|
-
needsClarification: boolean;
|
|
1130
|
-
} {
|
|
1131
|
-
const text = typeof value === "string" ? value.toLowerCase() : "";
|
|
1132
|
-
const riskTerms = [
|
|
1133
|
-
"security",
|
|
1134
|
-
"release",
|
|
1135
|
-
"publish",
|
|
1136
|
-
"hook",
|
|
1137
|
-
"memory",
|
|
1138
|
-
"learning",
|
|
1139
|
-
"secret",
|
|
1140
|
-
"privacy",
|
|
1141
|
-
].filter((term) => text.includes(term));
|
|
1142
|
-
let kind = "feature";
|
|
1143
|
-
if (/\bbug|fix|error|failed|failure\b/.test(text)) kind = "bugfix";
|
|
1144
|
-
if (/\brefactor|migration|migrate\b/.test(text)) kind = "refactor";
|
|
1145
|
-
if (/\breview|audit\b/.test(text)) kind = "review";
|
|
1146
|
-
if (/\btest|coverage\b/.test(text)) kind = "test";
|
|
1147
|
-
if (/\bdoc|readme|guide\b/.test(text)) kind = "docs";
|
|
1148
|
-
if (riskTerms.includes("security") || riskTerms.includes("privacy")) kind = "security";
|
|
1149
|
-
if (riskTerms.includes("release") || riskTerms.includes("publish")) kind = "release";
|
|
1150
|
-
return {
|
|
1151
|
-
kind,
|
|
1152
|
-
riskTerms,
|
|
1153
|
-
needsClarification: text.trim().length < 12 || /\bmaybe|unclear|not sure\b/.test(text),
|
|
1154
|
-
};
|
|
1155
|
-
}
|
|
1156
|
-
|
|
1157
|
-
async function readActiveContract(
|
|
1158
|
-
homeDir: string,
|
|
1159
|
-
payload: Record<string, unknown>,
|
|
1160
|
-
): Promise<TaskContract | null> {
|
|
1161
|
-
const binding = await readSessionBinding(homeDir, payload);
|
|
1162
|
-
if (binding?.contractPath === null || binding?.contractPath === undefined) return null;
|
|
1163
|
-
try {
|
|
1164
|
-
return JSON.parse(await readFile(binding.contractPath, "utf8")) as TaskContract;
|
|
1165
|
-
} catch (error) {
|
|
1166
|
-
if (isNotFoundError(error)) return null;
|
|
1167
|
-
throw error;
|
|
1168
|
-
}
|
|
1169
|
-
}
|
|
1170
|
-
|
|
1171
1108
|
async function readSessionBinding(
|
|
1172
1109
|
homeDir: string,
|
|
1173
1110
|
payload: Record<string, unknown>,
|
|
@@ -1202,10 +1139,6 @@ function safeDiagnosticId(value: string): string {
|
|
|
1202
1139
|
return value.replace(/[^A-Za-z0-9._-]/g, "-").slice(0, 120) || "unknown";
|
|
1203
1140
|
}
|
|
1204
1141
|
|
|
1205
|
-
function optionalPayloadNumber(value: unknown): number | null {
|
|
1206
|
-
return typeof value === "number" && Number.isFinite(value) ? value : null;
|
|
1207
|
-
}
|
|
1208
|
-
|
|
1209
1142
|
function isNotFoundError(error: unknown): boolean {
|
|
1210
1143
|
return (
|
|
1211
1144
|
error instanceof Error && "code" in error && (error as NodeJS.ErrnoException).code === "ENOENT"
|
package/src/index.ts
CHANGED
|
@@ -18,11 +18,10 @@ export * from "./hooks/index.ts";
|
|
|
18
18
|
export * from "./observability/index.ts";
|
|
19
19
|
export * from "./pack/index.ts";
|
|
20
20
|
export * from "./plugins/index.ts";
|
|
21
|
-
export * from "./project/index.ts";
|
|
22
21
|
export * from "./protected-zones/index.ts";
|
|
22
|
+
export * from "./projects/index.ts";
|
|
23
23
|
export * from "./runtime-logs/index.ts";
|
|
24
24
|
export * from "./sync/index.ts";
|
|
25
|
-
export * from "./task/index.ts";
|
|
26
25
|
export * from "./team/index.ts";
|
|
27
26
|
export * from "./team/mcp.ts";
|
|
28
27
|
export * from "./workflow/index.ts";
|