@crewx/sdk 0.9.0-rc.140 → 0.9.0-rc.141
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/app/app.d.ts +49 -1
- package/dist/app/content-media-types.d.ts +2 -0
- package/dist/app/context.d.ts +2 -0
- package/dist/app/frame.d.ts +56 -0
- package/dist/app/index.d.ts +4 -2
- package/dist/app/index.js +10 -9
- package/dist/app/protocol.d.ts +9 -0
- package/dist/app/runtime.d.ts +4 -2
- package/dist/app/tool-mode.d.ts +3 -0
- package/dist/esm/app/index.js +10 -9
- package/dist/esm/index.js +321 -288
- package/dist/esm/plugins/index.js +54 -54
- package/dist/esm/publish/index.js +2 -2
- package/dist/esm/repository/index.js +73 -73
- package/dist/esm/skills/index.js +2 -2
- package/dist/index.browser.js +3 -3
- package/dist/index.d.ts +5 -4
- package/dist/index.js +322 -289
- package/dist/mcp-app/content-channel.d.ts +3 -6
- package/dist/mcp-app/content-declarations.d.ts +4 -2
- package/dist/mcp-app/skill-backend.d.ts +3 -4
- package/dist/migrations/0036_ui_definition_archive.sql +8 -0
- package/dist/migrations/meta/0036_snapshot.json +3591 -0
- package/dist/migrations/meta/_journal.json +7 -0
- package/dist/plugins/index.js +53 -53
- package/dist/publish/index.js +2 -2
- package/dist/repository/index.js +70 -70
- package/dist/schema/index.d.ts +1 -0
- package/dist/schema/ui-definition-archive.d.ts +63 -0
- package/dist/skills/index.js +2 -2
- package/dist/ui-instance/index.d.ts +3 -3
- package/dist/ui-instance/lineage.d.ts +2 -0
- package/dist/ui-instance/store.d.ts +14 -0
- package/dist/ui-plugin/app-manifest.d.ts +7 -2
- package/dist/ui-plugin/index.d.ts +2 -2
- package/dist/ui-plugin/types.d.ts +10 -1
- package/package.json +1 -1
package/dist/app/app.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { UiContentMediaType } from './content-media-types.js';
|
|
1
2
|
export type JsonObject = Record<string, unknown>;
|
|
2
3
|
export type JsonSchema = Readonly<{
|
|
3
4
|
type: 'object';
|
|
@@ -26,6 +27,33 @@ export interface AppDefinition {
|
|
|
26
27
|
allow: readonly string[];
|
|
27
28
|
}>;
|
|
28
29
|
}
|
|
30
|
+
export interface ToolContentInput {
|
|
31
|
+
readonly mediaType: UiContentMediaType;
|
|
32
|
+
readonly required?: boolean;
|
|
33
|
+
}
|
|
34
|
+
export interface ToolContentOutput {
|
|
35
|
+
readonly mediaType: UiContentMediaType;
|
|
36
|
+
readonly range?: boolean;
|
|
37
|
+
}
|
|
38
|
+
export interface ToolContentDeclaration {
|
|
39
|
+
readonly in?: ToolContentInput;
|
|
40
|
+
readonly out?: ToolContentOutput;
|
|
41
|
+
}
|
|
42
|
+
export interface ContentRangeRequest {
|
|
43
|
+
readonly startLine: number;
|
|
44
|
+
readonly lineCount: number;
|
|
45
|
+
}
|
|
46
|
+
export interface ContentRange extends ContentRangeRequest {
|
|
47
|
+
readonly totalLines: number;
|
|
48
|
+
}
|
|
49
|
+
export interface ToolContent {
|
|
50
|
+
readonly in?: {
|
|
51
|
+
readonly text: string;
|
|
52
|
+
};
|
|
53
|
+
readonly out?: {
|
|
54
|
+
readonly range?: ContentRangeRequest;
|
|
55
|
+
};
|
|
56
|
+
}
|
|
29
57
|
export interface ToolOptions {
|
|
30
58
|
readonly name: string;
|
|
31
59
|
readonly description: string;
|
|
@@ -37,10 +65,19 @@ export interface ToolOptions {
|
|
|
37
65
|
readonly resultProjection?: Readonly<{
|
|
38
66
|
allow: readonly string[];
|
|
39
67
|
}>;
|
|
68
|
+
readonly content?: ToolContentDeclaration;
|
|
69
|
+
}
|
|
70
|
+
export interface AppContext {
|
|
71
|
+
readonly instanceId: string;
|
|
72
|
+
readonly threadId: string | null;
|
|
73
|
+
readonly actor: 'user' | 'agent';
|
|
74
|
+
readonly requestId: string;
|
|
75
|
+
readonly nowMs: number;
|
|
40
76
|
}
|
|
41
77
|
export interface AppRuntimeOptions<State extends JsonObject = JsonObject> {
|
|
42
78
|
readonly state?: State;
|
|
43
79
|
readonly workspaceRoot: string;
|
|
80
|
+
readonly context?: AppContext;
|
|
44
81
|
}
|
|
45
82
|
export type AppFailureOutcome = 'failed' | 'rejected';
|
|
46
83
|
export interface AppErrorMapping {
|
|
@@ -71,11 +108,21 @@ export declare class CrewXApp<State extends JsonObject = JsonObject> {
|
|
|
71
108
|
} | undefined;
|
|
72
109
|
private currentState;
|
|
73
110
|
private stateWasSet;
|
|
111
|
+
private answerBody;
|
|
112
|
+
private answerRange;
|
|
113
|
+
private readonly callContext;
|
|
74
114
|
readonly workspaceRoot: string;
|
|
75
115
|
constructor(options?: AppRuntimeOptions<State>);
|
|
116
|
+
get context(): AppContext;
|
|
76
117
|
get state(): DeepReadonly<State>;
|
|
77
118
|
get didSetState(): boolean;
|
|
78
119
|
setState(next: State): void;
|
|
120
|
+
get didSetContent(): boolean;
|
|
121
|
+
get producedContent(): {
|
|
122
|
+
readonly body: Uint8Array;
|
|
123
|
+
readonly range?: ContentRange;
|
|
124
|
+
} | undefined;
|
|
125
|
+
setContent(body: string | Uint8Array, range?: ContentRange): void;
|
|
79
126
|
emptyState(): State;
|
|
80
127
|
validate(_actionId: string, _input: JsonObject, _state: JsonObject): void | Promise<void>;
|
|
81
128
|
mapError(_error: unknown): AppErrorMapping;
|
|
@@ -92,9 +139,10 @@ export type CrewXAppConstructor = (new (options: AppRuntimeOptions) => CrewXApp)
|
|
|
92
139
|
readonly definition: AppDefinition;
|
|
93
140
|
readonly [key: string]: unknown;
|
|
94
141
|
};
|
|
95
|
-
type DecoratedMethod<This, Input extends object, Result extends ToolResult> = (this: This, input: Input) => Result;
|
|
142
|
+
type DecoratedMethod<This, Input extends object, Result extends ToolResult> = (this: This, input: Input, content: ToolContent) => Result;
|
|
96
143
|
export declare function Tool(options: ToolOptions): <This, Input extends object, Result extends ToolResult>(_method: DecoratedMethod<This, Input, Result>, context: ClassMethodDecoratorContext<This, DecoratedMethod<This, Input, Result>>) => void;
|
|
97
144
|
export declare function getToolDeclarations(appClass: CrewXAppConstructor): ToolDeclaration[];
|
|
145
|
+
export declare function generateToolDeclarations(appClass: CrewXAppConstructor): JsonObject[];
|
|
98
146
|
export declare function generateManifest(appClass: CrewXAppConstructor, backendCommand: readonly string[]): JsonObject;
|
|
99
147
|
export declare function isPlainRecord(value: unknown): value is JsonObject;
|
|
100
148
|
export {};
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import type { ContentRange, ContentRangeRequest, JsonObject } from './app.js';
|
|
2
|
+
import type { UiContentMediaType } from './protocol.js';
|
|
3
|
+
export declare const V1_MAX_INPUT_BYTES: number;
|
|
4
|
+
export declare const MAX_REQUEST_BYTES: number;
|
|
5
|
+
export type RequestFrame = {
|
|
6
|
+
readonly kind: 'v1';
|
|
7
|
+
readonly value: unknown;
|
|
8
|
+
} | {
|
|
9
|
+
readonly kind: 'v2';
|
|
10
|
+
readonly header: JsonObject;
|
|
11
|
+
readonly body: Uint8Array;
|
|
12
|
+
} | {
|
|
13
|
+
readonly kind: 'invalid';
|
|
14
|
+
};
|
|
15
|
+
export declare function readStdinBytes(fd: number, maxBytes: number): Uint8Array | undefined;
|
|
16
|
+
export declare function readRequestFrame(fd: number): RequestFrame;
|
|
17
|
+
export declare function parseRequestFrame(bytes: Uint8Array | undefined): RequestFrame;
|
|
18
|
+
export interface ContentRequest {
|
|
19
|
+
readonly in?: {
|
|
20
|
+
readonly mediaType: UiContentMediaType;
|
|
21
|
+
readonly text: string;
|
|
22
|
+
};
|
|
23
|
+
readonly out?: {
|
|
24
|
+
readonly mediaType: UiContentMediaType;
|
|
25
|
+
readonly range?: ContentRangeRequest;
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
export interface VerifiedFrame {
|
|
29
|
+
readonly actionId: string;
|
|
30
|
+
readonly input: JsonObject;
|
|
31
|
+
readonly state: JsonObject;
|
|
32
|
+
readonly content: ContentRequest;
|
|
33
|
+
}
|
|
34
|
+
export interface FrameFailure {
|
|
35
|
+
readonly code: string;
|
|
36
|
+
readonly outcome: 'failed' | 'rejected';
|
|
37
|
+
}
|
|
38
|
+
export declare function verifyRequestFrame(header: JsonObject, body: Uint8Array): VerifiedFrame | FrameFailure;
|
|
39
|
+
export declare function isFrameFailure(value: VerifiedFrame | FrameFailure): value is FrameFailure;
|
|
40
|
+
export interface DeclaredContent {
|
|
41
|
+
readonly in?: {
|
|
42
|
+
readonly mediaType: UiContentMediaType;
|
|
43
|
+
readonly required?: boolean;
|
|
44
|
+
};
|
|
45
|
+
readonly out?: {
|
|
46
|
+
readonly mediaType: UiContentMediaType;
|
|
47
|
+
readonly range?: boolean;
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
export declare function checkAgainstDeclaration(declared: DeclaredContent | undefined, request: ContentRequest): FrameFailure | undefined;
|
|
51
|
+
export interface AnswerContent {
|
|
52
|
+
readonly body: Uint8Array;
|
|
53
|
+
readonly range?: ContentRange;
|
|
54
|
+
}
|
|
55
|
+
export declare function encodeResponseFrame(header: JsonObject, answer?: AnswerContent): Uint8Array;
|
|
56
|
+
export declare function answerLimitFailure(answer: AnswerContent): FrameFailure | undefined;
|
package/dist/app/index.d.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
export { AppError, CrewXApp, Tool, generateManifest, getToolDeclarations, } from './app.js';
|
|
2
|
-
export type { AppDefinition, AppErrorContext, AppErrorMapping, AppErrorOptions, AppFailureOutcome, AppRuntimeOptions, CrewXAppConstructor, DeepReadonly, JsonObject, JsonSchema, ToolDeclaration, ToolOptions, ToolResult, } from './app.js';
|
|
1
|
+
export { AppError, CrewXApp, Tool, generateManifest, generateToolDeclarations, getToolDeclarations, } from './app.js';
|
|
2
|
+
export type { AppContext, AppDefinition, AppErrorContext, AppErrorMapping, AppErrorOptions, AppFailureOutcome, AppRuntimeOptions, ContentRange, ContentRangeRequest, CrewXAppConstructor, DeepReadonly, JsonObject, JsonSchema, ToolContent, ToolContentDeclaration, ToolContentInput, ToolContentOutput, ToolDeclaration, ToolOptions, ToolResult, } from './app.js';
|
|
3
|
+
export { readAppContext } from './context.js';
|
|
4
|
+
export { APP_TOOLS_FILE, APP_TOOLS_SCHEMA_VERSION, APP_TOOL_ENTRY } from './tool-mode.js';
|
|
3
5
|
export { SKILL_BACKEND_ENV_NAMES, isSkillBackendEnv } from './backend-env.js';
|
|
4
6
|
export type { SkillBackendEnvName } from './backend-env.js';
|
|
5
7
|
export { executeAppRequest, runSkillApp } from './runtime.js';
|
package/dist/app/index.js
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
'use strict';var fs=require('fs'),
|
|
2
|
-
|
|
3
|
-
`;}catch(
|
|
4
|
-
`;}
|
|
5
|
-
|
|
6
|
-
`),o=
|
|
7
|
-
`),E
|
|
8
|
-
`)
|
|
9
|
-
`);}function
|
|
1
|
+
'use strict';var util=require('util'),fs=require('fs'),crypto=require('crypto'),console$1=require('console'),stream=require('stream');var h=["text/plain","application/json"];var Y=Symbol;Y.metadata===void 0&&Object.defineProperty(Symbol,"metadata",{configurable:false,value:Symbol.for("Symbol.metadata")});var ue=Y.metadata,N=Symbol.for("crewx.app.tool-metadata"),A=class extends Error{code;detail;outcome;constructor(t,n=null,o){super(t),this.name="AppError",this.code=t,this.detail=n,this.outcome=q(o?.outcome);}};function q(e){return e==="rejected"?"rejected":"failed"}var X=class{static devtools=process.env.CREWX_APP_DEV==="1"?Object.freeze({log:true}):void 0;currentState;stateWasSet=false;answerBody;answerRange;callContext;workspaceRoot;constructor(t={workspaceRoot:process.cwd()}){this.currentState=t.state??{},this.workspaceRoot=t.workspaceRoot,this.callContext=t.context===void 0?void 0:fe(t.context);}get context(){if(this.callContext===void 0)throw new TypeError("this.context is only set when the Host runs the action; pass options.context when you construct the App in a test");return this.callContext}get state(){return this.currentState}get didSetState(){return this.stateWasSet}setState(t){this.currentState=t,this.stateWasSet=true;}get didSetContent(){return this.answerBody!==void 0}get producedContent(){return this.answerBody===void 0?void 0:{body:this.answerBody,...this.answerRange===void 0?{}:{range:this.answerRange}}}setContent(t,n){if(typeof t!="string"&&!(t instanceof Uint8Array))throw new TypeError("setContent needs a string or a Uint8Array");if(n!==void 0&&!me(n))throw new TypeError("setContent range must be { startLine, lineCount, totalLines }, three integers of at least 1");this.answerBody=typeof t=="string"?new TextEncoder().encode(t):new Uint8Array(t),this.answerRange=n===void 0?void 0:{startLine:n.startLine,lineCount:n.lineCount,totalLines:n.totalLines};}emptyState(){return {}}validate(t,n,o){}mapError(t){return {code:"EXECUTION_FAILED",detail:null}}errorState(t,n,o){return {...O(o.state)?o.state:{},error:{code:t,detail:n}}}};function ce(e){return function(t,n){if(n.static||n.private||n.kind!=="method")throw new TypeError("@Tool can decorate public instance methods only");let o=n.metadata;if(!o)throw new TypeError("standard decorator metadata is unavailable");let i=Object.hasOwn(o,N)?o[N]:[];if(i.some(s=>s.methodName===String(n.name)))throw new TypeError(`@Tool is declared more than once for ${String(n.name)}`);let r=e.content===void 0?void 0:pe(e.name,e.content);o[N]=[...i,{methodName:String(n.name),options:Object.freeze({...e,...r===void 0?{}:{content:r}})}];}}function D(e){let t=e[ue],n=t&&Object.hasOwn(t,N)?t[N]:[],o=new Map(n.map(r=>[r.methodName,r])),i=Object.getOwnPropertyNames(e.prototype).map(r=>o.get(r)).filter(r=>r!==void 0);if(i.length!==n.length)throw new TypeError("a @Tool method is missing from the App prototype");return i}function H(e){let t=e.definition,n=D(e),o=new Set;return n.map(({options:i})=>{if(o.has(i.name))throw new TypeError(`duplicate @Tool name: ${i.name}`);return o.add(i.name),{actionId:i.name,...i.dataInputs===void 0?{}:{dataInputs:[...i.dataInputs]},confirmation:i.confirmation??"none",capability:i.capability??"app.read",mutation:i.mutation??true,inputSchema:i.inputSchema,...i.content===void 0?{}:{content:ye(i.content)},resultProjection:i.resultProjection??{allow:[...t.stateProjection.allow]},_meta:{description:i.description}}})}function le(e,t){if(t.length===0)throw new TypeError("backendCommand must name the skill command");let n=H(e).map(({_meta:o,...i})=>({...i,backend:{type:"skill",command:[...t]},_meta:o}));return {...e.definition,actions:n}}function pe(e,t){let n=r=>{throw new TypeError(`@Tool ${e}: content ${r}`)},o=(r,s,u)=>{if(!O(u))return n(`${r} must be an object`);for(let a of Object.keys(u))if(a==="mediaType"){if(!h.includes(u[a]))return n(`${r}.mediaType must be one of ${h.join(", ")}`)}else if(a===s){if(typeof u[a]!="boolean")return n(`${r}.${a} must be true or false`)}else return n(`${r} has the unknown key "${a}"`);return Object.hasOwn(u,"mediaType")?Object.freeze({...u}):n(`${r}.mediaType is required`)};if(!O(t))return n("must be an object");let i={};for(let r of Object.keys(t))if(r==="in")i[r]=o("in","required",t[r]);else if(r==="out")i[r]=o("out","range",t[r]);else return n(`has the unknown key "${r}"; use "in" and/or "out"`);return Object.keys(i).length===0?n('needs "in" and/or "out"'):Object.freeze(i)}function fe(e){return Object.freeze({instanceId:e.instanceId,threadId:e.threadId,actor:e.actor,requestId:e.requestId,nowMs:e.nowMs})}function ye(e){let t={};for(let[n,o]of Object.entries(e))t[n]={...o};return t}function me(e){return O(e)&&["startLine","lineCount","totalLines"].every(t=>Number.isSafeInteger(e[t])&&e[t]>=1)}function O(e){if(e===null||typeof e!="object"||Array.isArray(e))return false;let t=Object.getPrototypeOf(e);return t===Object.prototype||t===null}var Te=/^[A-Za-z0-9._:-]{1,128}$/u,Ee=/[\u0000-\u001f\u007f\u2028\u2029]/u;function B(e=process.env){let t=G(e.CREWX_APP_INSTANCE_ID),n=e.CREWX_APP_REQUEST_ID,o=e.CREWX_APP_ACTOR_KIND,i=e.CREWX_APP_NOW_MS;if(t===void 0||typeof n!="string"||!Te.test(n)||o!=="user"&&o!=="agent"||typeof i!="string"||!/^\d{1,16}$/u.test(i))return;let r=Number(i);if(!Number.isSafeInteger(r))return;let s=e.CREWX_THREAD_ID===void 0?null:G(e.CREWX_THREAD_ID);if(s!==void 0)return Object.freeze({instanceId:t,threadId:s,actor:o,requestId:n,nowMs:r})}function G(e){if(!(typeof e!="string"||e.length===0||Ee.test(e)))return new TextEncoder().encode(e).byteLength<=512?e:void 0}var ge="dist/tools.json",Ae=1,Ce="dist/main.mjs";var Q=["CREWX_APP_INSTANCE_ID","CREWX_THREAD_ID"];function Oe(e){if(!Array.isArray(e)||e.length===0)return false;let t=new Set;for(let n of e){if(!Q.some(o=>o===n)||t.has(n))return false;t.add(n);}return true}var j=2,K=524288;var R=2*1024*1024,U=2e4;function $(e){return crypto.createHash("sha256").update(e).digest("hex")}function L(e){if(e.byteLength===0)return 0;let t=0;for(let n of e)n===10&&(t+=1);return e[e.byteLength-1]!==10&&(t+=1),t}var be=64*1024,Se=K+1+R,Ie=64*1024,he=10,F={kind:"invalid"};function Re(e,t){try{let n=[],o=0;for(;;){let s=new Uint8Array(Ie),u=fs.readSync(e,s,0,s.length,null);if(u===0)break;if(o+=u,o>t)return;n.push(s.subarray(0,u));}let i=new Uint8Array(o),r=0;for(let s of n)i.set(s,r),r+=s.byteLength;return i}catch{return}}function P(e){return Ne(Re(e,Se))}function Ne(e){if(e===void 0)return F;let t=e.indexOf(he);if(e.byteLength<=be){let o=Le(Buffer.from(e.buffer,e.byteOffset,e.byteLength).toString("utf8"));if(o.ok&&!(t>=0&&b(o.value)&&o.value.schemaVersion===j))return {kind:"v1",value:o.value}}if(t<=0||t>K)return F;let n;try{n=JSON.parse(new TextDecoder("utf-8",{fatal:!0}).decode(e.subarray(0,t)));}catch{return F}return !b(n)||n.schemaVersion!==j?F:{kind:"v2",header:n,body:e.subarray(t+1)}}var xe="actionId,content,input,schemaVersion,state",ke="bytes,lines,mediaType,sha256",De="mediaType,range",je=/^[a-f0-9]{64}$/u,Ue=new TextDecoder("utf-8",{fatal:true,ignoreBOM:true});function te(e,t){let n=a=>({code:a,outcome:"rejected"});if(x(e)!==xe||e.schemaVersion!==j||typeof e.actionId!="string"||!b(e.input)||!b(e.state)||!b(e.content)||x(e.content)!=="in,out")return {code:"INPUT_INVALID",outcome:"failed"};let o=e.content,i,r=o.in;if(r===null){if(t.byteLength!==0)return n(t.byteLength>R?"CONTENT_TOO_LARGE":"CONTENT_DIGEST_MISMATCH")}else {if(!b(r)||x(r)!==ke||!Z(r.mediaType)||!ee(r.bytes,R)||!ee(r.lines,U)||typeof r.sha256!="string"||!je.test(r.sha256)||t.byteLength!==r.bytes)return n(t.byteLength>R?"CONTENT_TOO_LARGE":"CONTENT_DIGEST_MISMATCH");if($(t)!==r.sha256||L(t)!==r.lines)return n("CONTENT_DIGEST_MISMATCH");let a;try{a=Ue.decode(t);}catch{return n("CONTENT_ENCODING_INVALID")}i={mediaType:r.mediaType,text:a};}let s,u=o.out;if(u!==null){if(!b(u)||x(u)!==De||!Z(u.mediaType))return n("CONTENT_SOURCE_UNSUPPORTED");let a=u.range;if(a!==null&&!Fe(a))return n("CONTENT_SOURCE_UNSUPPORTED");s={mediaType:u.mediaType,...a===null?{}:{range:{startLine:a.startLine,lineCount:a.lineCount}}};}return {actionId:e.actionId,input:e.input,state:e.state,content:{...i===void 0?{}:{in:i},...s===void 0?{}:{out:s}}}}function ne(e){return Object.hasOwn(e,"code")}function oe(e,t){let n=o=>({code:o,outcome:"rejected"});if(e?.in===void 0){if(t.in!==void 0)return n("CONTENT_SOURCE_UNSUPPORTED")}else if(t.in===void 0){if(e.in.required===true)return n("CONTENT_REQUIRED")}else if(t.in.mediaType!==e.in.mediaType)return n("CONTENT_SOURCE_UNSUPPORTED");if(e?.out===void 0){if(t.out!==void 0)return n("CONTENT_SOURCE_UNSUPPORTED")}else {if(t.out===void 0)return n("CONTENT_REQUIRED");if(t.out.mediaType!==e.out.mediaType||t.out.range!==void 0&&e.out.range!==true)return n("CONTENT_SOURCE_UNSUPPORTED")}}function M(e,t){let{content:n,...o}=e,i=t===void 0?o:{...o,content:{bytes:t.body.byteLength,lines:L(t.body),sha256:$(t.body),...t.range===void 0?{}:{range:t.range}}},r=new TextEncoder().encode(`${JSON.stringify(i)}
|
|
2
|
+
`);if(t===void 0)return r;let s=new Uint8Array(r.byteLength+t.body.byteLength);return s.set(r,0),s.set(t.body,r.byteLength),s}function re(e){if(e.body.byteLength>R||L(e.body)>U)return {code:"CONTENT_TOO_LARGE",outcome:"failed"}}function Le(e){try{return {ok:!0,value:JSON.parse(e)}}catch{return {ok:false}}}function x(e){return Object.keys(e).sort().join(",")}function b(e){if(e===null||typeof e!="object"||Array.isArray(e))return false;let t=Object.getPrototypeOf(e);return t===Object.prototype||t===null}function Z(e){return typeof e=="string"&&h.includes(e)}function ee(e,t){return Number.isSafeInteger(e)&&e>=0&&e<=t}function Fe(e){return b(e)&&x(e)==="lineCount,startLine"&&Number.isSafeInteger(e.startLine)&&e.startLine>=1&&Number.isSafeInteger(e.lineCount)&&e.lineCount>=1&&e.lineCount<=U}var Me=1;async function ve(e,t,n=process.env.CREWX_WORKSPACE_ROOT??process.cwd(),o){return (await se(e,t,n,void 0,true,void 0,o)).response}async function se(e,t,n,o,i=true,r,s){let u=r!==void 0,a=O(t)?t:void 0,m=a?.input,T=a?.state,d=new e({state:O(T)?T:{},workspaceRoot:n,...s===void 0?{}:{context:s}}),C=O(m)?m:{},E=O(T)?T:d.emptyState(),y={};try{let c;if(u){if(a===void 0)throw new A("INPUT_INVALID");let f=te(a,r);if(ne(f))throw new A(f.code,null,{outcome:f.outcome});(({actionId:c,input:C,state:E}=f)),y=f.content;}else {if(!a||Object.keys(a).length!==4||!["schemaVersion","actionId","input","state"].every(f=>Object.hasOwn(a,f))||a.schemaVersion!==Me||typeof a.actionId!="string"||!O(m)||!O(T))throw new A("INPUT_INVALID");c=a.actionId,C=m,E=T;}d=new e({state:E,workspaceRoot:n,...s===void 0?{}:{context:s}}),await d.validate(c,C,E);let l=D(e).find(({options:f})=>f.name===c);if(!l)throw new A("INPUT_INVALID");let g=d[l.methodName];if(typeof g!="function")throw new A("EXECUTION_FAILED");let p=oe(l.options.content,y);if(p)throw new A(p.code,null,{outcome:p.outcome});let k=Object.freeze({...y.in===void 0?{}:{in:Object.freeze({text:y.in.text})},...y.out===void 0?{}:{out:Object.freeze(y.out.range===void 0?{}:{range:Object.freeze({...y.out.range})})}}),I=()=>g.call(d,C,k),S=i?await Xe(I):await I();if(S!==void 0&&!O(S))throw new A("EXECUTION_FAILED");let _;if(y.out!==void 0){if(_=d.producedContent,_===void 0)throw new A("EXECUTION_FAILED","content.out was requested but setContent was never called");let f=re(_);if(f)throw new A(f.code,null,{outcome:f.outcome})}else if(d.didSetContent)throw new A("EXECUTION_FAILED","setContent was called but the request asked for no content.out");return {response:{...d.didSetState?{state:d.state}:{},...S===void 0?{}:{result:S}},..._===void 0?{}:{answer:_}}}catch(c){let l,g=c,p=c instanceof A?c:void 0;if(p)l={code:p.code,detail:p.detail,outcome:p.outcome};else try{l=d.mapError(c);}catch(J){l={code:"EXECUTION_FAILED",detail:null},g=J;}let k=Be(l?.code),I=k?l.code:"EXECUTION_FAILED",S=typeof l?.detail=="string"?l.detail:null,_=k?q(l.outcome):"failed",f;try{f=d.errorState(I,S,{input:C,state:E});}catch(J){g=new AggregateError([g,J],"App error handling failed"),f=d.emptyState();}return o?.(I,g,{outcome:_,detail:S,expected:p!==void 0&&g===p}),{response:{outcome:_,errorCode:I,state:O(f)?f:d.emptyState()}}}}async function Je(e,t={}){let n=t.output??process.stdout,o,i;if(t.preloadedInput!==void 0)o=t.preloadedInput.value,i=t.preloadedInput.body;else {let d=P(t.inputFd??0);d.kind==="v1"?o=d.value:d.kind==="v2"&&(o=d.header,i=d.body);}let r=i!==void 0,s=t.context??B(),u=false,a=(d,C,E)=>{u=true,t.onFailure?.(d,C,E);},m;try{m=await se(e,o,process.env.CREWX_WORKSPACE_ROOT??process.cwd(),a,t.consoleManaged!==!0,i,s);}catch(d){a("EXECUTION_FAILED",d),m={response:ie(t.emptyState)};}qe(m.response)&&!u&&a(m.response.errorCode,void 0,{outcome:m.response.outcome,detail:null,expected:false});let T;try{let d=(t.sanitize??ae)(m.response);T=r?M(d,m.answer):`${JSON.stringify(d)}
|
|
3
|
+
`;}catch(d){a("EXECUTION_FAILED",d);let C=ie(t.emptyState);try{let E=(t.sanitize??ae)(C);T=r?M(E):`${JSON.stringify(E)}
|
|
4
|
+
`;}catch(E){a("EXECUTION_FAILED",E),T=r?M(C):`${JSON.stringify(C)}
|
|
5
|
+
`;}}n.write(T);}async function Xe(e){let t=["log","info","debug"],n=new Map;for(let o of t)n.set(o,console[o]),console[o]=(...i)=>process.stderr.write(`${util.format(...i)}
|
|
6
|
+
`);try{return await e()}finally{for(let o of t)console[o]=n.get(o);}}function ie(e={}){return {outcome:"failed",errorCode:"EXECUTION_FAILED",state:{...e,error:{code:"EXECUTION_FAILED",detail:null}}}}function qe(e){return (e.outcome==="failed"||e.outcome==="rejected")&&typeof e.errorCode=="string"}function Be(e){return typeof e=="string"&&/^[A-Z][A-Z0-9_]{0,127}$/u.test(e)}function ae(e){return e}var V={depth:null,maxArrayLength:null,maxStringLength:null},W=class extends stream.Writable{#e="buffer";#t=[];_write(t,n,o){if(this.#e==="buffer"){this.#t.push(typeof t=="string"?t:Uint8Array.from(t)),o();return}if(this.#e==="discard"){o();return}process.stderr.write(t,o);}flushToStderr(){this.#e="stderr";for(let t of this.#t)process.stderr.write(t);this.#t=[];}discard(){this.#e="discard",this.#t=[];}};async function Ve(e,t={}){let n=process.stdout,o=n.write.bind(n),i=new W,r=new console$1.Console({stdout:i,stderr:i,inspectOptions:{...V}});globalThis.console=r;let s=false,u="-",a="-",m,T=false,d,C;try{let c=We(t.inputFd??0);u=Ye(c.value),a=v(process.env.CREWX_APP_REQUEST_ID),m=new Date().toISOString();try{d=await e();}catch(p){T=!0,C=p;}let l=d?.default;if(!T&&l?.devtools?.log===!0?(Object.assign(util.inspect.defaultOptions,V),E(m),i.flushToStderr()):i.discard(),T){y("EXECUTION_FAILED",C),z(o,t,y);return}try{if(typeof d?.runSkillApp!="function")throw new TypeError("App module does not export runSkillApp");let p={sanitize:t.sanitize,emptyState:t.emptyState??ze(l),preloadedInput:c.body===void 0?{value:c.value}:{value:c.value,body:c.body},onFailure:y,consoleManaged:!0,output:{write:o}};await d.runSkillApp(l,p);}catch(p){y("EXECUTION_FAILED",p),z(o,t,y);}}catch(c){y("EXECUTION_FAILED",c),z(o,t,y);}finally{process.exitCode=0;}function E(c){s||(process.stderr.write(`[crewx-app] ${c??new Date().toISOString()} ${v(u)} req=${a}
|
|
7
|
+
`),s=true);}function y(c,l,g){E();let p=g?.expected===true&&g.detail?` ${v(g.detail)}`:"";process.stderr.write(`[crewx-app] ${g?.outcome??"failed"} ${v(c)}${p}
|
|
8
|
+
`),l!==void 0&&g?.expected!==true&&process.stderr.write(`${util.inspect(l,V)}
|
|
9
|
+
`);}}function ze(e){if(typeof e=="function")try{let n=new e({workspaceRoot:process.cwd()}).emptyState();return n!==null&&typeof n=="object"&&!Array.isArray(n)?n:void 0}catch{return}}function We(e){let t=P(e);return t.kind==="v1"?{value:t.value}:t.kind==="v2"?{value:t.header,body:t.body}:{value:void 0}}function Ye(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)&&typeof e.actionId=="string"?e.actionId:"-"}function v(e){return typeof e!="string"||e.length===0?"-":e.replace(/[\u0000-\u001f\u007f\u2028\u2029]/gu,"_")}function z(e,t,n){let o={code:"EXECUTION_FAILED",detail:null},r={outcome:"failed",errorCode:"EXECUTION_FAILED",state:t.emptyState!==null&&typeof t.emptyState=="object"&&!Array.isArray(t.emptyState)?{...t.emptyState,error:o}:{error:o}},s=r;try{s=(t.sanitize??He)(r);}catch(u){n("EXECUTION_FAILED",u);}e(`${JSON.stringify(s)}
|
|
10
|
+
`);}function He(e){return e}exports.APP_TOOLS_FILE=ge;exports.APP_TOOLS_SCHEMA_VERSION=Ae;exports.APP_TOOL_ENTRY=Ce;exports.AppError=A;exports.CrewXApp=X;exports.SKILL_BACKEND_ENV_NAMES=Q;exports.Tool=ce;exports.executeAppRequest=ve;exports.generateManifest=le;exports.generateToolDeclarations=H;exports.getToolDeclarations=D;exports.isSkillBackendEnv=Oe;exports.readAppContext=B;exports.runAppEntry=Ve;exports.runSkillApp=Je;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export { UI_CONTENT_MEDIA_TYPES } from './content-media-types.js';
|
|
2
|
+
export type { UiContentMediaType } from './content-media-types.js';
|
|
3
|
+
export declare const SKILL_BACKEND_CONTENT_SCHEMA_VERSION: 2;
|
|
4
|
+
export declare const SKILL_BACKEND_MAX_INPUT_BYTES = 524288;
|
|
5
|
+
export declare const SKILL_BACKEND_MAX_OUTPUT_BYTES = 524288;
|
|
6
|
+
export declare const UI_CONTENT_MAX_BYTES: number;
|
|
7
|
+
export declare const UI_CONTENT_MAX_LINES = 20000;
|
|
8
|
+
export declare function sha256Content(bytes: Uint8Array): string;
|
|
9
|
+
export declare function countContentLines(bytes: Uint8Array): number;
|
package/dist/app/runtime.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type AppFailureOutcome, type CrewXAppConstructor, type JsonObject } from './app.js';
|
|
1
|
+
import { type AppContext, type AppFailureOutcome, type CrewXAppConstructor, type JsonObject } from './app.js';
|
|
2
2
|
export interface AppFailureInfo {
|
|
3
3
|
readonly outcome: AppFailureOutcome;
|
|
4
4
|
readonly detail: string | null;
|
|
@@ -11,9 +11,11 @@ export interface RunSkillAppOptions {
|
|
|
11
11
|
readonly emptyState?: JsonObject;
|
|
12
12
|
readonly preloadedInput?: {
|
|
13
13
|
readonly value: unknown;
|
|
14
|
+
readonly body?: Uint8Array;
|
|
14
15
|
};
|
|
15
16
|
readonly onFailure?: (errorCode: string, error?: unknown, info?: AppFailureInfo) => void;
|
|
16
17
|
readonly consoleManaged?: boolean;
|
|
18
|
+
readonly context?: AppContext;
|
|
17
19
|
}
|
|
18
|
-
export declare function executeAppRequest(appClass: CrewXAppConstructor, rawRequest: unknown, workspaceRoot?: string): Promise<JsonObject>;
|
|
20
|
+
export declare function executeAppRequest(appClass: CrewXAppConstructor, rawRequest: unknown, workspaceRoot?: string, context?: AppContext): Promise<JsonObject>;
|
|
19
21
|
export declare function runSkillApp(appClass: CrewXAppConstructor, options?: RunSkillAppOptions): Promise<void>;
|
package/dist/esm/app/index.js
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import {readSync}from'fs';import {
|
|
2
|
-
|
|
3
|
-
`;}catch(
|
|
4
|
-
`;}
|
|
5
|
-
|
|
6
|
-
`),o=
|
|
7
|
-
`),E
|
|
8
|
-
`)
|
|
9
|
-
`);}function
|
|
1
|
+
import {format,inspect}from'util';import {readSync}from'fs';import {createHash}from'crypto';import {Console}from'console';import {Writable}from'stream';var R=["text/plain","application/json"];var H=Symbol;H.metadata===void 0&&Object.defineProperty(Symbol,"metadata",{configurable:false,value:Symbol.for("Symbol.metadata")});var ce=H.metadata,x=Symbol.for("crewx.app.tool-metadata"),A=class extends Error{code;detail;outcome;constructor(t,n=null,o){super(t),this.name="AppError",this.code=t,this.detail=n,this.outcome=B(o?.outcome);}};function B(e){return e==="rejected"?"rejected":"failed"}var q=class{static devtools=process.env.CREWX_APP_DEV==="1"?Object.freeze({log:true}):void 0;currentState;stateWasSet=false;answerBody;answerRange;callContext;workspaceRoot;constructor(t={workspaceRoot:process.cwd()}){this.currentState=t.state??{},this.workspaceRoot=t.workspaceRoot,this.callContext=t.context===void 0?void 0:ye(t.context);}get context(){if(this.callContext===void 0)throw new TypeError("this.context is only set when the Host runs the action; pass options.context when you construct the App in a test");return this.callContext}get state(){return this.currentState}get didSetState(){return this.stateWasSet}setState(t){this.currentState=t,this.stateWasSet=true;}get didSetContent(){return this.answerBody!==void 0}get producedContent(){return this.answerBody===void 0?void 0:{body:this.answerBody,...this.answerRange===void 0?{}:{range:this.answerRange}}}setContent(t,n){if(typeof t!="string"&&!(t instanceof Uint8Array))throw new TypeError("setContent needs a string or a Uint8Array");if(n!==void 0&&!Te(n))throw new TypeError("setContent range must be { startLine, lineCount, totalLines }, three integers of at least 1");this.answerBody=typeof t=="string"?new TextEncoder().encode(t):new Uint8Array(t),this.answerRange=n===void 0?void 0:{startLine:n.startLine,lineCount:n.lineCount,totalLines:n.totalLines};}emptyState(){return {}}validate(t,n,o){}mapError(t){return {code:"EXECUTION_FAILED",detail:null}}errorState(t,n,o){return {...O(o.state)?o.state:{},error:{code:t,detail:n}}}};function le(e){return function(t,n){if(n.static||n.private||n.kind!=="method")throw new TypeError("@Tool can decorate public instance methods only");let o=n.metadata;if(!o)throw new TypeError("standard decorator metadata is unavailable");let i=Object.hasOwn(o,x)?o[x]:[];if(i.some(s=>s.methodName===String(n.name)))throw new TypeError(`@Tool is declared more than once for ${String(n.name)}`);let r=e.content===void 0?void 0:fe(e.name,e.content);o[x]=[...i,{methodName:String(n.name),options:Object.freeze({...e,...r===void 0?{}:{content:r}})}];}}function j(e){let t=e[ce],n=t&&Object.hasOwn(t,x)?t[x]:[],o=new Map(n.map(r=>[r.methodName,r])),i=Object.getOwnPropertyNames(e.prototype).map(r=>o.get(r)).filter(r=>r!==void 0);if(i.length!==n.length)throw new TypeError("a @Tool method is missing from the App prototype");return i}function G(e){let t=e.definition,n=j(e),o=new Set;return n.map(({options:i})=>{if(o.has(i.name))throw new TypeError(`duplicate @Tool name: ${i.name}`);return o.add(i.name),{actionId:i.name,...i.dataInputs===void 0?{}:{dataInputs:[...i.dataInputs]},confirmation:i.confirmation??"none",capability:i.capability??"app.read",mutation:i.mutation??true,inputSchema:i.inputSchema,...i.content===void 0?{}:{content:me(i.content)},resultProjection:i.resultProjection??{allow:[...t.stateProjection.allow]},_meta:{description:i.description}}})}function pe(e,t){if(t.length===0)throw new TypeError("backendCommand must name the skill command");let n=G(e).map(({_meta:o,...i})=>({...i,backend:{type:"skill",command:[...t]},_meta:o}));return {...e.definition,actions:n}}function fe(e,t){let n=r=>{throw new TypeError(`@Tool ${e}: content ${r}`)},o=(r,s,u)=>{if(!O(u))return n(`${r} must be an object`);for(let a of Object.keys(u))if(a==="mediaType"){if(!R.includes(u[a]))return n(`${r}.mediaType must be one of ${R.join(", ")}`)}else if(a===s){if(typeof u[a]!="boolean")return n(`${r}.${a} must be true or false`)}else return n(`${r} has the unknown key "${a}"`);return Object.hasOwn(u,"mediaType")?Object.freeze({...u}):n(`${r}.mediaType is required`)};if(!O(t))return n("must be an object");let i={};for(let r of Object.keys(t))if(r==="in")i[r]=o("in","required",t[r]);else if(r==="out")i[r]=o("out","range",t[r]);else return n(`has the unknown key "${r}"; use "in" and/or "out"`);return Object.keys(i).length===0?n('needs "in" and/or "out"'):Object.freeze(i)}function ye(e){return Object.freeze({instanceId:e.instanceId,threadId:e.threadId,actor:e.actor,requestId:e.requestId,nowMs:e.nowMs})}function me(e){let t={};for(let[n,o]of Object.entries(e))t[n]={...o};return t}function Te(e){return O(e)&&["startLine","lineCount","totalLines"].every(t=>Number.isSafeInteger(e[t])&&e[t]>=1)}function O(e){if(e===null||typeof e!="object"||Array.isArray(e))return false;let t=Object.getPrototypeOf(e);return t===Object.prototype||t===null}var Ee=/^[A-Za-z0-9._:-]{1,128}$/u,ge=/[\u0000-\u001f\u007f\u2028\u2029]/u;function K(e=process.env){let t=Q(e.CREWX_APP_INSTANCE_ID),n=e.CREWX_APP_REQUEST_ID,o=e.CREWX_APP_ACTOR_KIND,i=e.CREWX_APP_NOW_MS;if(t===void 0||typeof n!="string"||!Ee.test(n)||o!=="user"&&o!=="agent"||typeof i!="string"||!/^\d{1,16}$/u.test(i))return;let r=Number(i);if(!Number.isSafeInteger(r))return;let s=e.CREWX_THREAD_ID===void 0?null:Q(e.CREWX_THREAD_ID);if(s!==void 0)return Object.freeze({instanceId:t,threadId:s,actor:o,requestId:n,nowMs:r})}function Q(e){if(!(typeof e!="string"||e.length===0||ge.test(e)))return new TextEncoder().encode(e).byteLength<=512?e:void 0}var Ae="dist/tools.json",Ce=1,Oe="dist/main.mjs";var Z=["CREWX_APP_INSTANCE_ID","CREWX_THREAD_ID"];function we(e){if(!Array.isArray(e)||e.length===0)return false;let t=new Set;for(let n of e){if(!Z.some(o=>o===n)||t.has(n))return false;t.add(n);}return true}var U=2,$=524288;var N=2*1024*1024,L=2e4;function V(e){return createHash("sha256").update(e).digest("hex")}function F(e){if(e.byteLength===0)return 0;let t=0;for(let n of e)n===10&&(t+=1);return e[e.byteLength-1]!==10&&(t+=1),t}var Se=64*1024,Ie=$+1+N,he=64*1024,Re=10,P={kind:"invalid"};function Ne(e,t){try{let n=[],o=0;for(;;){let s=new Uint8Array(he),u=readSync(e,s,0,s.length,null);if(u===0)break;if(o+=u,o>t)return;n.push(s.subarray(0,u));}let i=new Uint8Array(o),r=0;for(let s of n)i.set(s,r),r+=s.byteLength;return i}catch{return}}function M(e){return xe(Ne(e,Ie))}function xe(e){if(e===void 0)return P;let t=e.indexOf(Re);if(e.byteLength<=Se){let o=Fe(Buffer.from(e.buffer,e.byteOffset,e.byteLength).toString("utf8"));if(o.ok&&!(t>=0&&S(o.value)&&o.value.schemaVersion===U))return {kind:"v1",value:o.value}}if(t<=0||t>$)return P;let n;try{n=JSON.parse(new TextDecoder("utf-8",{fatal:!0}).decode(e.subarray(0,t)));}catch{return P}return !S(n)||n.schemaVersion!==U?P:{kind:"v2",header:n,body:e.subarray(t+1)}}var ke="actionId,content,input,schemaVersion,state",De="bytes,lines,mediaType,sha256",je="mediaType,range",Ue=/^[a-f0-9]{64}$/u,Le=new TextDecoder("utf-8",{fatal:true,ignoreBOM:true});function ne(e,t){let n=a=>({code:a,outcome:"rejected"});if(k(e)!==ke||e.schemaVersion!==U||typeof e.actionId!="string"||!S(e.input)||!S(e.state)||!S(e.content)||k(e.content)!=="in,out")return {code:"INPUT_INVALID",outcome:"failed"};let o=e.content,i,r=o.in;if(r===null){if(t.byteLength!==0)return n(t.byteLength>N?"CONTENT_TOO_LARGE":"CONTENT_DIGEST_MISMATCH")}else {if(!S(r)||k(r)!==De||!ee(r.mediaType)||!te(r.bytes,N)||!te(r.lines,L)||typeof r.sha256!="string"||!Ue.test(r.sha256)||t.byteLength!==r.bytes)return n(t.byteLength>N?"CONTENT_TOO_LARGE":"CONTENT_DIGEST_MISMATCH");if(V(t)!==r.sha256||F(t)!==r.lines)return n("CONTENT_DIGEST_MISMATCH");let a;try{a=Le.decode(t);}catch{return n("CONTENT_ENCODING_INVALID")}i={mediaType:r.mediaType,text:a};}let s,u=o.out;if(u!==null){if(!S(u)||k(u)!==je||!ee(u.mediaType))return n("CONTENT_SOURCE_UNSUPPORTED");let a=u.range;if(a!==null&&!Pe(a))return n("CONTENT_SOURCE_UNSUPPORTED");s={mediaType:u.mediaType,...a===null?{}:{range:{startLine:a.startLine,lineCount:a.lineCount}}};}return {actionId:e.actionId,input:e.input,state:e.state,content:{...i===void 0?{}:{in:i},...s===void 0?{}:{out:s}}}}function oe(e){return Object.hasOwn(e,"code")}function re(e,t){let n=o=>({code:o,outcome:"rejected"});if(e?.in===void 0){if(t.in!==void 0)return n("CONTENT_SOURCE_UNSUPPORTED")}else if(t.in===void 0){if(e.in.required===true)return n("CONTENT_REQUIRED")}else if(t.in.mediaType!==e.in.mediaType)return n("CONTENT_SOURCE_UNSUPPORTED");if(e?.out===void 0){if(t.out!==void 0)return n("CONTENT_SOURCE_UNSUPPORTED")}else {if(t.out===void 0)return n("CONTENT_REQUIRED");if(t.out.mediaType!==e.out.mediaType||t.out.range!==void 0&&e.out.range!==true)return n("CONTENT_SOURCE_UNSUPPORTED")}}function v(e,t){let{content:n,...o}=e,i=t===void 0?o:{...o,content:{bytes:t.body.byteLength,lines:F(t.body),sha256:V(t.body),...t.range===void 0?{}:{range:t.range}}},r=new TextEncoder().encode(`${JSON.stringify(i)}
|
|
2
|
+
`);if(t===void 0)return r;let s=new Uint8Array(r.byteLength+t.body.byteLength);return s.set(r,0),s.set(t.body,r.byteLength),s}function ie(e){if(e.body.byteLength>N||F(e.body)>L)return {code:"CONTENT_TOO_LARGE",outcome:"failed"}}function Fe(e){try{return {ok:!0,value:JSON.parse(e)}}catch{return {ok:false}}}function k(e){return Object.keys(e).sort().join(",")}function S(e){if(e===null||typeof e!="object"||Array.isArray(e))return false;let t=Object.getPrototypeOf(e);return t===Object.prototype||t===null}function ee(e){return typeof e=="string"&&R.includes(e)}function te(e,t){return Number.isSafeInteger(e)&&e>=0&&e<=t}function Pe(e){return S(e)&&k(e)==="lineCount,startLine"&&Number.isSafeInteger(e.startLine)&&e.startLine>=1&&Number.isSafeInteger(e.lineCount)&&e.lineCount>=1&&e.lineCount<=L}var ve=1;async function Je(e,t,n=process.env.CREWX_WORKSPACE_ROOT??process.cwd(),o){return (await de(e,t,n,void 0,true,void 0,o)).response}async function de(e,t,n,o,i=true,r,s){let u=r!==void 0,a=O(t)?t:void 0,m=a?.input,T=a?.state,d=new e({state:O(T)?T:{},workspaceRoot:n,...s===void 0?{}:{context:s}}),C=O(m)?m:{},E=O(T)?T:d.emptyState(),y={};try{let c;if(u){if(a===void 0)throw new A("INPUT_INVALID");let f=ne(a,r);if(oe(f))throw new A(f.code,null,{outcome:f.outcome});(({actionId:c,input:C,state:E}=f)),y=f.content;}else {if(!a||Object.keys(a).length!==4||!["schemaVersion","actionId","input","state"].every(f=>Object.hasOwn(a,f))||a.schemaVersion!==ve||typeof a.actionId!="string"||!O(m)||!O(T))throw new A("INPUT_INVALID");c=a.actionId,C=m,E=T;}d=new e({state:E,workspaceRoot:n,...s===void 0?{}:{context:s}}),await d.validate(c,C,E);let l=j(e).find(({options:f})=>f.name===c);if(!l)throw new A("INPUT_INVALID");let g=d[l.methodName];if(typeof g!="function")throw new A("EXECUTION_FAILED");let p=re(l.options.content,y);if(p)throw new A(p.code,null,{outcome:p.outcome});let D=Object.freeze({...y.in===void 0?{}:{in:Object.freeze({text:y.in.text})},...y.out===void 0?{}:{out:Object.freeze(y.out.range===void 0?{}:{range:Object.freeze({...y.out.range})})}}),h=()=>g.call(d,C,D),I=i?await qe(h):await h();if(I!==void 0&&!O(I))throw new A("EXECUTION_FAILED");let b;if(y.out!==void 0){if(b=d.producedContent,b===void 0)throw new A("EXECUTION_FAILED","content.out was requested but setContent was never called");let f=ie(b);if(f)throw new A(f.code,null,{outcome:f.outcome})}else if(d.didSetContent)throw new A("EXECUTION_FAILED","setContent was called but the request asked for no content.out");return {response:{...d.didSetState?{state:d.state}:{},...I===void 0?{}:{result:I}},...b===void 0?{}:{answer:b}}}catch(c){let l,g=c,p=c instanceof A?c:void 0;if(p)l={code:p.code,detail:p.detail,outcome:p.outcome};else try{l=d.mapError(c);}catch(X){l={code:"EXECUTION_FAILED",detail:null},g=X;}let D=Ke(l?.code),h=D?l.code:"EXECUTION_FAILED",I=typeof l?.detail=="string"?l.detail:null,b=D?B(l.outcome):"failed",f;try{f=d.errorState(h,I,{input:C,state:E});}catch(X){g=new AggregateError([g,X],"App error handling failed"),f=d.emptyState();}return o?.(h,g,{outcome:b,detail:I,expected:p!==void 0&&g===p}),{response:{outcome:b,errorCode:h,state:O(f)?f:d.emptyState()}}}}async function Xe(e,t={}){let n=t.output??process.stdout,o,i;if(t.preloadedInput!==void 0)o=t.preloadedInput.value,i=t.preloadedInput.body;else {let d=M(t.inputFd??0);d.kind==="v1"?o=d.value:d.kind==="v2"&&(o=d.header,i=d.body);}let r=i!==void 0,s=t.context??K(),u=false,a=(d,C,E)=>{u=true,t.onFailure?.(d,C,E);},m;try{m=await de(e,o,process.env.CREWX_WORKSPACE_ROOT??process.cwd(),a,t.consoleManaged!==!0,i,s);}catch(d){a("EXECUTION_FAILED",d),m={response:ae(t.emptyState)};}Be(m.response)&&!u&&a(m.response.errorCode,void 0,{outcome:m.response.outcome,detail:null,expected:false});let T;try{let d=(t.sanitize??se)(m.response);T=r?v(d,m.answer):`${JSON.stringify(d)}
|
|
3
|
+
`;}catch(d){a("EXECUTION_FAILED",d);let C=ae(t.emptyState);try{let E=(t.sanitize??se)(C);T=r?v(E):`${JSON.stringify(E)}
|
|
4
|
+
`;}catch(E){a("EXECUTION_FAILED",E),T=r?v(C):`${JSON.stringify(C)}
|
|
5
|
+
`;}}n.write(T);}async function qe(e){let t=["log","info","debug"],n=new Map;for(let o of t)n.set(o,console[o]),console[o]=(...i)=>process.stderr.write(`${format(...i)}
|
|
6
|
+
`);try{return await e()}finally{for(let o of t)console[o]=n.get(o);}}function ae(e={}){return {outcome:"failed",errorCode:"EXECUTION_FAILED",state:{...e,error:{code:"EXECUTION_FAILED",detail:null}}}}function Be(e){return (e.outcome==="failed"||e.outcome==="rejected")&&typeof e.errorCode=="string"}function Ke(e){return typeof e=="string"&&/^[A-Z][A-Z0-9_]{0,127}$/u.test(e)}function se(e){return e}var z={depth:null,maxArrayLength:null,maxStringLength:null},Y=class extends Writable{#e="buffer";#t=[];_write(t,n,o){if(this.#e==="buffer"){this.#t.push(typeof t=="string"?t:Uint8Array.from(t)),o();return}if(this.#e==="discard"){o();return}process.stderr.write(t,o);}flushToStderr(){this.#e="stderr";for(let t of this.#t)process.stderr.write(t);this.#t=[];}discard(){this.#e="discard",this.#t=[];}};async function ze(e,t={}){let n=process.stdout,o=n.write.bind(n),i=new Y,r=new Console({stdout:i,stderr:i,inspectOptions:{...z}});globalThis.console=r;let s=false,u="-",a="-",m,T=false,d,C;try{let c=Ye(t.inputFd??0);u=He(c.value),a=J(process.env.CREWX_APP_REQUEST_ID),m=new Date().toISOString();try{d=await e();}catch(p){T=!0,C=p;}let l=d?.default;if(!T&&l?.devtools?.log===!0?(Object.assign(inspect.defaultOptions,z),E(m),i.flushToStderr()):i.discard(),T){y("EXECUTION_FAILED",C),W(o,t,y);return}try{if(typeof d?.runSkillApp!="function")throw new TypeError("App module does not export runSkillApp");let p={sanitize:t.sanitize,emptyState:t.emptyState??We(l),preloadedInput:c.body===void 0?{value:c.value}:{value:c.value,body:c.body},onFailure:y,consoleManaged:!0,output:{write:o}};await d.runSkillApp(l,p);}catch(p){y("EXECUTION_FAILED",p),W(o,t,y);}}catch(c){y("EXECUTION_FAILED",c),W(o,t,y);}finally{process.exitCode=0;}function E(c){s||(process.stderr.write(`[crewx-app] ${c??new Date().toISOString()} ${J(u)} req=${a}
|
|
7
|
+
`),s=true);}function y(c,l,g){E();let p=g?.expected===true&&g.detail?` ${J(g.detail)}`:"";process.stderr.write(`[crewx-app] ${g?.outcome??"failed"} ${J(c)}${p}
|
|
8
|
+
`),l!==void 0&&g?.expected!==true&&process.stderr.write(`${inspect(l,z)}
|
|
9
|
+
`);}}function We(e){if(typeof e=="function")try{let n=new e({workspaceRoot:process.cwd()}).emptyState();return n!==null&&typeof n=="object"&&!Array.isArray(n)?n:void 0}catch{return}}function Ye(e){let t=M(e);return t.kind==="v1"?{value:t.value}:t.kind==="v2"?{value:t.header,body:t.body}:{value:void 0}}function He(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)&&typeof e.actionId=="string"?e.actionId:"-"}function J(e){return typeof e!="string"||e.length===0?"-":e.replace(/[\u0000-\u001f\u007f\u2028\u2029]/gu,"_")}function W(e,t,n){let o={code:"EXECUTION_FAILED",detail:null},r={outcome:"failed",errorCode:"EXECUTION_FAILED",state:t.emptyState!==null&&typeof t.emptyState=="object"&&!Array.isArray(t.emptyState)?{...t.emptyState,error:o}:{error:o}},s=r;try{s=(t.sanitize??Ge)(r);}catch(u){n("EXECUTION_FAILED",u);}e(`${JSON.stringify(s)}
|
|
10
|
+
`);}function Ge(e){return e}export{Ae as APP_TOOLS_FILE,Ce as APP_TOOLS_SCHEMA_VERSION,Oe as APP_TOOL_ENTRY,A as AppError,q as CrewXApp,Z as SKILL_BACKEND_ENV_NAMES,le as Tool,Je as executeAppRequest,pe as generateManifest,G as generateToolDeclarations,j as getToolDeclarations,we as isSkillBackendEnv,K as readAppContext,ze as runAppEntry,Xe as runSkillApp};
|