@xemahq/opencode-xema-plugin 0.1.5 → 0.1.8
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/logger.d.ts.map +1 -1
- package/dist/logger.js.map +1 -1
- package/package.json +6 -7
- package/plugin.mjs +83 -87
- package/dist/tools/xema-studio.d.ts +0 -28
- package/dist/tools/xema-studio.d.ts.map +0 -1
- package/dist/tools/xema-studio.js +0 -220
- package/dist/tools/xema-studio.js.map +0 -1
- package/src/context.ts +0 -154
- package/src/errors.ts +0 -24
- package/src/hooks/session-idle-autocommit.ts +0 -411
- package/src/hooks/system-prompt-overlay.ts +0 -99
- package/src/hooks/workspace-listing.ts +0 -175
- package/src/index.ts +0 -163
- package/src/logger.ts +0 -40
- package/src/opencode-types.ts +0 -107
- package/src/plugin-entry.ts +0 -22
- package/src/session-state.ts +0 -92
- package/src/tools/runtime.ts +0 -7
- package/src/tools/service-token.ts +0 -68
- package/src/tools/shared.ts +0 -16
- package/src/tools/xema-memory.ts +0 -232
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import { z } from 'zod';
|
|
2
|
-
export declare enum StudioKind {
|
|
3
|
-
Workflow = "workflow",
|
|
4
|
-
Spec = "spec"
|
|
5
|
-
}
|
|
6
|
-
export declare function buildXemaStudioFetchSchemaTool(workspaceDir: string): import("../opencode-types.js").ToolDefinition<{
|
|
7
|
-
kind: z.ZodEnum<{
|
|
8
|
-
workflow: StudioKind.Workflow;
|
|
9
|
-
spec: StudioKind.Spec;
|
|
10
|
-
}>;
|
|
11
|
-
}>;
|
|
12
|
-
export declare function buildXemaStudioValidateTool(workspaceDir: string): import("../opencode-types.js").ToolDefinition<{
|
|
13
|
-
kind: z.ZodEnum<{
|
|
14
|
-
workflow: StudioKind.Workflow;
|
|
15
|
-
spec: StudioKind.Spec;
|
|
16
|
-
}>;
|
|
17
|
-
rawYaml: z.ZodString;
|
|
18
|
-
isReusable: z.ZodOptional<z.ZodBoolean>;
|
|
19
|
-
}>;
|
|
20
|
-
export declare function buildXemaStudioListExistingArtifactsTool(workspaceDir: string): import("../opencode-types.js").ToolDefinition<{
|
|
21
|
-
kind: z.ZodEnum<{
|
|
22
|
-
workflow: StudioKind.Workflow;
|
|
23
|
-
spec: StudioKind.Spec;
|
|
24
|
-
}>;
|
|
25
|
-
search: z.ZodOptional<z.ZodString>;
|
|
26
|
-
limit: z.ZodDefault<z.ZodNumber>;
|
|
27
|
-
}>;
|
|
28
|
-
//# sourceMappingURL=xema-studio.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"xema-studio.d.ts","sourceRoot":"","sources":["../../src/tools/xema-studio.ts"],"names":[],"mappings":"AAsBA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAaxB,oBAAY,UAAU;IACpB,QAAQ,aAAa;IACrB,IAAI,SAAS;CACd;AA4HD,wBAAgB,8BAA8B,CAAC,YAAY,EAAE,MAAM;;;;;GAoBlE;AAyBD,wBAAgB,2BAA2B,CAAC,YAAY,EAAE,MAAM;;;;;;;GAmC/D;AAyDD,wBAAgB,wCAAwC,CAAC,YAAY,EAAE,MAAM;;;;;;;GAqC5E"}
|
|
@@ -1,220 +0,0 @@
|
|
|
1
|
-
import { z } from 'zod';
|
|
2
|
-
import { tool } from '../opencode-types.js';
|
|
3
|
-
import { loadSessionStateForTool } from './runtime.js';
|
|
4
|
-
import { serviceTokenAuthorizationHeader } from './service-token.js';
|
|
5
|
-
import { toJsonString } from './shared.js';
|
|
6
|
-
export var StudioKind;
|
|
7
|
-
(function (StudioKind) {
|
|
8
|
-
StudioKind["Workflow"] = "workflow";
|
|
9
|
-
StudioKind["Spec"] = "spec";
|
|
10
|
-
})(StudioKind || (StudioKind = {}));
|
|
11
|
-
const STUDIO_KINDS = [StudioKind.Workflow, StudioKind.Spec];
|
|
12
|
-
function trimSlash(value) {
|
|
13
|
-
return value.replace(/\/+$/, '');
|
|
14
|
-
}
|
|
15
|
-
function readEnv(name) {
|
|
16
|
-
const v = process.env[name]?.trim();
|
|
17
|
-
if (!v) {
|
|
18
|
-
throw new Error(`${name} is not configured on this worker. The operator must set it ` +
|
|
19
|
-
'for xema_studio_* tools to work.');
|
|
20
|
-
}
|
|
21
|
-
return v;
|
|
22
|
-
}
|
|
23
|
-
function resolveStudioApiCtx(workspaceDir, toolName) {
|
|
24
|
-
const state = loadSessionStateForTool(workspaceDir, toolName);
|
|
25
|
-
const project = state.ctx.project;
|
|
26
|
-
if (!project || !project.projectId) {
|
|
27
|
-
throw new Error('xema_studio_* tools require a projectId in context.json; this session ' +
|
|
28
|
-
'is not bound to a project (orgId-only).');
|
|
29
|
-
}
|
|
30
|
-
return {
|
|
31
|
-
workflowEngineUrl: trimSlash(readEnv('WORKFLOW_ENGINE_API_URL')),
|
|
32
|
-
deliverableSpecsUrl: trimSlash(readEnv('DELIVERABLE_SPECS_API_URL')),
|
|
33
|
-
orgId: project.orgId,
|
|
34
|
-
projectId: project.projectId,
|
|
35
|
-
actorId: `xema:${state.ctx.invocation.role}`,
|
|
36
|
-
};
|
|
37
|
-
}
|
|
38
|
-
function studioHeaders(ctx) {
|
|
39
|
-
return {
|
|
40
|
-
'Content-Type': 'application/json',
|
|
41
|
-
Authorization: serviceTokenAuthorizationHeader(),
|
|
42
|
-
'x-org-id': ctx.orgId,
|
|
43
|
-
'x-project-id': ctx.projectId,
|
|
44
|
-
'x-actor-type': 'agent',
|
|
45
|
-
'x-actor-id': ctx.actorId,
|
|
46
|
-
};
|
|
47
|
-
}
|
|
48
|
-
function routesFor(kind, ctx) {
|
|
49
|
-
switch (kind) {
|
|
50
|
-
case StudioKind.Workflow:
|
|
51
|
-
return {
|
|
52
|
-
schema: `${ctx.workflowEngineUrl}/schemas/workflow/v1alpha1/Workflow.json`,
|
|
53
|
-
validate: `${ctx.workflowEngineUrl}/compiler/preview-raw`,
|
|
54
|
-
list: `${ctx.workflowEngineUrl}/workflows`,
|
|
55
|
-
};
|
|
56
|
-
case StudioKind.Spec:
|
|
57
|
-
return {
|
|
58
|
-
schema: `${ctx.deliverableSpecsUrl}/schemas/deliverable/v1/DeliverableSpec.json`,
|
|
59
|
-
validate: `${ctx.deliverableSpecsUrl}/deliverable-specs/preview-content`,
|
|
60
|
-
list: `${ctx.deliverableSpecsUrl}/deliverable-specs`,
|
|
61
|
-
};
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
async function httpJson(url, init, toolName) {
|
|
65
|
-
const res = await fetch(url, {
|
|
66
|
-
...init,
|
|
67
|
-
signal: AbortSignal.timeout(15_000),
|
|
68
|
-
});
|
|
69
|
-
if (!res.ok) {
|
|
70
|
-
const errText = await res.text().catch(() => '');
|
|
71
|
-
throw new Error(`${toolName}: upstream ${res.status} at ${url} — ${errText.slice(0, 400)}`);
|
|
72
|
-
}
|
|
73
|
-
try {
|
|
74
|
-
return (await res.json());
|
|
75
|
-
}
|
|
76
|
-
catch (err) {
|
|
77
|
-
const message = err instanceof Error ? err.message : String(err);
|
|
78
|
-
throw new Error(`${toolName}: upstream 2xx at ${url} returned non-JSON body — ${message}`);
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
const FETCH_SCHEMA_ARGS = {
|
|
82
|
-
kind: z
|
|
83
|
-
.enum(STUDIO_KINDS)
|
|
84
|
-
.describe('Which Studio artifact kind to fetch the live JSON Schema for. ' +
|
|
85
|
-
'`workflow` → /schemas/workflow/v1alpha1/Workflow.json (engine), ' +
|
|
86
|
-
'`spec` → /schemas/deliverable/v1/DeliverableSpec.json.'),
|
|
87
|
-
};
|
|
88
|
-
export function buildXemaStudioFetchSchemaTool(workspaceDir) {
|
|
89
|
-
return tool({
|
|
90
|
-
description: 'Fetch the live JSON Schema for a Studio artifact kind. Returns the ' +
|
|
91
|
-
'deterministic schema document published by the owning service so ' +
|
|
92
|
-
'every proposal cites real field names + enum values, never guessed. ' +
|
|
93
|
-
'Call this BEFORE proposing YAML so required keys and enum values ' +
|
|
94
|
-
'come from the live schema, not training data.',
|
|
95
|
-
args: FETCH_SCHEMA_ARGS,
|
|
96
|
-
async execute(args) {
|
|
97
|
-
const ctx = resolveStudioApiCtx(workspaceDir, 'xema_studio_fetch_schema');
|
|
98
|
-
const routes = routesFor(args.kind, ctx);
|
|
99
|
-
const schema = await httpJson(routes.schema, { method: 'GET', headers: studioHeaders(ctx) }, 'xema_studio_fetch_schema');
|
|
100
|
-
return toJsonString({ kind: args.kind, schema });
|
|
101
|
-
},
|
|
102
|
-
});
|
|
103
|
-
}
|
|
104
|
-
const VALIDATE_ARGS = {
|
|
105
|
-
kind: z
|
|
106
|
-
.enum(STUDIO_KINDS)
|
|
107
|
-
.describe('Studio artifact kind being validated.'),
|
|
108
|
-
rawYaml: z
|
|
109
|
-
.string()
|
|
110
|
-
.min(1)
|
|
111
|
-
.describe('Raw YAML body for the artifact. The tool routes to the service-side ' +
|
|
112
|
-
'compile-preview / preview / preview-content endpoint and reports ' +
|
|
113
|
-
'the typed result.'),
|
|
114
|
-
isReusable: z
|
|
115
|
-
.boolean()
|
|
116
|
-
.optional()
|
|
117
|
-
.describe('For `kind="workflow"`, when true selects the reusable-workflow ' +
|
|
118
|
-
'trigger envelope (`workflow_call`). Ignored for spec.'),
|
|
119
|
-
};
|
|
120
|
-
export function buildXemaStudioValidateTool(workspaceDir) {
|
|
121
|
-
return tool({
|
|
122
|
-
description: 'Validate proposed YAML against the live schema + compiler/preview ' +
|
|
123
|
-
'endpoint BEFORE emitting a StudioAuthorProposal. Returns the typed ' +
|
|
124
|
-
'compile-preview / validate result so the agent can either correct ' +
|
|
125
|
-
'errors and retry or include the successful summary in its proposal.',
|
|
126
|
-
args: VALIDATE_ARGS,
|
|
127
|
-
async execute(args) {
|
|
128
|
-
const ctx = resolveStudioApiCtx(workspaceDir, 'xema_studio_validate');
|
|
129
|
-
const routes = routesFor(args.kind, ctx);
|
|
130
|
-
let body;
|
|
131
|
-
if (args.kind === StudioKind.Workflow) {
|
|
132
|
-
body = {
|
|
133
|
-
rawYaml: args.rawYaml,
|
|
134
|
-
isReusable: args.isReusable === true,
|
|
135
|
-
};
|
|
136
|
-
}
|
|
137
|
-
else {
|
|
138
|
-
body = { rawYaml: args.rawYaml };
|
|
139
|
-
}
|
|
140
|
-
const result = await httpJson(routes.validate, {
|
|
141
|
-
method: 'POST',
|
|
142
|
-
headers: studioHeaders(ctx),
|
|
143
|
-
body: JSON.stringify(body),
|
|
144
|
-
}, 'xema_studio_validate');
|
|
145
|
-
return toJsonString({ kind: args.kind, result });
|
|
146
|
-
},
|
|
147
|
-
});
|
|
148
|
-
}
|
|
149
|
-
const LIST_ARGS = {
|
|
150
|
-
kind: z
|
|
151
|
-
.enum(STUDIO_KINDS)
|
|
152
|
-
.describe('Studio artifact kind to list.'),
|
|
153
|
-
search: z
|
|
154
|
-
.string()
|
|
155
|
-
.optional()
|
|
156
|
-
.describe('Optional case-insensitive substring filter applied to slug + title.'),
|
|
157
|
-
limit: z
|
|
158
|
-
.number()
|
|
159
|
-
.int()
|
|
160
|
-
.min(1)
|
|
161
|
-
.max(100)
|
|
162
|
-
.default(25)
|
|
163
|
-
.describe('Maximum entries to return — keep small to save tokens.'),
|
|
164
|
-
};
|
|
165
|
-
function projectListRows(rows) {
|
|
166
|
-
if (!Array.isArray(rows))
|
|
167
|
-
return [];
|
|
168
|
-
const out = [];
|
|
169
|
-
for (const row of rows) {
|
|
170
|
-
if (row === null || typeof row !== 'object')
|
|
171
|
-
continue;
|
|
172
|
-
const r = row;
|
|
173
|
-
if (typeof r.slug !== 'string')
|
|
174
|
-
continue;
|
|
175
|
-
out.push({
|
|
176
|
-
slug: r.slug,
|
|
177
|
-
...(typeof r.title === 'string' ? { title: r.title } : {}),
|
|
178
|
-
...(typeof r.version === 'string' ? { version: r.version } : {}),
|
|
179
|
-
...(typeof r.currentVersion === 'string'
|
|
180
|
-
? { version: r.currentVersion }
|
|
181
|
-
: {}),
|
|
182
|
-
...(typeof r.source === 'string' ? { source: r.source } : {}),
|
|
183
|
-
});
|
|
184
|
-
}
|
|
185
|
-
return out;
|
|
186
|
-
}
|
|
187
|
-
function matchesSearch(entry, search) {
|
|
188
|
-
const needle = search.toLowerCase();
|
|
189
|
-
if (entry.slug.toLowerCase().includes(needle))
|
|
190
|
-
return true;
|
|
191
|
-
if (entry.title && entry.title.toLowerCase().includes(needle))
|
|
192
|
-
return true;
|
|
193
|
-
return false;
|
|
194
|
-
}
|
|
195
|
-
export function buildXemaStudioListExistingArtifactsTool(workspaceDir) {
|
|
196
|
-
return tool({
|
|
197
|
-
description: 'List existing artifacts of a given kind within the active org/project ' +
|
|
198
|
-
'so the agent can reference them by real slug instead of inventing ' +
|
|
199
|
-
'names. Returns a slim array of { slug, title, version, source }; ' +
|
|
200
|
-
'never full bodies. Use this BEFORE suggesting `uses:` actions, ' +
|
|
201
|
-
'`extends:` chains, or spec refs.',
|
|
202
|
-
args: LIST_ARGS,
|
|
203
|
-
async execute(args) {
|
|
204
|
-
const ctx = resolveStudioApiCtx(workspaceDir, 'xema_studio_list_existing_artifacts');
|
|
205
|
-
const routes = routesFor(args.kind, ctx);
|
|
206
|
-
const raw = await httpJson(routes.list, { method: 'GET', headers: studioHeaders(ctx) }, 'xema_studio_list_existing_artifacts');
|
|
207
|
-
const rows = raw !== null && typeof raw === 'object' && 'data' in raw
|
|
208
|
-
? raw.data
|
|
209
|
-
: raw;
|
|
210
|
-
let entries = projectListRows(rows);
|
|
211
|
-
if (args.search && args.search.trim().length > 0) {
|
|
212
|
-
const filter = args.search.trim();
|
|
213
|
-
entries = entries.filter((e) => matchesSearch(e, filter));
|
|
214
|
-
}
|
|
215
|
-
const limit = args.limit ?? 25;
|
|
216
|
-
return toJsonString({ kind: args.kind, entries: entries.slice(0, limit) });
|
|
217
|
-
},
|
|
218
|
-
});
|
|
219
|
-
}
|
|
220
|
-
//# sourceMappingURL=xema-studio.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"xema-studio.js","sourceRoot":"","sources":["../../src/tools/xema-studio.ts"],"names":[],"mappings":"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"}
|
package/src/context.ts
DELETED
|
@@ -1,154 +0,0 @@
|
|
|
1
|
-
// ═══════════════════════════════════════════════════════════════════════════
|
|
2
|
-
// ── /workspace/context.json reader ──
|
|
3
|
-
// Read once per tool/hook invocation. Surfaces invocation identity (role,
|
|
4
|
-
// surface, runId, sessionId) and the per-invocation `authority` block to
|
|
5
|
-
// the plugin's tools and the system-prompt overlay hook.
|
|
6
|
-
// ═══════════════════════════════════════════════════════════════════════════
|
|
7
|
-
|
|
8
|
-
import { existsSync, readFileSync } from 'node:fs';
|
|
9
|
-
import { join } from 'node:path';
|
|
10
|
-
import { z } from 'zod';
|
|
11
|
-
|
|
12
|
-
import { warn } from './logger.js';
|
|
13
|
-
|
|
14
|
-
const ContextJsonSchema = z.object({
|
|
15
|
-
invocation: z.object({
|
|
16
|
-
runId: z.string().nullable().optional(),
|
|
17
|
-
sessionId: z.string().nullable().optional(),
|
|
18
|
-
attempt: z.number().int().min(1).default(1),
|
|
19
|
-
role: z.enum([
|
|
20
|
-
'unit-worker',
|
|
21
|
-
'coordinator',
|
|
22
|
-
'gate-reviewer',
|
|
23
|
-
'clarification-coordinator',
|
|
24
|
-
'scope-validator',
|
|
25
|
-
'agent-session',
|
|
26
|
-
'design-system-builder',
|
|
27
|
-
'engineer',
|
|
28
|
-
'generic-agent',
|
|
29
|
-
'auditor',
|
|
30
|
-
// Document Buddy: agent collaborates on a single KB document page
|
|
31
|
-
// by editing a real working file (`/workspace/document/<slug>.<ext>`)
|
|
32
|
-
// natively; workspace-proxy's document-sync component derives the
|
|
33
|
-
// reviewable change set from those edits.
|
|
34
|
-
'document',
|
|
35
|
-
]),
|
|
36
|
-
surface: z
|
|
37
|
-
.enum(['pipeline-run', 'agent-session', 'design-system-builder', 'gate-review'])
|
|
38
|
-
.optional(),
|
|
39
|
-
}),
|
|
40
|
-
project: z
|
|
41
|
-
.object({
|
|
42
|
-
orgId: z.string(),
|
|
43
|
-
projectId: z.string().nullish(),
|
|
44
|
-
// Pipeline invocations outside a run (interactive sessions,
|
|
45
|
-
// brainstorming, gate reviews not tied to a specific branch)
|
|
46
|
-
// emit `pipelineBranch: null` — distinct from "absent". Accept
|
|
47
|
-
// both null and undefined here so the context validation survives.
|
|
48
|
-
pipelineBranch: z.string().nullish(),
|
|
49
|
-
})
|
|
50
|
-
.nullish(),
|
|
51
|
-
authority: z.object({
|
|
52
|
-
mayWriteWorkspace: z.array(z.string()).default(['/workspace/deliverables']),
|
|
53
|
-
mayWriteSlugs: z.array(z.string()).default([]),
|
|
54
|
-
mayWriteKnowledgeBase: z.boolean().default(true),
|
|
55
|
-
mayEditRepos: z.boolean().default(false),
|
|
56
|
-
writePolicy: z.enum(['read-only', 'own-pages-only', 'full-write']),
|
|
57
|
-
/**
|
|
58
|
-
* Closed list of Xema-namespaced tool names this invocation may call.
|
|
59
|
-
* Resolved from the `RoleCapabilityProfile` for `invocation.role` by
|
|
60
|
-
* llm-registry-api's `agent-run-context.service.ts` and written into
|
|
61
|
-
* context.json verbatim. `session-state.ensureRoleAllowed` checks
|
|
62
|
-
* every Xema tool call against this list — no fallback to a per-role
|
|
63
|
-
* registry baked into the plugin.
|
|
64
|
-
*/
|
|
65
|
-
allowedXemaTools: z.array(z.string()).min(1),
|
|
66
|
-
}),
|
|
67
|
-
/**
|
|
68
|
-
* Optional `git` block consumed by the `session.idle` auto-commit hook
|
|
69
|
-
* (see `hooks/session-idle-autocommit.ts`). Written by the orchestrator
|
|
70
|
-
* when the session's `BranchMode` opts into per-turn auto-commit
|
|
71
|
-
* (`shared_dev_publish_to_prod` — the default). Absent / `disabled` for
|
|
72
|
-
* `branch_per_session` sessions, where commits are user-controlled.
|
|
73
|
-
*
|
|
74
|
-
* `repoSubPath` is the working repo's path relative to the workspace
|
|
75
|
-
* root. When omitted, the hook commits at the workspace root itself
|
|
76
|
-
* (single-repo workspace contract — multi-repo workspaces are handled
|
|
77
|
-
* by a future follow-up; see TODO(multi-repo) in the
|
|
78
|
-
* hook).
|
|
79
|
-
*/
|
|
80
|
-
git: z
|
|
81
|
-
.object({
|
|
82
|
-
autoCommit: z.enum(['enabled', 'disabled']),
|
|
83
|
-
repoSubPath: z.string().nullish(),
|
|
84
|
-
})
|
|
85
|
-
.nullish(),
|
|
86
|
-
/**
|
|
87
|
-
* Optional `actor` block consumed by the `session.idle` auto-commit
|
|
88
|
-
* hook. Mirrors `ActorRefDto` in workspace-git-api: the subject that
|
|
89
|
-
* triggered the turn. Stamped at session-start by the orchestrator
|
|
90
|
-
* (single-user binding) or rotated per-turn by the multi-user session
|
|
91
|
-
* extension. Absent for non-session invocations (pipeline-run agents
|
|
92
|
-
* never auto-commit).
|
|
93
|
-
*/
|
|
94
|
-
actor: z
|
|
95
|
-
.object({
|
|
96
|
-
kind: z.enum(['org_user']),
|
|
97
|
-
subjectRef: z.string().min(1),
|
|
98
|
-
displayName: z.string().min(1),
|
|
99
|
-
})
|
|
100
|
-
.nullish(),
|
|
101
|
-
});
|
|
102
|
-
|
|
103
|
-
export type InvocationContext = z.infer<typeof ContextJsonSchema>;
|
|
104
|
-
export type InvocationRole = InvocationContext['invocation']['role'];
|
|
105
|
-
|
|
106
|
-
/**
|
|
107
|
-
* Read and validate /workspace/context.json. Returns null if the file is
|
|
108
|
-
* absent — the plugin then registers no Xema-specific tools (non-Xema
|
|
109
|
-
* sessions simply pass through). Throws on malformed JSON or schema
|
|
110
|
-
* violations so programmatic consumers (tests, tools) see the underlying
|
|
111
|
-
* error; hooks call {@link readInvocationContextForHook} instead to get
|
|
112
|
-
* a log-and-skip shape.
|
|
113
|
-
*/
|
|
114
|
-
export function readInvocationContext(
|
|
115
|
-
workspaceDir: string,
|
|
116
|
-
): InvocationContext | null {
|
|
117
|
-
const path = join(workspaceDir, 'context.json');
|
|
118
|
-
if (!existsSync(path)) {
|
|
119
|
-
return null;
|
|
120
|
-
}
|
|
121
|
-
const raw = readFileSync(path, 'utf-8');
|
|
122
|
-
const parsed = JSON.parse(raw) as unknown;
|
|
123
|
-
return ContextJsonSchema.parse(parsed);
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
/**
|
|
127
|
-
* Hook-friendly variant of {@link readInvocationContext}. Silently returns
|
|
128
|
-
* `null` when `context.json` is absent (expected for non-Xema sessions /
|
|
129
|
-
* pre-mount calls), and emits a prefixed warn to stderr when the file is
|
|
130
|
-
* present but malformed — previously these errors propagated into
|
|
131
|
-
* opencode's hook dispatcher and were swallowed by the runtime, leaving
|
|
132
|
-
* operators with no signal that the plugin had gone blind mid-session.
|
|
133
|
-
*/
|
|
134
|
-
export function readInvocationContextForHook(
|
|
135
|
-
workspaceDir: string,
|
|
136
|
-
hookName: string,
|
|
137
|
-
): InvocationContext | null {
|
|
138
|
-
const path = join(workspaceDir, 'context.json');
|
|
139
|
-
if (!existsSync(path)) {
|
|
140
|
-
return null;
|
|
141
|
-
}
|
|
142
|
-
try {
|
|
143
|
-
const raw = readFileSync(path, 'utf-8');
|
|
144
|
-
const parsed = JSON.parse(raw) as unknown;
|
|
145
|
-
return ContextJsonSchema.parse(parsed);
|
|
146
|
-
} catch (err) {
|
|
147
|
-
const message = err instanceof Error ? err.message : String(err);
|
|
148
|
-
warn(
|
|
149
|
-
`hook=${hookName}: failed to read/validate ${path}: ${message}. ` +
|
|
150
|
-
`Hook will skip this invocation; fix context.json to re-enable plugin behavior.`,
|
|
151
|
-
);
|
|
152
|
-
return null;
|
|
153
|
-
}
|
|
154
|
-
}
|
package/src/errors.ts
DELETED
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
// ═══════════════════════════════════════════════════════════════════════════
|
|
2
|
-
// ── Plugin error types ──
|
|
3
|
-
// Typed errors surfaced to the LLM as tool results. Opencode naturally
|
|
4
|
-
// retries tool errors in the same session, so these are our in-session
|
|
5
|
-
// correction signals.
|
|
6
|
-
// ═══════════════════════════════════════════════════════════════════════════
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* Thrown by the `experimental.chat.system.transform` hook when a Xema
|
|
10
|
-
* session boots but `/workspace/.xema/system-overlay.md` is missing.
|
|
11
|
-
*
|
|
12
|
-
* Fail-closed: the run's platform contract is undefined; we refuse to
|
|
13
|
-
* start the chat rather than letting the agent operate without the AWP
|
|
14
|
-
* base layer + deliverable contract + authority guidance the rest of
|
|
15
|
-
* the platform assumes is in scope.
|
|
16
|
-
*/
|
|
17
|
-
export class XemaSystemOverlayMissingError extends Error {
|
|
18
|
-
readonly code = 'XEMA_SYSTEM_OVERLAY_MISSING';
|
|
19
|
-
constructor(message: string) {
|
|
20
|
-
super(message);
|
|
21
|
-
this.name = 'XemaSystemOverlayMissingError';
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
|