deepclause-sdk 0.0.64 → 0.0.66
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/README.md +114 -6
- package/dist/agent.d.ts.map +1 -1
- package/dist/agent.js +131 -30
- package/dist/agent.js.map +1 -1
- package/dist/cli/commands.d.ts +5 -0
- package/dist/cli/commands.d.ts.map +1 -1
- package/dist/cli/commands.js +75 -5
- package/dist/cli/commands.js.map +1 -1
- package/dist/cli/compile.d.ts +3 -0
- package/dist/cli/compile.d.ts.map +1 -1
- package/dist/cli/compile.js.map +1 -1
- package/dist/cli/config.d.ts.map +1 -1
- package/dist/cli/config.js +31 -2
- package/dist/cli/config.js.map +1 -1
- package/dist/cli/index.js +34 -7
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/tui.d.ts +9 -0
- package/dist/cli/tui.d.ts.map +1 -1
- package/dist/cli/tui.js +100 -30
- package/dist/cli/tui.js.map +1 -1
- package/dist/compiler.d.ts.map +1 -1
- package/dist/compiler.js +6 -8
- package/dist/compiler.js.map +1 -1
- package/dist/compiler_prompt.d.ts +1 -1
- package/dist/compiler_prompt.d.ts.map +1 -1
- package/dist/compiler_prompt.js +4 -2
- package/dist/compiler_prompt.js.map +1 -1
- package/dist/prolog/bridge.d.ts +10 -1
- package/dist/prolog/bridge.d.ts.map +1 -1
- package/dist/prolog/bridge.js +26 -1
- package/dist/prolog/bridge.js.map +1 -1
- package/dist/prolog-src/deepclause_mi.pl +40 -2
- package/dist/runner.d.ts +2 -1
- package/dist/runner.d.ts.map +1 -1
- package/dist/runner.js +19 -16
- package/dist/runner.js.map +1 -1
- package/dist/system/assets/docs/CONDUCTOR_PROMPT.md +39 -5
- package/dist/system/assets/docs/DML_COMPILER_PROMPT.md +37 -5
- package/dist/system/assets/index.d.ts +2 -0
- package/dist/system/assets/index.d.ts.map +1 -1
- package/dist/system/assets/index.js +7 -0
- package/dist/system/assets/index.js.map +1 -1
- package/dist/system/assets/recipes/deepclause-coding-workflow/SKILL.md +45 -0
- package/dist/system/assets/skills/conductor.dml +20 -14
- package/dist/system/assets/skills/skill-creator.dml +1 -0
- package/dist/system/runtime/catalog-recipes.d.ts +24 -0
- package/dist/system/runtime/catalog-recipes.d.ts.map +1 -0
- package/dist/system/runtime/catalog-recipes.js +273 -0
- package/dist/system/runtime/catalog-recipes.js.map +1 -0
- package/dist/system/runtime/catalog-skills.d.ts +6 -1
- package/dist/system/runtime/catalog-skills.d.ts.map +1 -1
- package/dist/system/runtime/catalog-skills.js +28 -0
- package/dist/system/runtime/catalog-skills.js.map +1 -1
- package/dist/system/runtime/conductor.d.ts +29 -0
- package/dist/system/runtime/conductor.d.ts.map +1 -1
- package/dist/system/runtime/conductor.js +199 -59
- package/dist/system/runtime/conductor.js.map +1 -1
- package/dist/system/runtime/runtime-tools.d.ts +6 -0
- package/dist/system/runtime/runtime-tools.d.ts.map +1 -1
- package/dist/system/runtime/runtime-tools.js +26 -1
- package/dist/system/runtime/runtime-tools.js.map +1 -1
- package/dist/system/runtime/shell-manager.d.ts.map +1 -1
- package/dist/system/runtime/shell-manager.js +112 -29
- package/dist/system/runtime/shell-manager.js.map +1 -1
- package/dist/system/runtime/skill-creator.d.ts +2 -0
- package/dist/system/runtime/skill-creator.d.ts.map +1 -1
- package/dist/system/runtime/skill-creator.js +199 -15
- package/dist/system/runtime/skill-creator.js.map +1 -1
- package/package.json +2 -2
- package/src/prolog-src/deepclause_mi.pl +40 -2
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { spawn } from 'child_process';
|
|
2
2
|
import { AgentVMManager, } from './agentvm-manager.js';
|
|
3
3
|
const ABORT_FORCE_KILL_MS = 500;
|
|
4
|
+
const EXIT_STDIO_GRACE_MS = 25;
|
|
5
|
+
const DEFAULT_HOST_SHELL_IDLE_TIMEOUT_MS = 180_000;
|
|
4
6
|
export class HostShellManager {
|
|
5
7
|
workspacePath;
|
|
6
8
|
kind = 'host';
|
|
@@ -12,6 +14,7 @@ export class HostShellManager {
|
|
|
12
14
|
throw abortError(signal.reason);
|
|
13
15
|
}
|
|
14
16
|
return new Promise((resolve, reject) => {
|
|
17
|
+
const idleTimeoutMs = getHostShellIdleTimeoutMs();
|
|
15
18
|
const child = spawn('bash', ['-lc', command], {
|
|
16
19
|
cwd: this.workspacePath,
|
|
17
20
|
env: process.env,
|
|
@@ -24,10 +27,43 @@ export class HostShellManager {
|
|
|
24
27
|
});
|
|
25
28
|
let stdout = '';
|
|
26
29
|
let stderr = '';
|
|
30
|
+
let exitCode = null;
|
|
31
|
+
let exitSignal = null;
|
|
32
|
+
let timedOut = false;
|
|
33
|
+
let idleTimer = null;
|
|
34
|
+
const resetIdleTimer = () => {
|
|
35
|
+
if (idleTimeoutMs <= 0 || settled || timedOut) {
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
if (idleTimer) {
|
|
39
|
+
clearTimeout(idleTimer);
|
|
40
|
+
}
|
|
41
|
+
idleTimer = setTimeout(() => {
|
|
42
|
+
if (settled || signal?.aborted) {
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
timedOut = true;
|
|
46
|
+
exitCode = 124;
|
|
47
|
+
stderr = stderr
|
|
48
|
+
? `${stderr}${stderr.endsWith('\n') ? '' : '\n'}Command timed out after ${idleTimeoutMs}ms without output`
|
|
49
|
+
: `Command timed out after ${idleTimeoutMs}ms without output`;
|
|
50
|
+
terminateChildProcessTree(child, 'SIGTERM');
|
|
51
|
+
if (!forceKillTimer) {
|
|
52
|
+
forceKillTimer = setTimeout(() => {
|
|
53
|
+
if (child.exitCode === null && child.signalCode === null) {
|
|
54
|
+
terminateChildProcessTree(child, 'SIGKILL');
|
|
55
|
+
}
|
|
56
|
+
}, ABORT_FORCE_KILL_MS);
|
|
57
|
+
forceKillTimer.unref?.();
|
|
58
|
+
}
|
|
59
|
+
}, idleTimeoutMs);
|
|
60
|
+
idleTimer.unref?.();
|
|
61
|
+
};
|
|
27
62
|
child.stdout.setEncoding('utf8');
|
|
28
63
|
child.stderr.setEncoding('utf8');
|
|
29
64
|
child.stdout.on('data', (chunk) => {
|
|
30
65
|
stdout += chunk;
|
|
66
|
+
resetIdleTimer();
|
|
31
67
|
observer?.onStdout?.({
|
|
32
68
|
command,
|
|
33
69
|
chunk,
|
|
@@ -37,6 +73,7 @@ export class HostShellManager {
|
|
|
37
73
|
});
|
|
38
74
|
child.stderr.on('data', (chunk) => {
|
|
39
75
|
stderr += chunk;
|
|
76
|
+
resetIdleTimer();
|
|
40
77
|
observer?.onStderr?.({
|
|
41
78
|
command,
|
|
42
79
|
chunk,
|
|
@@ -45,7 +82,44 @@ export class HostShellManager {
|
|
|
45
82
|
});
|
|
46
83
|
});
|
|
47
84
|
let forceKillTimer = null;
|
|
85
|
+
let exitGraceTimer = null;
|
|
48
86
|
let settled = false;
|
|
87
|
+
const maybeDestroyStreams = () => {
|
|
88
|
+
child.stdout.destroy?.();
|
|
89
|
+
child.stderr.destroy?.();
|
|
90
|
+
};
|
|
91
|
+
const buildResult = () => {
|
|
92
|
+
const resolvedExitCode = typeof exitCode === 'number'
|
|
93
|
+
? exitCode
|
|
94
|
+
: (timedOut ? 124 : 1);
|
|
95
|
+
const signalSuffix = exitSignal ? ` (signal ${exitSignal})` : '';
|
|
96
|
+
return {
|
|
97
|
+
success: resolvedExitCode === 0,
|
|
98
|
+
stdout,
|
|
99
|
+
stderr,
|
|
100
|
+
exitCode: resolvedExitCode,
|
|
101
|
+
pid: child.pid,
|
|
102
|
+
backend: this.kind,
|
|
103
|
+
summary: resolvedExitCode === 0
|
|
104
|
+
? 'Command completed successfully'
|
|
105
|
+
: (timedOut ? `Command timed out after ${idleTimeoutMs}ms without output` : (stderr || `Command failed with exit code ${resolvedExitCode}${signalSuffix}`)),
|
|
106
|
+
};
|
|
107
|
+
};
|
|
108
|
+
const finalizeExit = (detachStreams = false) => {
|
|
109
|
+
if (detachStreams) {
|
|
110
|
+
maybeDestroyStreams();
|
|
111
|
+
}
|
|
112
|
+
const result = buildResult();
|
|
113
|
+
observer?.onExit?.({
|
|
114
|
+
command,
|
|
115
|
+
pid: child.pid,
|
|
116
|
+
backend: this.kind,
|
|
117
|
+
success: result.success,
|
|
118
|
+
exitCode: result.exitCode,
|
|
119
|
+
summary: result.summary,
|
|
120
|
+
});
|
|
121
|
+
finalizeResolve(result);
|
|
122
|
+
};
|
|
49
123
|
const finalizeReject = (error) => {
|
|
50
124
|
if (settled) {
|
|
51
125
|
return;
|
|
@@ -76,50 +150,49 @@ export class HostShellManager {
|
|
|
76
150
|
};
|
|
77
151
|
const cleanup = () => {
|
|
78
152
|
signal?.removeEventListener('abort', onAbort);
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
153
|
+
if (idleTimer) {
|
|
154
|
+
clearTimeout(idleTimer);
|
|
155
|
+
idleTimer = null;
|
|
156
|
+
}
|
|
82
157
|
if (forceKillTimer) {
|
|
83
158
|
clearTimeout(forceKillTimer);
|
|
84
159
|
forceKillTimer = null;
|
|
85
160
|
}
|
|
161
|
+
if (exitGraceTimer) {
|
|
162
|
+
clearTimeout(exitGraceTimer);
|
|
163
|
+
exitGraceTimer = null;
|
|
164
|
+
}
|
|
165
|
+
};
|
|
166
|
+
signal?.addEventListener('abort', onAbort, { once: true });
|
|
167
|
+
resetIdleTimer();
|
|
168
|
+
child.once('error', (error) => {
|
|
86
169
|
if (signal?.aborted) {
|
|
87
170
|
finalizeReject(abortError(signal.reason));
|
|
88
171
|
return;
|
|
89
172
|
}
|
|
90
173
|
finalizeReject(error);
|
|
91
174
|
});
|
|
92
|
-
child.once('
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
175
|
+
child.once('exit', (code, closeSignal) => {
|
|
176
|
+
exitCode = typeof code === 'number' ? code : 1;
|
|
177
|
+
exitSignal = closeSignal;
|
|
178
|
+
if (signal?.aborted || settled) {
|
|
179
|
+
return;
|
|
96
180
|
}
|
|
181
|
+
exitGraceTimer = setTimeout(() => {
|
|
182
|
+
if (!settled) {
|
|
183
|
+
finalizeExit(true);
|
|
184
|
+
}
|
|
185
|
+
}, EXIT_STDIO_GRACE_MS);
|
|
186
|
+
exitGraceTimer.unref?.();
|
|
187
|
+
});
|
|
188
|
+
child.once('close', (code, closeSignal) => {
|
|
189
|
+
exitCode = typeof code === 'number' ? code : (exitCode ?? 1);
|
|
190
|
+
exitSignal = closeSignal ?? exitSignal;
|
|
97
191
|
if (signal?.aborted) {
|
|
98
192
|
finalizeReject(abortError(signal.reason));
|
|
99
193
|
return;
|
|
100
194
|
}
|
|
101
|
-
|
|
102
|
-
const signalSuffix = closeSignal ? ` (signal ${closeSignal})` : '';
|
|
103
|
-
const result = {
|
|
104
|
-
success: exitCode === 0,
|
|
105
|
-
stdout,
|
|
106
|
-
stderr,
|
|
107
|
-
exitCode,
|
|
108
|
-
pid: child.pid,
|
|
109
|
-
backend: this.kind,
|
|
110
|
-
summary: exitCode === 0
|
|
111
|
-
? 'Command completed successfully'
|
|
112
|
-
: (stderr || `Command failed with exit code ${exitCode}${signalSuffix}`),
|
|
113
|
-
};
|
|
114
|
-
observer?.onExit?.({
|
|
115
|
-
command,
|
|
116
|
-
pid: child.pid,
|
|
117
|
-
backend: this.kind,
|
|
118
|
-
success: result.success,
|
|
119
|
-
exitCode,
|
|
120
|
-
summary: result.summary,
|
|
121
|
-
});
|
|
122
|
-
finalizeResolve(result);
|
|
195
|
+
finalizeExit(false);
|
|
123
196
|
});
|
|
124
197
|
});
|
|
125
198
|
}
|
|
@@ -133,6 +206,16 @@ export function createShellManager(options) {
|
|
|
133
206
|
}
|
|
134
207
|
return new HostShellManager(options.workspacePath);
|
|
135
208
|
}
|
|
209
|
+
function getHostShellIdleTimeoutMs() {
|
|
210
|
+
const raw = process.env.DC_HOST_SHELL_IDLE_TIMEOUT_MS;
|
|
211
|
+
if (raw != null) {
|
|
212
|
+
const parsed = Number.parseInt(raw, 10);
|
|
213
|
+
if (Number.isFinite(parsed) && parsed >= 0) {
|
|
214
|
+
return parsed;
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
return DEFAULT_HOST_SHELL_IDLE_TIMEOUT_MS;
|
|
218
|
+
}
|
|
136
219
|
function abortError(reason) {
|
|
137
220
|
return reason instanceof Error
|
|
138
221
|
? reason
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shell-manager.js","sourceRoot":"","sources":["../../../src/system/runtime/shell-manager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAqB,MAAM,eAAe,CAAC;AACzD,OAAO,EACL,cAAc,GAGf,MAAM,sBAAsB,CAAC;AAE9B,MAAM,mBAAmB,GAAG,GAAG,CAAC;
|
|
1
|
+
{"version":3,"file":"shell-manager.js","sourceRoot":"","sources":["../../../src/system/runtime/shell-manager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAqB,MAAM,eAAe,CAAC;AACzD,OAAO,EACL,cAAc,GAGf,MAAM,sBAAsB,CAAC;AAE9B,MAAM,mBAAmB,GAAG,GAAG,CAAC;AAChC,MAAM,mBAAmB,GAAG,EAAE,CAAC;AAC/B,MAAM,kCAAkC,GAAG,OAAO,CAAC;AAcnD,MAAM,OAAO,gBAAgB;IAGE;IAFpB,IAAI,GAAG,MAAe,CAAC;IAEhC,YAA6B,aAAqB;QAArB,kBAAa,GAAb,aAAa,CAAQ;IAAG,CAAC;IAEtD,KAAK,CAAC,IAAI,CACR,OAAe,EACf,MAAoB,EACpB,QAA4B;QAE5B,IAAI,MAAM,EAAE,OAAO,EAAE,CAAC;YACpB,MAAM,UAAU,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QAClC,CAAC;QAED,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YACrC,MAAM,aAAa,GAAG,yBAAyB,EAAE,CAAC;YAClD,MAAM,KAAK,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,OAAO,CAAC,EAAE;gBAC5C,GAAG,EAAE,IAAI,CAAC,aAAa;gBACvB,GAAG,EAAE,OAAO,CAAC,GAAG;gBAChB,QAAQ,EAAE,OAAO,CAAC,QAAQ,KAAK,OAAO;aACvC,CAAC,CAAC;YAEH,QAAQ,EAAE,OAAO,EAAE,CAAC;gBAClB,OAAO;gBACP,GAAG,EAAE,KAAK,CAAC,GAAG;gBACd,OAAO,EAAE,IAAI,CAAC,IAAI;aACnB,CAAC,CAAC;YAEH,IAAI,MAAM,GAAG,EAAE,CAAC;YAChB,IAAI,MAAM,GAAG,EAAE,CAAC;YAChB,IAAI,QAAQ,GAAkB,IAAI,CAAC;YACnC,IAAI,UAAU,GAA0B,IAAI,CAAC;YAC7C,IAAI,QAAQ,GAAG,KAAK,CAAC;YACrB,IAAI,SAAS,GAAyC,IAAI,CAAC;YAE3D,MAAM,cAAc,GAAG,GAAG,EAAE;gBAC1B,IAAI,aAAa,IAAI,CAAC,IAAI,OAAO,IAAI,QAAQ,EAAE,CAAC;oBAC9C,OAAO;gBACT,CAAC;gBACD,IAAI,SAAS,EAAE,CAAC;oBACd,YAAY,CAAC,SAAS,CAAC,CAAC;gBAC1B,CAAC;gBACD,SAAS,GAAG,UAAU,CAAC,GAAG,EAAE;oBAC1B,IAAI,OAAO,IAAI,MAAM,EAAE,OAAO,EAAE,CAAC;wBAC/B,OAAO;oBACT,CAAC;oBAED,QAAQ,GAAG,IAAI,CAAC;oBAChB,QAAQ,GAAG,GAAG,CAAC;oBACf,MAAM,GAAG,MAAM;wBACb,CAAC,CAAC,GAAG,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,2BAA2B,aAAa,mBAAmB;wBAC1G,CAAC,CAAC,2BAA2B,aAAa,mBAAmB,CAAC;oBAEhE,yBAAyB,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;oBAC5C,IAAI,CAAC,cAAc,EAAE,CAAC;wBACpB,cAAc,GAAG,UAAU,CAAC,GAAG,EAAE;4BAC/B,IAAI,KAAK,CAAC,QAAQ,KAAK,IAAI,IAAI,KAAK,CAAC,UAAU,KAAK,IAAI,EAAE,CAAC;gCACzD,yBAAyB,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;4BAC9C,CAAC;wBACH,CAAC,EAAE,mBAAmB,CAAC,CAAC;wBACxB,cAAc,CAAC,KAAK,EAAE,EAAE,CAAC;oBAC3B,CAAC;gBACH,CAAC,EAAE,aAAa,CAAC,CAAC;gBAClB,SAAS,CAAC,KAAK,EAAE,EAAE,CAAC;YACtB,CAAC,CAAC;YAEF,KAAK,CAAC,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;YACjC,KAAK,CAAC,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;YACjC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,EAAE;gBAChC,MAAM,IAAI,KAAK,CAAC;gBAChB,cAAc,EAAE,CAAC;gBACjB,QAAQ,EAAE,QAAQ,EAAE,CAAC;oBACnB,OAAO;oBACP,KAAK;oBACL,GAAG,EAAE,KAAK,CAAC,GAAG;oBACd,OAAO,EAAE,IAAI,CAAC,IAAI;iBACnB,CAAC,CAAC;YACL,CAAC,CAAC,CAAC;YACH,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,EAAE;gBAChC,MAAM,IAAI,KAAK,CAAC;gBAChB,cAAc,EAAE,CAAC;gBACjB,QAAQ,EAAE,QAAQ,EAAE,CAAC;oBACnB,OAAO;oBACP,KAAK;oBACL,GAAG,EAAE,KAAK,CAAC,GAAG;oBACd,OAAO,EAAE,IAAI,CAAC,IAAI;iBACnB,CAAC,CAAC;YACL,CAAC,CAAC,CAAC;YAEH,IAAI,cAAc,GAAyC,IAAI,CAAC;YAChE,IAAI,cAAc,GAAyC,IAAI,CAAC;YAChE,IAAI,OAAO,GAAG,KAAK,CAAC;YACpB,MAAM,mBAAmB,GAAG,GAAG,EAAE;gBAC/B,KAAK,CAAC,MAAM,CAAC,OAAO,EAAE,EAAE,CAAC;gBACzB,KAAK,CAAC,MAAM,CAAC,OAAO,EAAE,EAAE,CAAC;YAC3B,CAAC,CAAC;YACF,MAAM,WAAW,GAAG,GAAoB,EAAE;gBACxC,MAAM,gBAAgB,GAAG,OAAO,QAAQ,KAAK,QAAQ;oBACnD,CAAC,CAAC,QAAQ;oBACV,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;gBACzB,MAAM,YAAY,GAAG,UAAU,CAAC,CAAC,CAAC,YAAY,UAAU,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;gBACjE,OAAO;oBACL,OAAO,EAAE,gBAAgB,KAAK,CAAC;oBAC/B,MAAM;oBACN,MAAM;oBACN,QAAQ,EAAE,gBAAgB;oBAC1B,GAAG,EAAE,KAAK,CAAC,GAAG;oBACd,OAAO,EAAE,IAAI,CAAC,IAAI;oBAClB,OAAO,EAAE,gBAAgB,KAAK,CAAC;wBAC7B,CAAC,CAAC,gCAAgC;wBAClC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,2BAA2B,aAAa,mBAAmB,CAAC,CAAC,CAAC,CAAC,MAAM,IAAI,iCAAiC,gBAAgB,GAAG,YAAY,EAAE,CAAC,CAAC;iBAC9J,CAAC;YACJ,CAAC,CAAC;YACF,MAAM,YAAY,GAAG,CAAC,aAAa,GAAG,KAAK,EAAE,EAAE;gBAC7C,IAAI,aAAa,EAAE,CAAC;oBAClB,mBAAmB,EAAE,CAAC;gBACxB,CAAC;gBACD,MAAM,MAAM,GAAG,WAAW,EAAE,CAAC;gBAC7B,QAAQ,EAAE,MAAM,EAAE,CAAC;oBACjB,OAAO;oBACP,GAAG,EAAE,KAAK,CAAC,GAAG;oBACd,OAAO,EAAE,IAAI,CAAC,IAAI;oBAClB,OAAO,EAAE,MAAM,CAAC,OAAO;oBACvB,QAAQ,EAAE,MAAM,CAAC,QAAQ;oBACzB,OAAO,EAAE,MAAM,CAAC,OAAO;iBACxB,CAAC,CAAC;gBACH,eAAe,CAAC,MAAM,CAAC,CAAC;YAC1B,CAAC,CAAC;YACF,MAAM,cAAc,GAAG,CAAC,KAAc,EAAE,EAAE;gBACxC,IAAI,OAAO,EAAE,CAAC;oBACZ,OAAO;gBACT,CAAC;gBACD,OAAO,GAAG,IAAI,CAAC;gBACf,OAAO,EAAE,CAAC;gBACV,MAAM,CAAC,KAAK,CAAC,CAAC;YAChB,CAAC,CAAC;YACF,MAAM,eAAe,GAAG,CAAC,MAAuB,EAAE,EAAE;gBAClD,IAAI,OAAO,EAAE,CAAC;oBACZ,OAAO;gBACT,CAAC;gBACD,OAAO,GAAG,IAAI,CAAC;gBACf,OAAO,EAAE,CAAC;gBACV,OAAO,CAAC,MAAM,CAAC,CAAC;YAClB,CAAC,CAAC;YAEF,MAAM,OAAO,GAAG,GAAG,EAAE;gBACnB,yBAAyB,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;gBAC5C,IAAI,CAAC,cAAc,EAAE,CAAC;oBACpB,cAAc,GAAG,UAAU,CAAC,GAAG,EAAE;wBAC/B,IAAI,KAAK,CAAC,QAAQ,KAAK,IAAI,IAAI,KAAK,CAAC,UAAU,KAAK,IAAI,EAAE,CAAC;4BACzD,yBAAyB,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;wBAC9C,CAAC;oBACH,CAAC,EAAE,mBAAmB,CAAC,CAAC;oBACxB,cAAc,CAAC,KAAK,EAAE,EAAE,CAAC;gBAC3B,CAAC;gBAED,cAAc,CAAC,UAAU,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;YAC7C,CAAC,CAAC;YACF,MAAM,OAAO,GAAG,GAAG,EAAE;gBACnB,MAAM,EAAE,mBAAmB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;gBAC9C,IAAI,SAAS,EAAE,CAAC;oBACd,YAAY,CAAC,SAAS,CAAC,CAAC;oBACxB,SAAS,GAAG,IAAI,CAAC;gBACnB,CAAC;gBACD,IAAI,cAAc,EAAE,CAAC;oBACnB,YAAY,CAAC,cAAc,CAAC,CAAC;oBAC7B,cAAc,GAAG,IAAI,CAAC;gBACxB,CAAC;gBACD,IAAI,cAAc,EAAE,CAAC;oBACnB,YAAY,CAAC,cAAc,CAAC,CAAC;oBAC7B,cAAc,GAAG,IAAI,CAAC;gBACxB,CAAC;YACH,CAAC,CAAC;YACF,MAAM,EAAE,gBAAgB,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;YAC3D,cAAc,EAAE,CAAC;YAEjB,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE;gBAC5B,IAAI,MAAM,EAAE,OAAO,EAAE,CAAC;oBACpB,cAAc,CAAC,UAAU,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;oBAC1C,OAAO;gBACT,CAAC;gBACD,cAAc,CAAC,KAAK,CAAC,CAAC;YACxB,CAAC,CAAC,CAAC;YACH,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,WAAW,EAAE,EAAE;gBACvC,QAAQ,GAAG,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;gBAC/C,UAAU,GAAG,WAAW,CAAC;gBAEzB,IAAI,MAAM,EAAE,OAAO,IAAI,OAAO,EAAE,CAAC;oBAC/B,OAAO;gBACT,CAAC;gBAED,cAAc,GAAG,UAAU,CAAC,GAAG,EAAE;oBAC/B,IAAI,CAAC,OAAO,EAAE,CAAC;wBACb,YAAY,CAAC,IAAI,CAAC,CAAC;oBACrB,CAAC;gBACH,CAAC,EAAE,mBAAmB,CAAC,CAAC;gBACxB,cAAc,CAAC,KAAK,EAAE,EAAE,CAAC;YAC3B,CAAC,CAAC,CAAC;YACH,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,WAAW,EAAE,EAAE;gBACxC,QAAQ,GAAG,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,QAAQ,IAAI,CAAC,CAAC,CAAC;gBAC7D,UAAU,GAAG,WAAW,IAAI,UAAU,CAAC;gBACvC,IAAI,MAAM,EAAE,OAAO,EAAE,CAAC;oBACpB,cAAc,CAAC,UAAU,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;oBAC1C,OAAO;gBACT,CAAC;gBACD,YAAY,CAAC,KAAK,CAAC,CAAC;YACtB,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,OAAO;QACX,8DAA8D;IAChE,CAAC;CACF;AAED,MAAM,UAAU,kBAAkB,CAAC,OAAkC;IACnE,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;QACpB,OAAO,IAAI,cAAc,CAAC,OAAO,CAAC,aAAa,EAAE,OAAO,CAAC,OAAO,IAAI,KAAK,CAAC,CAAC;IAC7E,CAAC;IAED,OAAO,IAAI,gBAAgB,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC;AACrD,CAAC;AAED,SAAS,yBAAyB;IAChC,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,6BAA6B,CAAC;IACtD,IAAI,GAAG,IAAI,IAAI,EAAE,CAAC;QAChB,MAAM,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;QACxC,IAAI,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,MAAM,IAAI,CAAC,EAAE,CAAC;YAC3C,OAAO,MAAM,CAAC;QAChB,CAAC;IACH,CAAC;IACD,OAAO,kCAAkC,CAAC;AAC5C,CAAC;AAED,SAAS,UAAU,CAAC,MAAe;IACjC,OAAO,MAAM,YAAY,KAAK;QAC5B,CAAC,CAAC,MAAM;QACR,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,4BAA4B,CAAC,EAAE,EAAE,IAAI,EAAE,YAAY,EAAE,CAAC,CAAC;AACrF,CAAC;AAED,SAAS,yBAAyB,CAAC,KAAmB,EAAE,MAAsB;IAC5E,IAAI,OAAO,KAAK,CAAC,GAAG,KAAK,QAAQ,IAAI,KAAK,CAAC,GAAG,IAAI,CAAC,EAAE,CAAC;QACpD,OAAO;IACT,CAAC;IAED,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;QACjC,IAAI,CAAC;YACH,OAAO,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;YACjC,OAAO;QACT,CAAC;QAAC,MAAM,CAAC;YACP,qEAAqE;QACvE,CAAC;IACH,CAAC;IAED,IAAI,CAAC;QACH,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACrB,CAAC;IAAC,MAAM,CAAC;QACP,gDAAgD;IAClD,CAAC;AACH,CAAC"}
|
|
@@ -33,4 +33,6 @@ export interface SkillCreatorCompileResult {
|
|
|
33
33
|
usageByModel: TokenUsageByModel;
|
|
34
34
|
}
|
|
35
35
|
export declare function compileWithSkillCreator(markdown: string, options: SkillCreatorCompileOptions): Promise<SkillCreatorCompileResult>;
|
|
36
|
+
export declare function normalizeSkillSlug(value: string, fallback?: string): string;
|
|
37
|
+
export declare function deriveSkillSlugFromMarkdown(markdown: string, fallbackBaseName?: string): string;
|
|
36
38
|
//# sourceMappingURL=skill-creator.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"skill-creator.d.ts","sourceRoot":"","sources":["../../../src/system/runtime/skill-creator.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,cAAc,EAAE,QAAQ,EAAiB,MAAM,gBAAgB,CAAC;AAG9E,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAClD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;
|
|
1
|
+
{"version":3,"file":"skill-creator.d.ts","sourceRoot":"","sources":["../../../src/system/runtime/skill-creator.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,cAAc,EAAE,QAAQ,EAAiB,MAAM,gBAAgB,CAAC;AAG9E,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAClD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAQpE,OAAO,EAAoB,KAAK,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAS5E,MAAM,WAAW,0BAA0B;IACzC,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,aAAa,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,gBAAgB,EAAE,mBAAmB,CAAC;IACtC,YAAY,EAAE,mBAAmB,CAAC;IAClC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,WAAW,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IAClD,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,QAAQ,KAAK,IAAI,CAAC;CACrC;AAED,MAAM,WAAW,yBAAyB;IACxC,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,QAAQ,CAAC;IACf,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,cAAc,CAAC;IACzB,YAAY,EAAE,iBAAiB,CAAC;CACjC;AAeD,wBAAsB,uBAAuB,CAC3C,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,0BAA0B,GAClC,OAAO,CAAC,yBAAyB,CAAC,CAYpC;AA2ZD,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,SAAU,GAAG,MAAM,CAsB5E;AAWD,wBAAgB,2BAA2B,CAAC,QAAQ,EAAE,MAAM,EAAE,gBAAgB,SAAU,GAAG,MAAM,CAahG"}
|
|
@@ -8,6 +8,7 @@ import { readSystemPromptAsset, readSystemSkillAsset } from '../assets/index.js'
|
|
|
8
8
|
import { listLocalSkillCatalog } from './catalog-skills.js';
|
|
9
9
|
import { withCapturedConsole } from './console-capture.js';
|
|
10
10
|
import { executeDml } from './dml-executor.js';
|
|
11
|
+
import { truncateUrlFetchTextBody } from './runtime-tools.js';
|
|
11
12
|
import { createShellManager } from './shell-manager.js';
|
|
12
13
|
import { createShellToolEventBridge } from './shell-tool-events.js';
|
|
13
14
|
import { recordTokenUsage } from './token-usage.js';
|
|
@@ -264,7 +265,7 @@ function registerSkillCreatorTools(sdk, context) {
|
|
|
264
265
|
context.onPublish(published);
|
|
265
266
|
return {
|
|
266
267
|
ok: true,
|
|
267
|
-
slug:
|
|
268
|
+
slug: published.slug,
|
|
268
269
|
version: published.meta.history.length,
|
|
269
270
|
};
|
|
270
271
|
},
|
|
@@ -281,7 +282,7 @@ async function buildSkillCreatorSystemPrompt(workspaceRoot, config, compileSelec
|
|
|
281
282
|
'## LLM Access from Scripts',
|
|
282
283
|
'',
|
|
283
284
|
'The local CLI runtime does not provide an extra proxy-only script API.',
|
|
284
|
-
'Use DML task()/prompt()
|
|
285
|
+
'Use DML task()/prompt() when the skill needs open-ended LLM reasoning or text generation. Deterministic or simple skills can be pure Prolog plus exec()/consult() with no task() at all.',
|
|
285
286
|
`The compile slot currently resolves to \`${compileSelection.id}\`.`,
|
|
286
287
|
].join('\n');
|
|
287
288
|
const runtimeSection = sandbox
|
|
@@ -318,6 +319,11 @@ async function buildSkillCreatorSystemPrompt(workspaceRoot, config, compileSelec
|
|
|
318
319
|
## File-Based DML Only
|
|
319
320
|
validate_dml, test_dml, and deploy_skill only accept file paths. Write the DML to disk first.
|
|
320
321
|
|
|
322
|
+
## Deterministic Skills
|
|
323
|
+
- It is fine for a skill to use no task()/prompt() when the workflow is mostly deterministic or simple.
|
|
324
|
+
- In those cases, prefer direct Prolog predicates, consult/use_module, and exec() calls.
|
|
325
|
+
- Add task()/prompt() only when the skill needs open-ended reasoning, extraction, summarization, classification, or free-form text generation.
|
|
326
|
+
|
|
321
327
|
## Reusing Existing Skills
|
|
322
328
|
- Call list_skills when the requested functionality overlaps with an existing local skill.
|
|
323
329
|
- Prefer narrow wrapper tool predicates that internally call exec(run_skill(...)) for one specific child skill.
|
|
@@ -325,25 +331,185 @@ validate_dml, test_dml, and deploy_skill only accept file paths. Write the DML t
|
|
|
325
331
|
|
|
326
332
|
${runtimeSection}${attemptSection}`;
|
|
327
333
|
}
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
334
|
+
const SKILL_NAME_PATTERNS = [
|
|
335
|
+
/(?:called|named)\s+["']?([A-Za-z0-9][A-Za-z0-9 _-]{1,79})["']?/i,
|
|
336
|
+
/(?:create|build|make|write|generate|implement)(?:\s+me)?\s+(?:a|an|the)?\s*["']?([A-Za-z0-9][A-Za-z0-9 _-]{1,79}?)(?:["']?\s+skill\b|["']?$)/i,
|
|
337
|
+
/(?:create|build|make|write|generate|implement)(?:\s+me)?\s+(?:a|an|the)?\s+skill\s+(?:to|for|that)\s+["']?([A-Za-z0-9][A-Za-z0-9 _-]{1,79})["']?/i,
|
|
338
|
+
];
|
|
339
|
+
function cleanSkillLabel(value) {
|
|
340
|
+
return value
|
|
341
|
+
.trim()
|
|
342
|
+
.replace(/[`"']/g, '')
|
|
343
|
+
.replace(/\s+/g, ' ')
|
|
344
|
+
.trim();
|
|
345
|
+
}
|
|
346
|
+
function findSkillNameCandidate(source) {
|
|
347
|
+
const heading = source.match(/^#\s+(.+)$/m)?.[1];
|
|
348
|
+
if (heading) {
|
|
349
|
+
const cleaned = cleanSkillLabel(heading);
|
|
350
|
+
if (cleaned) {
|
|
351
|
+
return cleaned;
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
for (const pattern of SKILL_NAME_PATTERNS) {
|
|
355
|
+
const match = pattern.exec(source);
|
|
356
|
+
if (!match?.[1]) {
|
|
357
|
+
continue;
|
|
358
|
+
}
|
|
359
|
+
const cleaned = cleanSkillLabel(match[1]);
|
|
360
|
+
if (cleaned) {
|
|
361
|
+
return cleaned;
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
return null;
|
|
365
|
+
}
|
|
366
|
+
function shortenSlug(slug, maxLength = 40) {
|
|
367
|
+
if (slug.length <= maxLength) {
|
|
368
|
+
return slug;
|
|
369
|
+
}
|
|
370
|
+
const boundary = slug.lastIndexOf('-', maxLength);
|
|
371
|
+
if (boundary >= Math.floor(maxLength / 2)) {
|
|
372
|
+
return slug.slice(0, boundary);
|
|
373
|
+
}
|
|
374
|
+
return slug.slice(0, maxLength).replace(/-+$/g, '');
|
|
375
|
+
}
|
|
376
|
+
export function normalizeSkillSlug(value, fallback = 'skill') {
|
|
377
|
+
const slug = shortenSlug(value
|
|
378
|
+
.trim()
|
|
379
|
+
.replace(/[`"']/g, '')
|
|
380
|
+
.toLowerCase()
|
|
381
|
+
.replace(/[^a-z0-9]+/g, '-')
|
|
382
|
+
.replace(/^-+|-+$/g, '')
|
|
383
|
+
.replace(/-+/g, '-'));
|
|
384
|
+
if (slug) {
|
|
385
|
+
return slug;
|
|
386
|
+
}
|
|
387
|
+
const fallbackSlug = fallback
|
|
388
|
+
.trim()
|
|
389
|
+
.replace(/[`"']/g, '')
|
|
390
|
+
.toLowerCase()
|
|
391
|
+
.replace(/[^a-z0-9]+/g, '-')
|
|
392
|
+
.replace(/^-+|-+$/g, '')
|
|
393
|
+
.replace(/-+/g, '-');
|
|
394
|
+
return fallbackSlug || 'skill';
|
|
395
|
+
}
|
|
396
|
+
function formatSkillName(value) {
|
|
397
|
+
return cleanSkillLabel(value)
|
|
398
|
+
.replace(/[-_]+/g, ' ')
|
|
399
|
+
.split(/\s+/)
|
|
331
400
|
.filter(Boolean)
|
|
332
401
|
.map((part) => part.charAt(0).toUpperCase() + part.slice(1))
|
|
333
402
|
.join(' ');
|
|
403
|
+
}
|
|
404
|
+
export function deriveSkillSlugFromMarkdown(markdown, fallbackBaseName = 'skill') {
|
|
405
|
+
const fallbackSlug = normalizeSkillSlug(fallbackBaseName, 'skill');
|
|
406
|
+
const directCandidate = findSkillNameCandidate(markdown);
|
|
407
|
+
if (directCandidate) {
|
|
408
|
+
return normalizeSkillSlug(directCandidate, fallbackSlug);
|
|
409
|
+
}
|
|
410
|
+
const fallbackCandidate = findSkillNameCandidate(fallbackBaseName.replace(/[-_]+/g, ' '));
|
|
411
|
+
if (fallbackCandidate) {
|
|
412
|
+
return normalizeSkillSlug(fallbackCandidate, fallbackSlug);
|
|
413
|
+
}
|
|
414
|
+
return fallbackSlug;
|
|
415
|
+
}
|
|
416
|
+
function buildLocalMetadata(markdown, baseName) {
|
|
417
|
+
const slug = deriveSkillSlugFromMarkdown(markdown, baseName);
|
|
418
|
+
const nameCandidate = findSkillNameCandidate(markdown)
|
|
419
|
+
?? findSkillNameCandidate(baseName.replace(/[-_]+/g, ' '))
|
|
420
|
+
?? slug;
|
|
421
|
+
const name = formatSkillName(nameCandidate) || formatSkillName(slug);
|
|
334
422
|
const description = extractDescription(markdown);
|
|
423
|
+
const triggerPhraseBase = name.replace(/\s+/g, ' ').trim().toLowerCase() || slug.replace(/[-_]+/g, ' ');
|
|
335
424
|
const triggerPhrases = Array.from(new Set([
|
|
336
|
-
|
|
337
|
-
`run ${
|
|
338
|
-
`use ${
|
|
425
|
+
triggerPhraseBase,
|
|
426
|
+
`run ${triggerPhraseBase}`,
|
|
427
|
+
`use ${triggerPhraseBase}`,
|
|
339
428
|
])).slice(0, 3);
|
|
340
429
|
return {
|
|
341
|
-
slug
|
|
342
|
-
name: name ||
|
|
430
|
+
slug,
|
|
431
|
+
name: name || formatSkillName(slug),
|
|
343
432
|
description,
|
|
344
433
|
trigger_phrases: triggerPhrases,
|
|
345
434
|
};
|
|
346
435
|
}
|
|
436
|
+
function normalizeParameterName(name) {
|
|
437
|
+
return name
|
|
438
|
+
.trim()
|
|
439
|
+
.replace(/[`"']/g, '')
|
|
440
|
+
.replace(/([A-Z])/g, (_m, c, i) => (i > 0 ? '_' : '') + c.toLowerCase())
|
|
441
|
+
.replace(/[\s-]+/g, '_')
|
|
442
|
+
.replace(/[^a-z0-9_]/g, '')
|
|
443
|
+
.replace(/_+/g, '_')
|
|
444
|
+
.replace(/^_+|_+$/g, '');
|
|
445
|
+
}
|
|
446
|
+
function extractParameterDocs(markdown) {
|
|
447
|
+
const parameterDocs = [];
|
|
448
|
+
const lines = markdown.split('\n');
|
|
449
|
+
let inParametersSection = false;
|
|
450
|
+
for (const line of lines) {
|
|
451
|
+
const trimmed = line.trim();
|
|
452
|
+
if (!inParametersSection) {
|
|
453
|
+
if (/^##\s+Parameters\b/i.test(trimmed)) {
|
|
454
|
+
inParametersSection = true;
|
|
455
|
+
}
|
|
456
|
+
continue;
|
|
457
|
+
}
|
|
458
|
+
if (/^##\s+/.test(trimmed)) {
|
|
459
|
+
break;
|
|
460
|
+
}
|
|
461
|
+
const match = /^-\s+`?([^`:(]+)`?\s*(?:\(([^)]*)\))?\s*:\s*(.+)$/.exec(trimmed);
|
|
462
|
+
if (!match) {
|
|
463
|
+
continue;
|
|
464
|
+
}
|
|
465
|
+
const [, rawName, qualifiers = '', description] = match;
|
|
466
|
+
const defaultMatch = /default\s*:\s*(?:"([^"]+)"|'([^']+)'|([^,]+))/i.exec(qualifiers);
|
|
467
|
+
const qualifierText = qualifiers.toLowerCase();
|
|
468
|
+
parameterDocs.push({
|
|
469
|
+
name: normalizeParameterName(rawName),
|
|
470
|
+
description: description.trim(),
|
|
471
|
+
required: qualifierText.includes('required')
|
|
472
|
+
? true
|
|
473
|
+
: (qualifierText.includes('optional') || !!defaultMatch ? false : undefined),
|
|
474
|
+
default: defaultMatch
|
|
475
|
+
? (defaultMatch[1] ?? defaultMatch[2] ?? defaultMatch[3]).trim()
|
|
476
|
+
: undefined,
|
|
477
|
+
});
|
|
478
|
+
}
|
|
479
|
+
return parameterDocs;
|
|
480
|
+
}
|
|
481
|
+
function mergeParameterDocs(parameters, parameterDocs) {
|
|
482
|
+
const docsByName = new Map(parameterDocs.map((parameterDoc) => [parameterDoc.name, parameterDoc]));
|
|
483
|
+
return parameters.map((parameter) => {
|
|
484
|
+
const parameterDoc = docsByName.get(parameter.name);
|
|
485
|
+
if (!parameterDoc) {
|
|
486
|
+
return parameter;
|
|
487
|
+
}
|
|
488
|
+
return {
|
|
489
|
+
...parameter,
|
|
490
|
+
description: parameterDoc.description ?? parameter.description,
|
|
491
|
+
required: parameterDoc.required ?? parameter.required,
|
|
492
|
+
default: parameterDoc.default ?? parameter.default,
|
|
493
|
+
};
|
|
494
|
+
});
|
|
495
|
+
}
|
|
496
|
+
function extractSkillCapabilities(analysis) {
|
|
497
|
+
return Array.from(new Set(analysis.capabilities.filter((capability) => !capability.startsWith('tool_use('))));
|
|
498
|
+
}
|
|
499
|
+
function readMetadataName(metadata, fallbackName) {
|
|
500
|
+
const name = metadata['name'];
|
|
501
|
+
return typeof name === 'string' && name.trim() ? name.trim() : fallbackName;
|
|
502
|
+
}
|
|
503
|
+
function readMetadataTriggerPhrases(metadata, fallbackTriggerPhrases) {
|
|
504
|
+
const rawTriggerPhrases = Array.isArray(metadata['trigger_phrases'])
|
|
505
|
+
? metadata['trigger_phrases']
|
|
506
|
+
: (Array.isArray(metadata['triggerPhrases']) ? metadata['triggerPhrases'] : fallbackTriggerPhrases);
|
|
507
|
+
return Array.from(new Set(rawTriggerPhrases
|
|
508
|
+
.filter((triggerPhrase) => typeof triggerPhrase === 'string')
|
|
509
|
+
.map((triggerPhrase) => triggerPhrase.trim())
|
|
510
|
+
.filter((triggerPhrase) => triggerPhrase.length > 0)))
|
|
511
|
+
.slice(0, 5);
|
|
512
|
+
}
|
|
347
513
|
async function writeWorkspaceFile(workspacePath, args) {
|
|
348
514
|
const relPath = String(args.path ?? '');
|
|
349
515
|
const content = String(args.content ?? '');
|
|
@@ -416,9 +582,13 @@ async function runLocalTestDml(context, args) {
|
|
|
416
582
|
async function publishSkill(context, args) {
|
|
417
583
|
const dmlPath = resolveWorkspacePath(context.workspacePath, String(args.dml_file ?? ''));
|
|
418
584
|
const dml = await fs.readFile(dmlPath, 'utf8');
|
|
585
|
+
const fallbackMetadata = buildLocalMetadata(context.markdown, context.baseName);
|
|
419
586
|
const normalized = normalizeDeployInputs(String(args.spec_markdown ?? context.markdown), String(args.metadata_json ?? ''));
|
|
420
|
-
const metadata = parseMetadataJson(normalized.metadataJson,
|
|
421
|
-
const
|
|
587
|
+
const metadata = parseMetadataJson(normalized.metadataJson, fallbackMetadata);
|
|
588
|
+
const requestedSlug = typeof args.slug_override === 'string' && args.slug_override.trim()
|
|
589
|
+
? args.slug_override
|
|
590
|
+
: (typeof metadata.slug === 'string' && metadata.slug.trim() ? metadata.slug : fallbackMetadata.slug);
|
|
591
|
+
const publishName = normalizeSkillSlug(requestedSlug, fallbackMetadata.slug);
|
|
422
592
|
const meta = await buildMetaFile({
|
|
423
593
|
dml,
|
|
424
594
|
markdown: normalized.specMarkdown,
|
|
@@ -426,6 +596,8 @@ async function publishSkill(context, args) {
|
|
|
426
596
|
publishName,
|
|
427
597
|
model: context.compileSelection.model,
|
|
428
598
|
provider: context.compileSelection.provider,
|
|
599
|
+
name: readMetadataName(metadata, fallbackMetadata.name),
|
|
600
|
+
triggerPhrases: readMetadataTriggerPhrases(metadata, fallbackMetadata.trigger_phrases),
|
|
429
601
|
description: typeof metadata.description === 'string' ? metadata.description : extractDescription(normalized.specMarkdown),
|
|
430
602
|
});
|
|
431
603
|
const outputPath = path.join(context.outputDir, `${publishName}.dml`);
|
|
@@ -438,6 +610,7 @@ async function publishSkill(context, args) {
|
|
|
438
610
|
dml,
|
|
439
611
|
meta,
|
|
440
612
|
outputPath,
|
|
613
|
+
slug: publishName,
|
|
441
614
|
};
|
|
442
615
|
}
|
|
443
616
|
async function buildMetaFile(input) {
|
|
@@ -447,6 +620,8 @@ async function buildMetaFile(input) {
|
|
|
447
620
|
const history = existing?.history ?? [];
|
|
448
621
|
const analysis = await analyzeDML(input.dml);
|
|
449
622
|
const tools = extractToolNames(analysis);
|
|
623
|
+
const parameters = mergeParameterDocs(extractParameters(input.dml), extractParameterDocs(input.markdown));
|
|
624
|
+
const capabilities = extractSkillCapabilities(analysis);
|
|
450
625
|
return {
|
|
451
626
|
version: '1.0.0',
|
|
452
627
|
source: input.publishName,
|
|
@@ -454,8 +629,11 @@ async function buildMetaFile(input) {
|
|
|
454
629
|
compiledAt: new Date().toISOString(),
|
|
455
630
|
model: input.model,
|
|
456
631
|
provider: input.provider,
|
|
632
|
+
name: input.name,
|
|
633
|
+
triggerPhrases: input.triggerPhrases.length > 0 ? input.triggerPhrases : undefined,
|
|
634
|
+
capabilities: capabilities.length > 0 ? capabilities : undefined,
|
|
457
635
|
description: input.description,
|
|
458
|
-
parameters
|
|
636
|
+
parameters,
|
|
459
637
|
tools,
|
|
460
638
|
history: [
|
|
461
639
|
...history,
|
|
@@ -493,8 +671,13 @@ async function urlFetch(workspacePath, args, signal) {
|
|
|
493
671
|
headers,
|
|
494
672
|
};
|
|
495
673
|
}
|
|
674
|
+
const body = await response.text();
|
|
675
|
+
const truncated = truncateUrlFetchTextBody(body);
|
|
496
676
|
return {
|
|
497
|
-
body:
|
|
677
|
+
body: truncated.body,
|
|
678
|
+
truncated: truncated.truncated,
|
|
679
|
+
original_length: truncated.originalLength,
|
|
680
|
+
returned_length: truncated.returnedLength,
|
|
498
681
|
status: response.status,
|
|
499
682
|
headers,
|
|
500
683
|
};
|
|
@@ -524,7 +707,8 @@ function looksLikeJsonObject(value) {
|
|
|
524
707
|
}
|
|
525
708
|
function parseMetadataJson(metadataJson, fallback) {
|
|
526
709
|
try {
|
|
527
|
-
|
|
710
|
+
const parsed = JSON.parse(metadataJson);
|
|
711
|
+
return parsed && typeof parsed === 'object' ? parsed : fallback;
|
|
528
712
|
}
|
|
529
713
|
catch {
|
|
530
714
|
return fallback;
|