@akagilnc/pi-workflow-roles 0.1.5079 → 0.1.5096
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/acp-host/production-host.js +348 -301
- package/dist/atomic-write.js +13 -19
- package/dist/auditor-soul.js +2 -1
- package/dist/doctor-contracts.js +1 -1
- package/dist/gatekeeper-role.js +2 -16
- package/dist/headless-host/production-host.js +380 -333
- package/dist/merger-contracts.js +1 -1
- package/dist/migrate-book-topology.js +18 -14
- package/dist/navigator-attendance.js +28 -143
- package/dist/navigator-invocation-identity.js +2 -0
- package/dist/navigator-public-session.js +13 -1
- package/dist/navigator-work-base.js +113 -0
- package/dist/notary-contracts.js +0 -2
- package/dist/package-contracts/fixer-output.js +1 -1
- package/dist/package-contracts/gatekeeper-output.js +1 -1
- package/dist/package-contracts/navigator-output.js +1 -1
- package/dist/package-contracts/terminating-infrastructure.js +3 -3
- package/dist/packaged-role-registry.js +9 -5
- package/dist/public-cli/countersign-run.js +1 -1
- package/dist/public-cli/invocation.js +6 -3
- package/dist/public-cli/main.js +46 -22
- package/dist/public-cli/settlement.js +20 -1
- package/dist/receipt-delivery-policy.js +9 -2
- package/dist/review-submission.js +3 -3
- package/docs/adr/0057-schema-narrowing-cuts-the-required-set-not-the-declared-set.md +9 -0
- package/extensions/role-runtime.ts +0 -27
- package/package.json +2 -1
- package/resources/836-deleted-machine-instruction-inventory.md +3 -3
- package/resources/collector-bot-handbook.md +4 -0
- package/resources/navigator-route-playbook.md +4 -6
- package/scripts/build-package.mjs +4 -0
- package/souls/coder-output-guide.md +1 -0
- package/src/auditor-soul.ts +2 -1
- package/src/collector-role.ts +6 -7
- package/src/collector-tool-schemas.ts +5 -5
- package/src/diarist-role.ts +2 -2
- package/src/doctor-contracts.ts +1 -1
- package/src/gatekeeper-role.ts +1 -18
- package/src/gleaner-left-role.ts +2 -2
- package/src/inspector-role.ts +1 -1
- package/src/judge-role.ts +1 -1
- package/src/merger-contracts.ts +1 -1
- package/src/navigator-attendance.ts +38 -164
- package/src/navigator-invocation-identity.ts +2 -0
- package/src/navigator-public-session.ts +17 -1
- package/src/navigator-role.ts +4 -0
- package/src/navigator-session-contracts.ts +2 -0
- package/src/navigator-work-base.ts +123 -0
- package/src/notary-contracts.ts +0 -4
- package/src/package-contracts/fixer-output.ts +1 -1
- package/src/package-contracts/gatekeeper-output.ts +3 -3
- package/src/package-contracts/navigator-output.ts +1 -1
- package/src/package-contracts/terminating-infrastructure.ts +3 -6
- package/src/packaged-role-registry.ts +5 -1
- package/src/public-cli/countersign-run.ts +1 -1
- package/src/public-cli/invocation.ts +6 -3
- package/src/public-cli/settlement.ts +21 -0
- package/src/receipt-delivery-policy.ts +9 -1
- package/src/review-submission.ts +3 -3
- package/src/reviewer-role.ts +3 -3
- package/src/role-runtime-dependencies.ts +1 -5
- package/src/role-runtime.ts +52 -38
- package/src/secretariat-role.ts +3 -3
- package/src/worker-role.ts +3 -3
package/dist/merger-contracts.js
CHANGED
|
@@ -13,7 +13,7 @@ const mergerInputSchema = Type.Object({
|
|
|
13
13
|
resolutionScope: Type.Array(Type.String(), { description: "\u6750\u6599\uFF1A\u89E3\u6790\u8303\u56F4\u63D0\u793A\uFF1B\u53EF\u7A7A" }),
|
|
14
14
|
authorizedChecks: Type.Array(checkSchema)
|
|
15
15
|
}, { additionalProperties: false });
|
|
16
|
-
const MERGER_STATUS_DESCRIPTION = "completed | escalate
|
|
16
|
+
const MERGER_STATUS_DESCRIPTION = "completed | escalate";
|
|
17
17
|
const mergerOutputVariants = Type.Union([
|
|
18
18
|
Type.Object({ status: Type.Unknown({ description: MERGER_STATUS_DESCRIPTION }), attemptId: Type.String({ description: "\u5DF2\u53D7\u7406\u5408\u5E76 attempt \u8EAB\u4EFD" }), report: Type.String({ description: "\u5982\u5B9E\u7ED3\u679C\u62A5\u544A" }), mergeCommitId: Type.String({ description: "\u5B8C\u6210\u5408\u5E76 commit object ID" }) }, { additionalProperties: false }),
|
|
19
19
|
Type.Object({ status: Type.Unknown({ description: MERGER_STATUS_DESCRIPTION }), attemptId: Type.String({ description: "\u5DF2\u53D7\u7406\u5408\u5E76 attempt \u8EAB\u4EFD" }), diagnosis: Type.String({ description: "\u5408\u5E76\u65E0\u6CD5\u6216\u4E0D\u5E94\u7531\u672C\u5E2D\u5B8C\u6210\u7684\u539F\u56E0\uFF08\u542B\u65E0\u8FDB\u884C\u4E2D\u5408\u5E76\u3001\u65E0\u6D3B\u53EF\u5E72\u3001\u9700\u65B0\u7684\u4EA7\u54C1/\u6743\u529B\u51B3\u5B9A\uFF09" }), report: Type.String({ description: "\u5982\u5B9E\u7ED3\u679C\u62A5\u544A" }) }, { additionalProperties: false })
|
|
@@ -8199,7 +8199,7 @@ function withTerminatingOutputDeclarations(schema) {
|
|
|
8199
8199
|
...baseProperties ?? {},
|
|
8200
8200
|
...baseProperties?.ticketNumber === void 0 ? {
|
|
8201
8201
|
ticketNumber: typebox_exports.Unknown({
|
|
8202
|
-
description: "\u53EF\u9009\u672C\u7968\u53F7\
|
|
8202
|
+
description: "\u53EF\u9009\u672C\u7968\u53F7\u3002\u5C1A\u672A\u7ED1\u5B9A\u65F6\u7531\u89D2\u8272\u5728\u65E2\u6709\u56DE\u6267\u4E2D\u7533\u62A5\u3002"
|
|
8203
8203
|
})
|
|
8204
8204
|
} : {},
|
|
8205
8205
|
[INFRASTRUCTURE_FAILURE_DECLARATION_KEY]: infrastructureFailureDeclarationSchema.properties[INFRASTRUCTURE_FAILURE_DECLARATION_KEY]
|
|
@@ -8220,12 +8220,12 @@ var init_terminating_infrastructure = __esm({
|
|
|
8220
8220
|
infrastructureFailureNested = typebox_exports.Object(
|
|
8221
8221
|
{
|
|
8222
8222
|
[INFRASTRUCTURE_FAILURE_DIAGNOSTIC_KEY]: typebox_exports.Unknown({
|
|
8223
|
-
description: "\
|
|
8223
|
+
description: "\u57FA\u7840\u8BBE\u65BD\u5931\u8D25\u8BCA\u65AD\u5B57\u7B26\u4E32\u3002"
|
|
8224
8224
|
})
|
|
8225
8225
|
},
|
|
8226
8226
|
{
|
|
8227
8227
|
additionalProperties: true,
|
|
8228
|
-
description: "\u57FA\u7840\u8BBE\u65BD\u771F\u5B9E\u5931\u8D25\
|
|
8228
|
+
description: "\u4EC5\u57FA\u7840\u8BBE\u65BD\u771F\u5B9E\u5931\u8D25\u65F6\u51FA\u73B0\u3002"
|
|
8229
8229
|
}
|
|
8230
8230
|
);
|
|
8231
8231
|
infrastructureFailureNested.required = [];
|
|
@@ -8250,7 +8250,7 @@ var init_gatekeeper_output = __esm({
|
|
|
8250
8250
|
gatekeeperDecisionSchema = openToolObject(
|
|
8251
8251
|
typebox_exports.Object({
|
|
8252
8252
|
status: typebox_exports.Unknown({
|
|
8253
|
-
description: "dispatch | pass
|
|
8253
|
+
description: "dispatch | pass"
|
|
8254
8254
|
}),
|
|
8255
8255
|
officer: typebox_exports.Unknown({
|
|
8256
8256
|
description: "status \u4E3A dispatch \u65F6\u4E3A inspector | notary"
|
|
@@ -8279,7 +8279,7 @@ var init_navigator_output = __esm({
|
|
|
8279
8279
|
openToolObject(
|
|
8280
8280
|
typebox_exports.Object({
|
|
8281
8281
|
prose: typebox_exports.Unknown({
|
|
8282
|
-
description: "\u6E38\u5955\u4F7F\u6563\u6587\u5EFA\u8BAE\uFF0C\u539F\u6837\u5448\u73B0\u3002\u4E0D\u8981\u6C42 candidates/next \u7B49\u7ED3\u6784\u5316\u5B57\u6BB5\u3002
|
|
8282
|
+
description: "\u6E38\u5955\u4F7F\u6563\u6587\u5EFA\u8BAE\uFF0C\u539F\u6837\u5448\u73B0\u3002\u4E0D\u8981\u6C42 candidates/next \u7B49\u7ED3\u6784\u5316\u5B57\u6BB5\u3002"
|
|
8283
8283
|
})
|
|
8284
8284
|
})
|
|
8285
8285
|
)
|
|
@@ -8306,7 +8306,7 @@ var init_review_submission = __esm({
|
|
|
8306
8306
|
typebox_exports.Literal(REVIEW_QUEUE_WORDS[2])
|
|
8307
8307
|
],
|
|
8308
8308
|
{
|
|
8309
|
-
description: "\u5BA1\u6838\
|
|
8309
|
+
description: "\u5BA1\u6838\u5E2D\u672C\u8F6E\u88C1\u51B3\u7684\u5224\u522B\u72B6\u6001\u3002"
|
|
8310
8310
|
}
|
|
8311
8311
|
),
|
|
8312
8312
|
findings: typebox_exports.Optional(typebox_exports.Unknown({ description: "\u5BA1\u6838\u53D1\u73B0\uFF0C\u539F\u6837\u7559\u5B58" })),
|
|
@@ -8376,7 +8376,7 @@ var init_fixer_output = __esm({
|
|
|
8376
8376
|
});
|
|
8377
8377
|
classResultSchema = typebox_exports.Union([completedClassResultSchema, refusedClassResultSchema]);
|
|
8378
8378
|
completedClassResultsSchema = typebox_exports.Array(completedClassResultSchema);
|
|
8379
|
-
FIXER_STATUS_DESCRIPTION = "planned | completed | refused | unfinished | partially_completed
|
|
8379
|
+
FIXER_STATUS_DESCRIPTION = "planned | completed | refused | unfinished | partially_completed\u3002unfinished \u7F3A\u524D\u7F6E\u6216\u8FDD\u5BAA\u7EA6\u675F\u81F4\u672C\u5C40\u672A\u5B8C\u6210\u65F6\u53EF\u7528\uFF0C\u7F3A\u5F85\u51B3 owner \u51B3\u5B9A\u6216\u7B54\u590D\u5C5E\u7F3A\u524D\u7F6E\u3002";
|
|
8380
8380
|
fixerOutputVariants = typebox_exports.Union([
|
|
8381
8381
|
typebox_exports.Object({ status: typebox_exports.Unknown({ description: FIXER_STATUS_DESCRIPTION }), report: typebox_exports.String({ description: "\u5982\u5B9E\u7ED3\u679C\u62A5\u544A" }) }),
|
|
8382
8382
|
typebox_exports.Object({ status: typebox_exports.Unknown({ description: FIXER_STATUS_DESCRIPTION }), report: typebox_exports.String({ description: "\u5982\u5B9E\u7ED3\u679C\u62A5\u544A" }), remainingScope: typebox_exports.String({ description: "\u4F9D\u6CD5\u4E0D\u80FD\u5B8C\u6210\u7684\u5DE5\u4F5C\u8303\u56F4" }), blocker: typebox_exports.Unsafe({ ...blockerSchema, description: "\u5408\u6CD5\u963B\u65AD\u5B8C\u6210\u7684 blocker" }) }),
|
|
@@ -13836,7 +13836,7 @@ var init_doctor_contracts = __esm({
|
|
|
13836
13836
|
typebox_exports.Object({ targetKey: nonblank, targetKind: typebox_exports.Optional(typebox_exports.Union(assetKinds.map((kind) => typebox_exports.Literal(kind)))), assetEvidence: typebox_exports.Optional(typebox_exports.Object({ targetKey: nonblank, targetKind: typebox_exports.Optional(typebox_exports.Union(assetKinds.map((kind) => typebox_exports.Literal(kind)))), evidenceId: nonblank }, { additionalProperties: true })), ...findingBody }, { additionalProperties: true })
|
|
13837
13837
|
]);
|
|
13838
13838
|
caseIdentity = typebox_exports.Object({ issueNumber: typebox_exports.Optional(typebox_exports.Integer()), runsPath: nonblank }, { additionalProperties: true });
|
|
13839
|
-
DOCTOR_STATUS_DESCRIPTION = "completed | refused
|
|
13839
|
+
DOCTOR_STATUS_DESCRIPTION = "completed | refused\u3002completed \u5141\u8BB8\u7A7A findings\uFF1Brefused \u4EC5\u5F53\u8BC1\u636E\u4E0D\u8DB3\u4EE5\u652F\u6491\u5982\u5B9E\u6848\u8BC1\u8BCD";
|
|
13840
13840
|
doctorSubmissionVariants = typebox_exports.Union([
|
|
13841
13841
|
typebox_exports.Object({
|
|
13842
13842
|
status: typebox_exports.Unknown({ description: DOCTOR_STATUS_DESCRIPTION }),
|
|
@@ -13885,7 +13885,7 @@ var init_merger_contracts = __esm({
|
|
|
13885
13885
|
resolutionScope: typebox_exports.Array(typebox_exports.String(), { description: "\u6750\u6599\uFF1A\u89E3\u6790\u8303\u56F4\u63D0\u793A\uFF1B\u53EF\u7A7A" }),
|
|
13886
13886
|
authorizedChecks: typebox_exports.Array(checkSchema)
|
|
13887
13887
|
}, { additionalProperties: false });
|
|
13888
|
-
MERGER_STATUS_DESCRIPTION = "completed | escalate
|
|
13888
|
+
MERGER_STATUS_DESCRIPTION = "completed | escalate";
|
|
13889
13889
|
mergerOutputVariants = typebox_exports.Union([
|
|
13890
13890
|
typebox_exports.Object({ status: typebox_exports.Unknown({ description: MERGER_STATUS_DESCRIPTION }), attemptId: typebox_exports.String({ description: "\u5DF2\u53D7\u7406\u5408\u5E76 attempt \u8EAB\u4EFD" }), report: typebox_exports.String({ description: "\u5982\u5B9E\u7ED3\u679C\u62A5\u544A" }), mergeCommitId: typebox_exports.String({ description: "\u5B8C\u6210\u5408\u5E76 commit object ID" }) }, { additionalProperties: false }),
|
|
13891
13891
|
typebox_exports.Object({ status: typebox_exports.Unknown({ description: MERGER_STATUS_DESCRIPTION }), attemptId: typebox_exports.String({ description: "\u5DF2\u53D7\u7406\u5408\u5E76 attempt \u8EAB\u4EFD" }), diagnosis: typebox_exports.String({ description: "\u5408\u5E76\u65E0\u6CD5\u6216\u4E0D\u5E94\u7531\u672C\u5E2D\u5B8C\u6210\u7684\u539F\u56E0\uFF08\u542B\u65E0\u8FDB\u884C\u4E2D\u5408\u5E76\u3001\u65E0\u6D3B\u53EF\u5E72\u3001\u9700\u65B0\u7684\u4EA7\u54C1/\u6743\u529B\u51B3\u5B9A\uFF09" }), report: typebox_exports.String({ description: "\u5982\u5B9E\u7ED3\u679C\u62A5\u544A" }) }, { additionalProperties: false })
|
|
@@ -13996,21 +13996,24 @@ var init_packaged_role_registry = __esm({
|
|
|
13996
13996
|
"souls/notary.md",
|
|
13997
13997
|
"souls/audit-law.md",
|
|
13998
13998
|
"souls/ticket-law.md",
|
|
13999
|
-
"souls/gate-output-guide.md"
|
|
13999
|
+
"souls/gate-output-guide.md",
|
|
14000
|
+
"docs/adr/0057-schema-narrowing-cuts-the-required-set-not-the-declared-set.md"
|
|
14000
14001
|
];
|
|
14001
14002
|
INSPECTOR_SESSION_MATERIALS = [
|
|
14002
14003
|
"CLAUDE.md",
|
|
14003
14004
|
"souls/inspector.md",
|
|
14004
14005
|
"souls/audit-law.md",
|
|
14005
14006
|
"souls/quality-law.md",
|
|
14006
|
-
"souls/gate-output-guide.md"
|
|
14007
|
+
"souls/gate-output-guide.md",
|
|
14008
|
+
"docs/adr/0057-schema-narrowing-cuts-the-required-set-not-the-declared-set.md"
|
|
14007
14009
|
];
|
|
14008
14010
|
AUDITOR_PUBLIC_SESSION_MATERIALS = [
|
|
14009
14011
|
"CLAUDE.md",
|
|
14010
14012
|
"souls/judge-auditor.md",
|
|
14011
14013
|
"souls/doctor-auditor.md",
|
|
14012
14014
|
"souls/audit-law.md",
|
|
14013
|
-
"souls/quality-law.md"
|
|
14015
|
+
"souls/quality-law.md",
|
|
14016
|
+
"docs/adr/0057-schema-narrowing-cuts-the-required-set-not-the-declared-set.md"
|
|
14014
14017
|
];
|
|
14015
14018
|
PUBLIC_ROLE_RECORDS = [
|
|
14016
14019
|
{
|
|
@@ -14038,7 +14041,8 @@ var init_packaged_role_registry = __esm({
|
|
|
14038
14041
|
"souls/judge.md",
|
|
14039
14042
|
"souls/audit-law.md",
|
|
14040
14043
|
"souls/quality-law.md",
|
|
14041
|
-
"souls/judge-output-guide.md"
|
|
14044
|
+
"souls/judge-output-guide.md",
|
|
14045
|
+
"docs/adr/0057-schema-narrowing-cuts-the-required-set-not-the-declared-set.md"
|
|
14042
14046
|
]
|
|
14043
14047
|
},
|
|
14044
14048
|
{
|
|
@@ -14316,7 +14320,7 @@ var init_packaged_role_registry = __esm({
|
|
|
14316
14320
|
activationStage: "load-and-install",
|
|
14317
14321
|
receiptStatusKey: "status",
|
|
14318
14322
|
// #924: 公用《票面法》三席同装
|
|
14319
|
-
sessionMaterials: ["CLAUDE.md", "souls/countersign.md", "souls/ticket-law.md", "resources/countersign-ticket-issue.md"]
|
|
14323
|
+
sessionMaterials: ["CLAUDE.md", "souls/countersign.md", "souls/ticket-law.md", "resources/countersign-ticket-issue.md", "docs/adr/0057-schema-narrowing-cuts-the-required-set-not-the-declared-set.md"]
|
|
14320
14324
|
},
|
|
14321
14325
|
{
|
|
14322
14326
|
role: "secretariat",
|
|
@@ -6,6 +6,7 @@ import {} from "@earendil-works/pi-coding-agent";
|
|
|
6
6
|
import { Type } from "typebox";
|
|
7
7
|
import {
|
|
8
8
|
NAVIGATOR_INVOCATION_ENTRY,
|
|
9
|
+
NAVIGATOR_ROUTE_PLAYBOOK_FAILURE_ENTRY,
|
|
9
10
|
mintNavigatorInvocationId
|
|
10
11
|
} from "./navigator-invocation-identity.js";
|
|
11
12
|
import { PACKAGED_ROLE_REGISTRY } from "./packaged-role-registry.js";
|
|
@@ -31,10 +32,10 @@ import {
|
|
|
31
32
|
} from "./navigator-session-contracts.js";
|
|
32
33
|
import { sitianReport } from "./sitian-facade.js";
|
|
33
34
|
import { issueRoot, subjectPath } from "./work-subject-identity.js";
|
|
34
|
-
import { createReceiptDeliveryPolicy, NO_RECEIPT_LIFECYCLE_ENTRY_TYPE
|
|
35
|
+
import { createReceiptDeliveryPolicy, NO_RECEIPT_LIFECYCLE_ENTRY_TYPE } from "./receipt-delivery-policy.js";
|
|
35
36
|
import { navigatorProseFromUnknown } from "./package-contracts/navigator-output.js";
|
|
37
|
+
import { persistNavigatorWorkBase } from "./navigator-work-base.js";
|
|
36
38
|
const NAVIGATOR_EVENT_TYPE = "ak-navigator-attendance";
|
|
37
|
-
const NAVIGATOR_PREPARE_ACCEPTED_TEXT = "\u6E38\u5955\u4F7F\u51C6\u5907\u5DF2\u63A5\u53D7";
|
|
38
39
|
function resolveNavigatorAuthorityMaterial(roleInput, fileAuthority) {
|
|
39
40
|
if (roleInput !== void 0 && roleInput.trim() !== "") return roleInput;
|
|
40
41
|
if (fileAuthority !== void 0 && fileAuthority.trim() !== "") return fileAuthority;
|
|
@@ -43,10 +44,9 @@ function resolveNavigatorAuthorityMaterial(roleInput, fileAuthority) {
|
|
|
43
44
|
const NAVIGATOR_TARGETS = PACKAGED_ROLE_REGISTRY.map(({ role, phases }) => ({ role, phases }));
|
|
44
45
|
const prepareSchema = Type.Object({
|
|
45
46
|
prose: Type.Optional(Type.Unknown({
|
|
46
|
-
description: "\u6E38\u5955\u4F7F\u6563\u6587\u5EFA\u8BAE\uFF0C\u539F\u6837\u5448\u73B0\u3002\u4E0D\u8981\u6C42 candidates/next \u7ED3\u6784\u3002
|
|
47
|
+
description: "\u6E38\u5955\u4F7F\u6563\u6587\u5EFA\u8BAE\uFF0C\u539F\u6837\u5448\u73B0\u3002\u4E0D\u8981\u6C42 candidates/next \u7ED3\u6784\u3002"
|
|
47
48
|
}))
|
|
48
49
|
}, { additionalProperties: true });
|
|
49
|
-
const CONTEXT_ENTRY = "ak-navigator-context";
|
|
50
50
|
const INVOCATION_ENTRY = NAVIGATOR_INVOCATION_ENTRY;
|
|
51
51
|
const SETTLEMENT_ENTRY = "ak-navigator-settlement";
|
|
52
52
|
const unavailableKeys = /* @__PURE__ */ new Set(["context", "session", "model", "thinking", "auth", "quota", "transport", "unknown"]);
|
|
@@ -105,12 +105,12 @@ function createNavigatorPrepareTool(onOutput) {
|
|
|
105
105
|
parameters: prepareSchema,
|
|
106
106
|
async execute(_id, value) {
|
|
107
107
|
onOutput(value);
|
|
108
|
-
return { content: [
|
|
108
|
+
return { content: [], details: value, terminate: true };
|
|
109
109
|
}
|
|
110
110
|
};
|
|
111
111
|
}
|
|
112
112
|
function formatNavigatorReport(report) {
|
|
113
|
-
const playbookFailure = report.routePlaybookReadFailure === void 0 ? [] : [
|
|
113
|
+
const playbookFailure = report.routePlaybookReadFailure === void 0 ? [] : [report.routePlaybookReadFailure];
|
|
114
114
|
if (report.disposition === "no-advice") return playbookFailure.join("\n");
|
|
115
115
|
if (report.disposition === "unavailable") {
|
|
116
116
|
return [...playbookFailure, ...report.unavailableReason ? [report.unavailableReason] : []].join("\n");
|
|
@@ -136,28 +136,15 @@ function createNavigatorAttendance(options) {
|
|
|
136
136
|
let settlementTail = Promise.resolve();
|
|
137
137
|
let settlementFailure;
|
|
138
138
|
let preparationFailure;
|
|
139
|
-
let
|
|
139
|
+
let observedRoutePlaybookFailure;
|
|
140
140
|
let disposed = false;
|
|
141
141
|
let closing;
|
|
142
142
|
const nestCancel = new AbortController();
|
|
143
|
-
let warmedHelp;
|
|
144
143
|
const sessionHostContext = () => {
|
|
145
144
|
const parentSignal = options.context.signal;
|
|
146
145
|
const signal = parentSignal === void 0 ? nestCancel.signal : AbortSignal.any([nestCancel.signal, parentSignal]);
|
|
147
146
|
return { ...options.context, signal };
|
|
148
147
|
};
|
|
149
|
-
const loadLiveHelp = async () => {
|
|
150
|
-
try {
|
|
151
|
-
return await Promise.all(
|
|
152
|
-
NAVIGATOR_TARGETS.map(async ({ role }) => ({
|
|
153
|
-
role,
|
|
154
|
-
help: await options.loadRoleHelp(role)
|
|
155
|
-
}))
|
|
156
|
-
);
|
|
157
|
-
} catch (error) {
|
|
158
|
-
throw navigatorUnavailableError("transport", error);
|
|
159
|
-
}
|
|
160
|
-
};
|
|
161
148
|
const unavailable = (invocationId, reason) => {
|
|
162
149
|
const failure = reason instanceof NavigatorUnavailableError ? reason : navigatorUnavailableError("unknown", reason);
|
|
163
150
|
return {
|
|
@@ -167,7 +154,6 @@ function createNavigatorAttendance(options) {
|
|
|
167
154
|
unavailableCause: failure.unavailableCause
|
|
168
155
|
};
|
|
169
156
|
};
|
|
170
|
-
let routePlaybookSettlement;
|
|
171
157
|
let prepareBoundSettlement;
|
|
172
158
|
const loadMaterialsAndSession = async (invocationId) => {
|
|
173
159
|
if (contextError !== void 0) throw navigatorUnavailableError("context", contextError);
|
|
@@ -177,30 +163,6 @@ function createNavigatorAttendance(options) {
|
|
|
177
163
|
new Error("controlling authority content was not supplied as typed work context")
|
|
178
164
|
);
|
|
179
165
|
}
|
|
180
|
-
let soul;
|
|
181
|
-
let modelSetting;
|
|
182
|
-
let help;
|
|
183
|
-
let routePlaybook = "";
|
|
184
|
-
routePlaybookReadFailure = void 0;
|
|
185
|
-
const soulPromise = (async () => {
|
|
186
|
-
try {
|
|
187
|
-
const text = (await options.loadSoul()).trim();
|
|
188
|
-
if (!text) throw new Error("Navigator soul is empty");
|
|
189
|
-
return text;
|
|
190
|
-
} catch (error) {
|
|
191
|
-
throw navigatorUnavailableError("context", error);
|
|
192
|
-
}
|
|
193
|
-
})();
|
|
194
|
-
const routePlaybookPromise = (async () => {
|
|
195
|
-
if (options.loadRoutePlaybook === void 0) return "";
|
|
196
|
-
try {
|
|
197
|
-
return await options.loadRoutePlaybook();
|
|
198
|
-
} catch (error) {
|
|
199
|
-
routePlaybookReadFailure = error instanceof Error ? error.message : String(error);
|
|
200
|
-
return "";
|
|
201
|
-
}
|
|
202
|
-
})();
|
|
203
|
-
routePlaybookSettlement = routePlaybookPromise.then(() => void 0);
|
|
204
166
|
const modelPromise = (async () => {
|
|
205
167
|
try {
|
|
206
168
|
const resolved = await resolveNavigatorSeatSelection(options.context);
|
|
@@ -210,23 +172,13 @@ function createNavigatorAttendance(options) {
|
|
|
210
172
|
throw navigatorUnavailableError("model", error);
|
|
211
173
|
}
|
|
212
174
|
})();
|
|
213
|
-
const
|
|
214
|
-
warmedHelp = void 0;
|
|
215
|
-
[soul, routePlaybook, modelSetting, help] = await Promise.all([
|
|
216
|
-
soulPromise,
|
|
217
|
-
routePlaybookPromise,
|
|
218
|
-
modelPromise,
|
|
219
|
-
helpPromise
|
|
220
|
-
]);
|
|
175
|
+
const modelSetting = await modelPromise;
|
|
221
176
|
let model;
|
|
222
177
|
try {
|
|
223
178
|
model = parseNavigatorModelSetting(modelSetting);
|
|
224
179
|
} catch (error) {
|
|
225
180
|
throw navigatorUnavailableError("model", error);
|
|
226
181
|
}
|
|
227
|
-
const helpContext = help.map(({ role, help: text }) => `<role_help role="${role}">
|
|
228
|
-
${text}
|
|
229
|
-
</role_help>`).join("\n");
|
|
230
182
|
const tool = createNavigatorPrepareTool((value) => {
|
|
231
183
|
outputSink?.(value);
|
|
232
184
|
});
|
|
@@ -271,9 +223,9 @@ ${text}
|
|
|
271
223
|
}
|
|
272
224
|
if (disposed) throw navigatorUnavailableError("session", new Error("Navigator attendance was disposed"));
|
|
273
225
|
if (session === void 0) throw new Error("Navigator session was not created");
|
|
274
|
-
return
|
|
226
|
+
return session;
|
|
275
227
|
};
|
|
276
|
-
const prepare = async (
|
|
228
|
+
const prepare = async (existingSession) => {
|
|
277
229
|
const boundSettlement = prepareBoundSettlement;
|
|
278
230
|
prepareBoundSettlement = void 0;
|
|
279
231
|
const invocationId = invocationPrincipal;
|
|
@@ -290,73 +242,19 @@ ${text}
|
|
|
290
242
|
const merged = [prior, next].filter((part) => part.trim() !== "").join("\n\n");
|
|
291
243
|
output = { prose: merged };
|
|
292
244
|
};
|
|
293
|
-
const
|
|
294
|
-
|
|
295
|
-
const
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
...boundSettlement === void 0 ? {} : { currentSettlement: boundSettlement },
|
|
301
|
-
publicSettlementHistory,
|
|
302
|
-
liveRoleHelp: help
|
|
303
|
-
};
|
|
304
|
-
activeSession.appendEntry(CONTEXT_ENTRY, projection);
|
|
305
|
-
const request = boundSettlement === void 0 ? [
|
|
306
|
-
"\u672C\u8F6E\u4E3A\u5F85\u547D\u8F6E\u3002",
|
|
307
|
-
`<navigator_soul>
|
|
308
|
-
${soul}
|
|
309
|
-
</navigator_soul>`,
|
|
310
|
-
...routePlaybookReadFailure === void 0 ? [`<route_playbook>
|
|
311
|
-
${routePlaybook}
|
|
312
|
-
</route_playbook>`] : ["\u53EF\u9009\u8DEF\u7EBF\u624B\u518C\u672A\u80FD\u8BFB\u53D6\u3002"],
|
|
313
|
-
`<work_subject>
|
|
314
|
-
${subject}
|
|
315
|
-
</work_subject>`,
|
|
316
|
-
`<controlling_authority>
|
|
317
|
-
${authority}
|
|
318
|
-
</controlling_authority>`,
|
|
319
|
-
`<current_role>
|
|
320
|
-
${JSON.stringify({ role: options.role, phase: options.phase })}
|
|
321
|
-
</current_role>`,
|
|
322
|
-
`<public_settlement_history>
|
|
323
|
-
${JSON.stringify(projection.publicSettlementHistory)}
|
|
324
|
-
</public_settlement_history>`,
|
|
325
|
-
`<live_role_help>
|
|
326
|
-
${helpContext}
|
|
327
|
-
</live_role_help>`
|
|
328
|
-
].join("\n\n") : [
|
|
329
|
-
"\u672C\u8F6E\u4E3A\u7ED3\u7B97\u6295\u5582\u8F6E\u3002",
|
|
330
|
-
`<navigator_soul>
|
|
331
|
-
${soul}
|
|
332
|
-
</navigator_soul>`,
|
|
333
|
-
...routePlaybookReadFailure === void 0 ? [`<route_playbook>
|
|
334
|
-
${routePlaybook}
|
|
335
|
-
</route_playbook>`] : ["\u53EF\u9009\u8DEF\u7EBF\u624B\u518C\u672A\u80FD\u8BFB\u53D6\u3002"],
|
|
336
|
-
`<work_subject>
|
|
337
|
-
${subject}
|
|
338
|
-
</work_subject>`,
|
|
339
|
-
`<controlling_authority>
|
|
340
|
-
${authority}
|
|
341
|
-
</controlling_authority>`,
|
|
342
|
-
`<current_role>
|
|
343
|
-
${JSON.stringify({ role: options.role, phase: options.phase })}
|
|
344
|
-
</current_role>`,
|
|
345
|
-
`<current_settlement>
|
|
346
|
-
${JSON.stringify(boundSettlement)}
|
|
347
|
-
</current_settlement>`,
|
|
348
|
-
`<public_settlement_history>
|
|
349
|
-
${JSON.stringify(projection.publicSettlementHistory)}
|
|
350
|
-
</public_settlement_history>`,
|
|
351
|
-
`<live_role_help>
|
|
352
|
-
${helpContext}
|
|
353
|
-
</live_role_help>`
|
|
354
|
-
].join("\n\n");
|
|
245
|
+
const activeSession = existingSession ?? await loadMaterialsAndSession(invocationId);
|
|
246
|
+
if (boundSettlement === void 0) return void 0;
|
|
247
|
+
const request = JSON.stringify({
|
|
248
|
+
...boundSettlement,
|
|
249
|
+
invocationId,
|
|
250
|
+
subjectKey
|
|
251
|
+
});
|
|
355
252
|
try {
|
|
356
253
|
try {
|
|
357
254
|
if (disposed) throw navigatorUnavailableError("session", new Error("Navigator attendance was disposed"));
|
|
358
255
|
const delivery = createReceiptDeliveryPolicy();
|
|
359
256
|
const promptAllowingRejectedPrepare = async (text, deliveryRequest) => {
|
|
257
|
+
await persistNavigatorWorkBase(activeSession.recordPointer(), { subject, authority });
|
|
360
258
|
const entryStart = activeSession.entries().length;
|
|
361
259
|
prepareBatchRejected = false;
|
|
362
260
|
let promptFailure;
|
|
@@ -387,7 +285,7 @@ ${helpContext}
|
|
|
387
285
|
await promptAllowingRejectedPrepare(request, false);
|
|
388
286
|
if (boundSettlement !== void 0) {
|
|
389
287
|
while (output === void 0 && prepareBatchRejected && delivery.nextAction() === "request-delivery") {
|
|
390
|
-
await promptAllowingRejectedPrepare(
|
|
288
|
+
await promptAllowingRejectedPrepare(JSON.stringify(delivery.deliveryState()), true);
|
|
391
289
|
}
|
|
392
290
|
if (output === void 0 && delivery.nextAction() === "request-delivery") {
|
|
393
291
|
while (delivery.nextAction() === "request-delivery") {
|
|
@@ -427,6 +325,8 @@ ${helpContext}
|
|
|
427
325
|
preparedProse = normalizePrepareProse(output);
|
|
428
326
|
return preparedProse;
|
|
429
327
|
} finally {
|
|
328
|
+
const playbookFailure = activeSession.routePlaybookReadFailure?.();
|
|
329
|
+
observedRoutePlaybookFailure = typeof playbookFailure === "string" && playbookFailure.trim() !== "" ? playbookFailure : void 0;
|
|
430
330
|
outputSink = void 0;
|
|
431
331
|
}
|
|
432
332
|
};
|
|
@@ -444,16 +344,6 @@ ${helpContext}
|
|
|
444
344
|
contextError = next.contextError;
|
|
445
345
|
return closing2;
|
|
446
346
|
},
|
|
447
|
-
/**
|
|
448
|
-
* Start live-help subprocesses during activation without beginning full
|
|
449
|
-
* preparation. Next prepare() consumes the warm result; a later prepare
|
|
450
|
-
* reloads so live help edits remain visible.
|
|
451
|
-
*/
|
|
452
|
-
warmHelp() {
|
|
453
|
-
if (disposed || warmedHelp !== void 0 || preparation !== void 0) return;
|
|
454
|
-
warmedHelp = loadLiveHelp();
|
|
455
|
-
void warmedHelp.catch(() => void 0);
|
|
456
|
-
},
|
|
457
347
|
prepare() {
|
|
458
348
|
if (disposed || preparation !== void 0) return;
|
|
459
349
|
preparationFailure = void 0;
|
|
@@ -468,9 +358,6 @@ ${helpContext}
|
|
|
468
358
|
isPreparing() {
|
|
469
359
|
return preparationInFlight;
|
|
470
360
|
},
|
|
471
|
-
knownRoutePlaybookReadFailure() {
|
|
472
|
-
return routePlaybookReadFailure;
|
|
473
|
-
},
|
|
474
361
|
settle(settlement) {
|
|
475
362
|
const next = settlementTail.then(() => settleOnce(settlement));
|
|
476
363
|
settlementTail = next.catch((error) => {
|
|
@@ -497,6 +384,7 @@ ${helpContext}
|
|
|
497
384
|
};
|
|
498
385
|
async function settleOnce(settlement) {
|
|
499
386
|
if (disposed) return;
|
|
387
|
+
observedRoutePlaybookFailure = void 0;
|
|
500
388
|
const invocationId = activeInvocationId ?? invocationPrincipal;
|
|
501
389
|
let report;
|
|
502
390
|
if (sessionReady !== void 0) {
|
|
@@ -535,10 +423,10 @@ ${helpContext}
|
|
|
535
423
|
}
|
|
536
424
|
} else {
|
|
537
425
|
if (session !== void 0) preparationFailure = void 0;
|
|
538
|
-
let
|
|
426
|
+
let coldSession;
|
|
539
427
|
if (session === void 0 && preparationFailure === void 0) {
|
|
540
428
|
try {
|
|
541
|
-
|
|
429
|
+
coldSession = await loadMaterialsAndSession(invocationId);
|
|
542
430
|
} catch (error) {
|
|
543
431
|
preparationFailure = error;
|
|
544
432
|
}
|
|
@@ -546,7 +434,7 @@ ${helpContext}
|
|
|
546
434
|
session?.appendEntry(SETTLEMENT_ENTRY, settlementFact);
|
|
547
435
|
if (preparationFailure === void 0) {
|
|
548
436
|
prepareBoundSettlement = settlement;
|
|
549
|
-
preparation = prepare(
|
|
437
|
+
preparation = prepare(coldSession);
|
|
550
438
|
void preparation.catch((error) => {
|
|
551
439
|
preparationFailure = error;
|
|
552
440
|
});
|
|
@@ -565,9 +453,8 @@ ${helpContext}
|
|
|
565
453
|
report = { disposition: "no-advice" };
|
|
566
454
|
}
|
|
567
455
|
}
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
report = { ...report, routePlaybookReadFailure };
|
|
456
|
+
if (observedRoutePlaybookFailure !== void 0) {
|
|
457
|
+
report = { ...report, routePlaybookReadFailure: observedRoutePlaybookFailure };
|
|
571
458
|
}
|
|
572
459
|
const event = {
|
|
573
460
|
version: 1,
|
|
@@ -594,8 +481,6 @@ ${helpContext}
|
|
|
594
481
|
sessionReady = void 0;
|
|
595
482
|
preparedProse = void 0;
|
|
596
483
|
preparationFailure = void 0;
|
|
597
|
-
routePlaybookSettlement = void 0;
|
|
598
|
-
routePlaybookReadFailure = void 0;
|
|
599
484
|
}
|
|
600
485
|
}
|
|
601
486
|
function registerNavigatorModelCommand(pi, path = navigatorModelSettingPath()) {
|
|
@@ -608,8 +493,8 @@ function registerNavigatorModelCommand(pi, path = navigatorModelSettingPath()) {
|
|
|
608
493
|
}
|
|
609
494
|
export {
|
|
610
495
|
NAVIGATOR_EVENT_TYPE,
|
|
611
|
-
NAVIGATOR_PREPARE_ACCEPTED_TEXT,
|
|
612
496
|
NAVIGATOR_PREPARE_TOOL_NAME,
|
|
497
|
+
NAVIGATOR_ROUTE_PLAYBOOK_FAILURE_ENTRY,
|
|
613
498
|
NAVIGATOR_TARGETS,
|
|
614
499
|
NavigatorUnavailableError,
|
|
615
500
|
createNativeNavigatorSessionFactory,
|
|
@@ -2,6 +2,7 @@ import { LEGACY_REVIEW_OUTPUT_ROLES, PACKAGED_ROLE_REGISTRY } from "./packaged-r
|
|
|
2
2
|
import { isUuidV7, uuidv7 } from "./uuidv7.js";
|
|
3
3
|
import { workSubjectKeysEqual } from "./work-subject-identity.js";
|
|
4
4
|
const NAVIGATOR_INVOCATION_ENTRY = "ak-navigator-invocation";
|
|
5
|
+
const NAVIGATOR_ROUTE_PLAYBOOK_FAILURE_ENTRY = "ak-navigator-route-playbook-failure";
|
|
5
6
|
const NAVIGATOR_INFRASTRUCTURE_FAILURE_KIND = "role_infrastructure_failure";
|
|
6
7
|
const NAVIGATOR_INFRASTRUCTURE_FAILURE_KEYS = [
|
|
7
8
|
"kind",
|
|
@@ -221,6 +222,7 @@ export {
|
|
|
221
222
|
NAVIGATOR_INFRASTRUCTURE_FAILURE_EVIDENCE_KEYS,
|
|
222
223
|
NAVIGATOR_INFRASTRUCTURE_FAILURE_KIND,
|
|
223
224
|
NAVIGATOR_INVOCATION_ENTRY,
|
|
225
|
+
NAVIGATOR_ROUTE_PLAYBOOK_FAILURE_ENTRY,
|
|
224
226
|
bindCurrentDurableTerminalToMarker,
|
|
225
227
|
buildNavigatorInfrastructureFailureFact,
|
|
226
228
|
classifyPackagedRoleTerminalResult,
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { existsSync } from "node:fs";
|
|
1
2
|
import { basename } from "node:path";
|
|
2
3
|
import { sitianReport } from "./sitian-facade.js";
|
|
3
4
|
import {
|
|
@@ -10,6 +11,10 @@ import {
|
|
|
10
11
|
import { runDirectoryFromHostContext } from "./host-contracts.js";
|
|
11
12
|
import { CliUsageError } from "./public-cli/cli-errors.js";
|
|
12
13
|
import { isNavigatorSeat } from "./packaged-role-registry.js";
|
|
14
|
+
import {
|
|
15
|
+
attachWorkContextPointer,
|
|
16
|
+
navigatorWorkContextFile
|
|
17
|
+
} from "./navigator-work-base.js";
|
|
13
18
|
async function resolveNavigatorLedgerHome(context) {
|
|
14
19
|
const { tryHomeFromAkRolesPath } = await import("./activation-ledger-topology.js");
|
|
15
20
|
const runDirectory = runDirectoryFromHostContext(context);
|
|
@@ -73,6 +78,7 @@ function createNativeNavigatorSessionFactory(deps) {
|
|
|
73
78
|
});
|
|
74
79
|
let providerFailure;
|
|
75
80
|
let noReceipt;
|
|
81
|
+
let routePlaybookReadFailure;
|
|
76
82
|
let disposed = false;
|
|
77
83
|
let hostRunId = readNavigatorHostRunPointer(sessionManager.getEntries());
|
|
78
84
|
const summon = deps?.summonPublicRole ?? (async (options) => {
|
|
@@ -86,13 +92,16 @@ function createNativeNavigatorSessionFactory(deps) {
|
|
|
86
92
|
}
|
|
87
93
|
providerFailure = void 0;
|
|
88
94
|
noReceipt = void 0;
|
|
95
|
+
routePlaybookReadFailure = void 0;
|
|
89
96
|
try {
|
|
90
97
|
const summonHome = await resolveNavigatorLedgerHome(context);
|
|
91
98
|
if (disposed) return;
|
|
92
99
|
const resumeRunId = hostRunId;
|
|
100
|
+
const workContextPath = navigatorWorkContextFile(sessionManager.getSessionDir());
|
|
101
|
+
const argvText = existsSync(workContextPath) ? attachWorkContextPointer(text, workContextPath) : text;
|
|
93
102
|
const baseSummon = {
|
|
94
103
|
role: "navigator",
|
|
95
|
-
argv: [
|
|
104
|
+
argv: [argvText],
|
|
96
105
|
cwd: context.cwd,
|
|
97
106
|
...summonHome === void 0 ? {} : { home: summonHome },
|
|
98
107
|
...context.signal === void 0 ? {} : { signal: context.signal }
|
|
@@ -113,6 +122,8 @@ function createNativeNavigatorSessionFactory(deps) {
|
|
|
113
122
|
}
|
|
114
123
|
}
|
|
115
124
|
if (disposed) return;
|
|
125
|
+
const playbookFailure = summoned.terminal?.navigator?.advisoryDiagnostic;
|
|
126
|
+
routePlaybookReadFailure = typeof playbookFailure === "string" && playbookFailure.trim() !== "" ? playbookFailure : void 0;
|
|
116
127
|
const outcome = summoned.terminal?.roleOutcome;
|
|
117
128
|
if (outcome === void 0) {
|
|
118
129
|
const detail = summoned.stderr?.trim() || `exit ${summoned.exitCode}`;
|
|
@@ -171,6 +182,7 @@ function createNativeNavigatorSessionFactory(deps) {
|
|
|
171
182
|
},
|
|
172
183
|
providerFailure: () => providerFailure,
|
|
173
184
|
noReceipt: () => noReceipt,
|
|
185
|
+
routePlaybookReadFailure: () => routePlaybookReadFailure,
|
|
174
186
|
appendEntry: (customType, data) => {
|
|
175
187
|
sessionManager.appendCustomEntry(customType, data);
|
|
176
188
|
try {
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import { existsSync, realpathSync } from "node:fs";
|
|
2
|
+
import { readFile } from "node:fs/promises";
|
|
3
|
+
import { basename, dirname, join, resolve } from "node:path";
|
|
4
|
+
import { writeFileAtomically } from "./atomic-write.js";
|
|
5
|
+
const NAVIGATOR_WORK_CONTEXT_BASENAME = "work-context.json";
|
|
6
|
+
function navigatorWorkContextFile(sessionDir) {
|
|
7
|
+
return join(sessionDir, NAVIGATOR_WORK_CONTEXT_BASENAME);
|
|
8
|
+
}
|
|
9
|
+
function isNavigatorWorkContextFile(path) {
|
|
10
|
+
const resolved = resolve(path);
|
|
11
|
+
if (basename(resolved) !== NAVIGATOR_WORK_CONTEXT_BASENAME) return false;
|
|
12
|
+
const nest = dirname(resolved);
|
|
13
|
+
if (!/^[0-9a-f]{32}$/.test(basename(nest))) return false;
|
|
14
|
+
return basename(dirname(nest)) === "navigator";
|
|
15
|
+
}
|
|
16
|
+
function canonicalNavigatorWorkContextFile(path) {
|
|
17
|
+
if (!isNavigatorWorkContextFile(path)) return void 0;
|
|
18
|
+
try {
|
|
19
|
+
const real = realpathSync(path);
|
|
20
|
+
return isNavigatorWorkContextFile(real) ? real : void 0;
|
|
21
|
+
} catch {
|
|
22
|
+
return void 0;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
async function persistNavigatorWorkBase(sessionDir, body) {
|
|
26
|
+
if (sessionDir.trim() === "" || !existsSync(sessionDir)) return void 0;
|
|
27
|
+
if (body.authority.trim() === "") return void 0;
|
|
28
|
+
const path = navigatorWorkContextFile(sessionDir);
|
|
29
|
+
const next = `${JSON.stringify({ subject: body.subject, authority: body.authority })}
|
|
30
|
+
`;
|
|
31
|
+
try {
|
|
32
|
+
const current = await readFile(path, "utf8");
|
|
33
|
+
if (current === next) return path;
|
|
34
|
+
} catch (error) {
|
|
35
|
+
if (!(error instanceof Error && "code" in error && error.code === "ENOENT")) {
|
|
36
|
+
throw error;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
await writeFileAtomically(path, next);
|
|
40
|
+
return path;
|
|
41
|
+
}
|
|
42
|
+
async function readNavigatorWorkBase(path) {
|
|
43
|
+
const canonical = canonicalNavigatorWorkContextFile(path);
|
|
44
|
+
if (canonical === void 0) return void 0;
|
|
45
|
+
let text;
|
|
46
|
+
try {
|
|
47
|
+
text = await readFile(canonical, "utf8");
|
|
48
|
+
} catch (error) {
|
|
49
|
+
if (error instanceof Error && "code" in error && error.code === "ENOENT") {
|
|
50
|
+
return void 0;
|
|
51
|
+
}
|
|
52
|
+
throw error;
|
|
53
|
+
}
|
|
54
|
+
let parsed;
|
|
55
|
+
try {
|
|
56
|
+
parsed = JSON.parse(text);
|
|
57
|
+
} catch {
|
|
58
|
+
return void 0;
|
|
59
|
+
}
|
|
60
|
+
if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) return void 0;
|
|
61
|
+
const record = parsed;
|
|
62
|
+
if (typeof record.subject !== "string" || typeof record.authority !== "string") return void 0;
|
|
63
|
+
if (record.authority.trim() === "") return void 0;
|
|
64
|
+
return { subject: record.subject, authority: record.authority };
|
|
65
|
+
}
|
|
66
|
+
function jsonObjectFromPrompt(prompt) {
|
|
67
|
+
const head = prompt.trimStart().split("\n\n", 1)[0] ?? "";
|
|
68
|
+
if (!head.startsWith("{")) return void 0;
|
|
69
|
+
try {
|
|
70
|
+
const parsed = JSON.parse(head);
|
|
71
|
+
if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) return void 0;
|
|
72
|
+
return parsed;
|
|
73
|
+
} catch {
|
|
74
|
+
return void 0;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
function workContextPathFromPrompt(prompt) {
|
|
78
|
+
const record = jsonObjectFromPrompt(prompt);
|
|
79
|
+
const path = record?.workContextPath;
|
|
80
|
+
if (typeof path !== "string" || path.trim() === "") return void 0;
|
|
81
|
+
return isNavigatorWorkContextFile(path) ? path : void 0;
|
|
82
|
+
}
|
|
83
|
+
function attachWorkContextPointer(text, workContextPath) {
|
|
84
|
+
const record = jsonObjectFromPrompt(text);
|
|
85
|
+
if (record === void 0) return text;
|
|
86
|
+
if (typeof record.workContextPath === "string" && record.workContextPath.trim() !== "") return text;
|
|
87
|
+
const head = text.trimStart().split("\n\n", 1)[0] ?? "";
|
|
88
|
+
const rest = text.trimStart().slice(head.length);
|
|
89
|
+
return `${JSON.stringify({ ...record, workContextPath })}${rest}`;
|
|
90
|
+
}
|
|
91
|
+
async function loadNavigatorWorkBaseSuffix(prompt) {
|
|
92
|
+
const path = workContextPathFromPrompt(prompt);
|
|
93
|
+
if (path === void 0) return void 0;
|
|
94
|
+
const body = await readNavigatorWorkBase(path);
|
|
95
|
+
if (body === void 0) return void 0;
|
|
96
|
+
return `<work_subject>
|
|
97
|
+
${body.subject}
|
|
98
|
+
</work_subject>
|
|
99
|
+
|
|
100
|
+
<controlling_authority>
|
|
101
|
+
${body.authority}
|
|
102
|
+
</controlling_authority>`;
|
|
103
|
+
}
|
|
104
|
+
export {
|
|
105
|
+
NAVIGATOR_WORK_CONTEXT_BASENAME,
|
|
106
|
+
attachWorkContextPointer,
|
|
107
|
+
isNavigatorWorkContextFile,
|
|
108
|
+
loadNavigatorWorkBaseSuffix,
|
|
109
|
+
navigatorWorkContextFile,
|
|
110
|
+
persistNavigatorWorkBase,
|
|
111
|
+
readNavigatorWorkBase,
|
|
112
|
+
workContextPathFromPrompt
|
|
113
|
+
};
|