@marifold/core 0.65.0 → 0.67.0

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.
Files changed (61) hide show
  1. package/dist/agent/AgentRunner.d.ts +6 -0
  2. package/dist/agent/AgentRunner.d.ts.map +1 -1
  3. package/dist/agent/AgentRunner.js +21 -6
  4. package/dist/agent/AgentRunner.js.map +1 -1
  5. package/dist/agent/RunWorkspace.d.ts +10 -0
  6. package/dist/agent/RunWorkspace.d.ts.map +1 -1
  7. package/dist/agent/RunWorkspace.js +19 -1
  8. package/dist/agent/RunWorkspace.js.map +1 -1
  9. package/dist/agent/tools/ReadFileTool.d.ts +7 -0
  10. package/dist/agent/tools/ReadFileTool.d.ts.map +1 -1
  11. package/dist/agent/tools/ReadFileTool.js +24 -2
  12. package/dist/agent/tools/ReadFileTool.js.map +1 -1
  13. package/dist/agent/tools/SkillAppTools.d.ts +90 -0
  14. package/dist/agent/tools/SkillAppTools.d.ts.map +1 -0
  15. package/dist/agent/tools/SkillAppTools.js +402 -0
  16. package/dist/agent/tools/SkillAppTools.js.map +1 -0
  17. package/dist/app/AppStore.d.ts +11 -1
  18. package/dist/app/AppStore.d.ts.map +1 -1
  19. package/dist/app/AppStore.js +110 -15
  20. package/dist/app/AppStore.js.map +1 -1
  21. package/dist/app/SkillAppCompiler.d.ts.map +1 -1
  22. package/dist/app/SkillAppCompiler.js +370 -44
  23. package/dist/app/SkillAppCompiler.js.map +1 -1
  24. package/dist/app/SkillAppDsl.d.ts +77 -4
  25. package/dist/app/SkillAppDsl.d.ts.map +1 -1
  26. package/dist/app/SkillAppDsl.js +53 -0
  27. package/dist/app/SkillAppDsl.js.map +1 -1
  28. package/dist/app/SkillAppInstanceRegistry.d.ts +23 -2
  29. package/dist/app/SkillAppInstanceRegistry.d.ts.map +1 -1
  30. package/dist/app/SkillAppInstanceRegistry.js +439 -11
  31. package/dist/app/SkillAppInstanceRegistry.js.map +1 -1
  32. package/dist/app/SkillAppResolver.d.ts +5 -2
  33. package/dist/app/SkillAppResolver.d.ts.map +1 -1
  34. package/dist/app/SkillAppResolver.js +66 -15
  35. package/dist/app/SkillAppResolver.js.map +1 -1
  36. package/dist/app/SkillAppSchema.d.ts +120 -9
  37. package/dist/app/SkillAppSchema.d.ts.map +1 -1
  38. package/dist/app/SkillAppSchema.js +2 -1
  39. package/dist/app/SkillAppSchema.js.map +1 -1
  40. package/dist/index.d.ts +6 -6
  41. package/dist/index.d.ts.map +1 -1
  42. package/dist/index.js +14 -4
  43. package/dist/index.js.map +1 -1
  44. package/dist/runtime/MarifoldRuntime.d.ts +14 -8
  45. package/dist/runtime/MarifoldRuntime.d.ts.map +1 -1
  46. package/dist/runtime/MarifoldRuntime.js +246 -30
  47. package/dist/runtime/MarifoldRuntime.js.map +1 -1
  48. package/dist/skill/BuiltInSkillAppBuilder.d.ts +10 -0
  49. package/dist/skill/BuiltInSkillAppBuilder.d.ts.map +1 -0
  50. package/dist/skill/BuiltInSkillAppBuilder.js +34 -0
  51. package/dist/skill/BuiltInSkillAppBuilder.js.map +1 -0
  52. package/dist/skill/BuiltInSkills.d.ts.map +1 -1
  53. package/dist/skill/BuiltInSkills.js +37 -0
  54. package/dist/skill/BuiltInSkills.js.map +1 -1
  55. package/dist/skill/SkillStore.d.ts +2 -2
  56. package/dist/skill/SkillStore.js +2 -2
  57. package/dist/skill/index.d.ts +1 -0
  58. package/dist/skill/index.d.ts.map +1 -1
  59. package/dist/skill/index.js +4 -1
  60. package/dist/skill/index.js.map +1 -1
  61. package/package.json +1 -1
@@ -0,0 +1,402 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.SkillAppManagementTool = exports.SkillAppContextTool = void 0;
37
+ const fs = __importStar(require("fs"));
38
+ const path = __importStar(require("path"));
39
+ const crypto_1 = require("crypto");
40
+ const MarifoldError_1 = require("../../errors/MarifoldError");
41
+ const ToolRegistry_1 = require("../ToolRegistry");
42
+ const SAFE_APP_NAME = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
43
+ const MAX_FILES = 32;
44
+ const MAX_TOTAL_BYTES = 512 * 1024;
45
+ const V1_TEMPLATE = `import {
46
+ App, Button, Column, Download, Markdown, State, Textarea, TextResult,
47
+ defineSkillApp, registerModel, registerSkill, useSkill,
48
+ } from '@marifold/core';
49
+
50
+ const input = State('');
51
+ const result = State('');
52
+ const model = registerModel('provider/model', { think: false });
53
+ const skill = registerSkill('skill-name', { result: TextResult({ trim: true }) });
54
+ const run = useSkill(model, skill, {
55
+ parameters: { request: input },
56
+ output: result,
57
+ memory: false,
58
+ history: false,
59
+ profileContext: false,
60
+ });
61
+
62
+ export default defineSkillApp({
63
+ app: { name: 'app-name', title: 'App title', version: '1.0.0', description: 'Focused purpose.' },
64
+ ui: App([Column([
65
+ Textarea('Input', input),
66
+ Button('Run', { trigger: run, emphasis: 'primary' }),
67
+ Markdown('Result', result),
68
+ Download('Download result', result, { filename: 'result.md', mediaType: 'text/markdown;charset=utf-8' }),
69
+ ])]),
70
+ });`;
71
+ const V2_TEMPLATE = `import {
72
+ App, Button, Column, State, Textarea, TextResult,
73
+ defineSkillApp, registerProfile, useProfileSkill,
74
+ } from '@marifold/core';
75
+
76
+ const input = State('');
77
+ const result = State('');
78
+ const profile = registerProfile('profile-name', { memory: false, history: false });
79
+ const run = useProfileSkill(profile, 'skill-name', {
80
+ input,
81
+ output: result,
82
+ result: TextResult({ trim: true }),
83
+ });
84
+
85
+ export default defineSkillApp({
86
+ app: { name: 'app-name', title: 'App title', version: '1.0.0', description: 'Focused purpose.' },
87
+ ui: App([Column([
88
+ Textarea('Input', input),
89
+ Button('Run', { trigger: run, emphasis: 'primary' }),
90
+ Textarea('Result', result, { editable: false, copyable: true }),
91
+ ])]),
92
+ });`;
93
+ /** Version-matched authoring context for the protected SkillApp builder. */
94
+ class SkillAppContextTool {
95
+ options;
96
+ kind = 'read';
97
+ definition = {
98
+ name: 'inspect_skill_apps',
99
+ description: [
100
+ 'Inspect the current Marifold SkillApp authoring environment.',
101
+ 'Returns the active profile, existing Apps, available profiles and their effective Skills, and the supported static component contract.',
102
+ 'When to use: before designing or generating a SkillApp.',
103
+ 'When NOT to use: ordinary Skill execution or unrelated project inspection. It never changes files.',
104
+ ].join(' '),
105
+ parameters: { type: 'object', properties: {} },
106
+ };
107
+ constructor(options) {
108
+ this.options = options;
109
+ }
110
+ summarizeCall() {
111
+ return 'inspect SkillApp components, profiles, Skills, and Apps';
112
+ }
113
+ async execute() {
114
+ const profiles = this.options.listProfiles().map(profile => ({
115
+ name: profile.name,
116
+ ...(profile.displayName ? { displayName: profile.displayName } : {}),
117
+ skills: this.options.listSkills(profile.name).map(skill => ({
118
+ name: skill.name,
119
+ description: skill.description,
120
+ mode: skill.mode ?? 'profile-default',
121
+ variables: skill.variables.map(variable => ({
122
+ name: variable.name,
123
+ required: variable.required,
124
+ ...(variable.description ? { description: variable.description } : {}),
125
+ ...(variable.default !== undefined ? { default: variable.default } : {}),
126
+ })),
127
+ })),
128
+ }));
129
+ return {
130
+ content: JSON.stringify({
131
+ activeProfile: this.options.activeProfile,
132
+ appsDirectory: this.options.appsDir,
133
+ apps: this.options.listApps(),
134
+ profiles,
135
+ contract: {
136
+ schemas: ['marifold.skillapp.v1', 'marifold.skillapp.v2'],
137
+ declarations: [
138
+ 'State(initialText)',
139
+ 'AttachmentState()',
140
+ "registerModel('provider/model', { think? })",
141
+ "registerProfile('profile-name', { model?, think?, memory?, history? })",
142
+ "registerSkill('skill-name', { result: TextResult({ trim? }) })",
143
+ 'TextResult({ trim? })',
144
+ ],
145
+ layout: ['App', 'Row', 'Column', 'Spacer'],
146
+ form: ['Textarea', 'Select'],
147
+ resources: ['Attachments'],
148
+ outputs: [
149
+ 'Markdown(label, state, { showLabel?, grow?, copyable?, sourceToggle?, placeholder? })',
150
+ 'Download(label, state, { filename, mediaType?, description?, showLabel?, grow? })',
151
+ ],
152
+ actions: ['Button'],
153
+ operations: [
154
+ 'useSkill(model, skill, { parameters, output, memory: false, history: false, profileContext: false })',
155
+ 'useProfileSkill(profile, skillNameOrState, { skills?, input?, attachments?, stripSkillName?, parameters?, output, result, interactive? })',
156
+ 'trigger(operation, { onChange, debounce?, concurrency?: "latest" })',
157
+ ],
158
+ interactive: 'Set useProfileSkill(..., { interactive: true }) for an Agent Skill that may ask questions or request approval.',
159
+ bundle: {
160
+ common: [
161
+ 'skillapp.ts is required; app.name and the bundle name must be the same kebab-case value',
162
+ 'replace the example app, profile, model, Skill, labels, parameter names, and filenames with the requested design',
163
+ ],
164
+ v1: [
165
+ 'use registerModel + registerSkill + useSkill',
166
+ 'include skills/<skill-name>/SKILL.md whose frontmatter name matches registerSkill',
167
+ 'map every required SKILL.md variable to a State in useSkill.parameters',
168
+ ],
169
+ v2: [
170
+ 'use registerProfile + useProfileSkill and one Skill from that profile effective catalog',
171
+ 'do not copy the profile Skill into the App bundle',
172
+ ],
173
+ },
174
+ templates: {
175
+ v1: V1_TEMPLATE,
176
+ v1Skill: '---\\nname: skill-name\\nvariables:\\n - name: request\\n required: true\\n---\\nPerform the focused task and return only the requested result.\\n\\n{{request}}',
177
+ v2: V2_TEMPLATE,
178
+ },
179
+ constraints: [
180
+ 'skillapp.ts is statically compiled and never executed',
181
+ 'no functions, callbacks, conditions, loops, arbitrary imports, HTML, CSS, network calls, or direct filesystem writes',
182
+ 'one interactive operation runs exclusively per App instance',
183
+ 'interactive operations cannot use automatic triggers',
184
+ 'Markdown and Download may bind the same text output State; Download creates the file in the renderer without filesystem access',
185
+ 'each Download is one text file with a static filename; multiple components make multiple static downloads, while binary files, per-run filenames, and dynamic file collections are unsupported',
186
+ 'v1 uses an app-local chat Skill and registered model; v2 registers an existing profile and its effective Skill',
187
+ 'inspect_skill_apps is authoritative; do not probe App directories or arbitrary host paths for examples',
188
+ ],
189
+ },
190
+ }, null, 2),
191
+ summary: `inspected ${profiles.length} profiles and ${this.options.listApps().length} Apps`,
192
+ };
193
+ }
194
+ }
195
+ exports.SkillAppContextTool = SkillAppContextTool;
196
+ /** Confined, validated, atomic mutation boundary for generated App bundles. */
197
+ class SkillAppManagementTool {
198
+ options;
199
+ kind = 'write';
200
+ definition = {
201
+ name: 'manage_skill_app',
202
+ description: [
203
+ 'Create or update exactly one global Marifold SkillApp bundle from generated text files.',
204
+ 'The complete staged bundle is statically compiled and validated before an atomic install.',
205
+ 'When to use: after inspecting the SkillApp environment and resolving essential design decisions.',
206
+ 'When NOT to use: arbitrary file writes, unvalidated application code, or implicit replacement after a name collision.',
207
+ ].join(' '),
208
+ parameters: {
209
+ type: 'object',
210
+ properties: {
211
+ action: { type: 'string', enum: ['create', 'update'] },
212
+ name: { type: 'string', description: 'Kebab-case App and bundle name.' },
213
+ files: {
214
+ type: 'array',
215
+ description: 'Complete generated text files relative to the App bundle, including skillapp.ts.',
216
+ items: {
217
+ type: 'object',
218
+ properties: {
219
+ path: { type: 'string' },
220
+ content: { type: 'string' },
221
+ },
222
+ required: ['path', 'content'],
223
+ },
224
+ },
225
+ },
226
+ required: ['action', 'name', 'files'],
227
+ },
228
+ };
229
+ failedAttempts = 0;
230
+ lastFailure;
231
+ constructor(options) {
232
+ this.options = options;
233
+ }
234
+ summarizeCall(input) {
235
+ const action = input.action === 'update' ? 'update' : 'create';
236
+ const name = typeof input.name === 'string' ? input.name : '<missing App>';
237
+ return `${action} SkillApp ${name}`;
238
+ }
239
+ assessRisk(input) {
240
+ const name = typeof input.name === 'string' && SAFE_APP_NAME.test(input.name)
241
+ ? input.name
242
+ : '<invalid-app>';
243
+ if (this.failedAttempts >= 3) {
244
+ return {
245
+ blocked: true,
246
+ escalate: false,
247
+ persistable: false,
248
+ reason: `three SkillApp validation attempts failed; stop and report the last error${this.lastFailure ? `: ${this.lastFailure}` : ''}`,
249
+ targetPath: path.join(this.options.appsDir, name),
250
+ };
251
+ }
252
+ return {
253
+ escalate: true,
254
+ persistable: false,
255
+ reason: 'installing a persistent Marifold App bundle',
256
+ targetPath: path.join(this.options.appsDir, name),
257
+ };
258
+ }
259
+ async execute(input, _ctx) {
260
+ let stageRoot;
261
+ try {
262
+ const action = (0, ToolRegistry_1.requireStringInput)(input, 'action', 'manage_skill_app');
263
+ if (action !== 'create' && action !== 'update') {
264
+ throw MarifoldError_1.MarifoldError.agentToolInvalid(`Unsupported SkillApp action '${action}'.`, 'manage_skill_app');
265
+ }
266
+ const name = (0, ToolRegistry_1.requireStringInput)(input, 'name', 'manage_skill_app');
267
+ if (!SAFE_APP_NAME.test(name)) {
268
+ throw MarifoldError_1.MarifoldError.appInvalid(`Invalid App name '${name}'. Use kebab-case.`);
269
+ }
270
+ const files = bundleFiles(input.files);
271
+ if (!files.some(file => file.path === 'skillapp.ts')) {
272
+ throw MarifoldError_1.MarifoldError.appInvalid("A generated App bundle must include 'skillapp.ts'.");
273
+ }
274
+ fs.mkdirSync(this.options.appsDir, { recursive: true });
275
+ const target = path.join(this.options.appsDir, name);
276
+ const exists = fs.existsSync(target);
277
+ if (action === 'create' && exists) {
278
+ throw MarifoldError_1.MarifoldError.appInvalid(`App '${name}' already exists. Use update only after the user explicitly requests replacing it.`);
279
+ }
280
+ if (action === 'update' && !exists) {
281
+ throw MarifoldError_1.MarifoldError.appNotFound(name);
282
+ }
283
+ if (exists && (!fs.lstatSync(target).isDirectory() || fs.lstatSync(target).isSymbolicLink())) {
284
+ throw MarifoldError_1.MarifoldError.appInvalid(`App target '${name}' is not a regular bundle directory.`);
285
+ }
286
+ stageRoot = fs.mkdtempSync(path.join(this.options.appsDir, '.skillapp-stage-'));
287
+ const stagedBundle = path.join(stageRoot, name);
288
+ fs.mkdirSync(stagedBundle, { recursive: true });
289
+ for (const file of files) {
290
+ const destination = path.join(stagedBundle, file.path);
291
+ fs.mkdirSync(path.dirname(destination), { recursive: true });
292
+ fs.writeFileSync(destination, file.content, 'utf8');
293
+ }
294
+ const definition = this.options.createStore(stageRoot).require(name);
295
+ const installedFiles = listRegularFiles(stagedBundle);
296
+ installAtomically(stagedBundle, target, action);
297
+ const effect = {
298
+ kind: 'app_installed',
299
+ appName: name,
300
+ title: definition.app.title,
301
+ action: action === 'create' ? 'created' : 'updated',
302
+ files: installedFiles,
303
+ };
304
+ this.options.onInstalled?.(effect);
305
+ this.failedAttempts = 0;
306
+ this.lastFailure = undefined;
307
+ return {
308
+ content: `${action === 'create' ? 'Created' : 'Updated'} SkillApp '${definition.app.title}' (${name}) with ${installedFiles.length} validated ${installedFiles.length === 1 ? 'file' : 'files'}. The service does not need a restart.`,
309
+ summary: `${effect.action} SkillApp ${name}`,
310
+ };
311
+ }
312
+ catch (error) {
313
+ const message = error instanceof Error ? error.message : String(error);
314
+ this.failedAttempts += 1;
315
+ this.lastFailure = message;
316
+ return {
317
+ content: `SkillApp management failed: ${message}${this.failedAttempts >= 3 ? ' No further installation attempts are allowed in this run; report this error to the user.' : ''}`,
318
+ summary: `SkillApp validation failed: ${message.length > 300 ? `${message.slice(0, 297)}...` : message}`,
319
+ isError: true,
320
+ };
321
+ }
322
+ finally {
323
+ if (stageRoot)
324
+ fs.rmSync(stageRoot, { recursive: true, force: true });
325
+ }
326
+ }
327
+ }
328
+ exports.SkillAppManagementTool = SkillAppManagementTool;
329
+ function bundleFiles(value) {
330
+ if (!Array.isArray(value) || value.length < 1 || value.length > MAX_FILES) {
331
+ throw MarifoldError_1.MarifoldError.agentToolInvalid(`manage_skill_app.files must contain 1-${MAX_FILES} text files.`, 'manage_skill_app');
332
+ }
333
+ const seen = new Set();
334
+ let total = 0;
335
+ return value.map((entry, index) => {
336
+ if (!entry || typeof entry !== 'object' || Array.isArray(entry)) {
337
+ throw MarifoldError_1.MarifoldError.agentToolInvalid(`manage_skill_app.files[${index}] must be an object.`, 'manage_skill_app');
338
+ }
339
+ const file = entry;
340
+ const relative = safeBundlePath((0, ToolRegistry_1.requireStringInput)(file, 'path', 'manage_skill_app'));
341
+ if (seen.has(relative))
342
+ throw MarifoldError_1.MarifoldError.appInvalid(`Duplicate App file '${relative}'.`);
343
+ seen.add(relative);
344
+ if (typeof file.content !== 'string') {
345
+ throw MarifoldError_1.MarifoldError.agentToolInvalid(`manage_skill_app.files[${index}].content must be text.`, 'manage_skill_app');
346
+ }
347
+ total += Buffer.byteLength(file.content, 'utf8');
348
+ if (total > MAX_TOTAL_BYTES) {
349
+ throw MarifoldError_1.MarifoldError.appInvalid(`Generated App bundle exceeds ${MAX_TOTAL_BYTES / 1024} KiB.`);
350
+ }
351
+ return { path: relative, content: file.content };
352
+ });
353
+ }
354
+ function safeBundlePath(value) {
355
+ if (value.includes('\0'))
356
+ throw MarifoldError_1.MarifoldError.appInvalid('App file paths cannot contain null bytes.');
357
+ const portable = value.replace(/\\/g, '/');
358
+ const parts = portable.split('/');
359
+ if (portable.startsWith('/') || /^[a-z]:\//i.test(portable)
360
+ || parts.some(part => part === '' || part === '.' || part === '..')) {
361
+ throw MarifoldError_1.MarifoldError.appInvalid(`Unsafe App file path '${value}'.`);
362
+ }
363
+ return parts.join(path.sep);
364
+ }
365
+ function listRegularFiles(root) {
366
+ const files = [];
367
+ const visit = (directory) => {
368
+ for (const entry of fs.readdirSync(directory, { withFileTypes: true })) {
369
+ const source = path.join(directory, entry.name);
370
+ if (entry.isDirectory())
371
+ visit(source);
372
+ else if (entry.isFile())
373
+ files.push(path.relative(root, source).split(path.sep).join('/'));
374
+ }
375
+ };
376
+ visit(root);
377
+ return files.sort();
378
+ }
379
+ function installAtomically(stagedBundle, target, action) {
380
+ if (action === 'create') {
381
+ fs.renameSync(stagedBundle, target);
382
+ return;
383
+ }
384
+ const backup = path.join(path.dirname(target), `.skillapp-backup-${path.basename(target)}-${(0, crypto_1.randomUUID)()}`);
385
+ fs.renameSync(target, backup);
386
+ try {
387
+ fs.renameSync(stagedBundle, target);
388
+ }
389
+ catch (error) {
390
+ if (!fs.existsSync(target) && fs.existsSync(backup))
391
+ fs.renameSync(backup, target);
392
+ throw error;
393
+ }
394
+ try {
395
+ fs.rmSync(backup, { recursive: true, force: true });
396
+ }
397
+ catch {
398
+ // The validated target is already installed; a stale hidden backup is safer
399
+ // than reporting a false installation failure or disturbing the new bundle.
400
+ }
401
+ }
402
+ //# sourceMappingURL=SkillAppTools.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SkillAppTools.js","sourceRoot":"","sources":["../../../src/agent/tools/SkillAppTools.ts"],"names":[],"mappings":"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"}
@@ -1,14 +1,24 @@
1
+ import type { MarifoldSkill } from '../skill/SkillSchema';
1
2
  import type { SkillAppDefinition } from './SkillAppSchema';
3
+ export interface AppStoreOptions {
4
+ /** Resolve exactly as a normal invocation from this profile: profile Skills
5
+ * shadow global Skills. Runtime wiring also validates that the profile exists. */
6
+ resolveProfileSkill?: (profile: string, skillName: string) => MarifoldSkill | undefined;
7
+ }
2
8
  /** Global App bundles under `<appsDir>/<name>/skillapp.ts`. Invalid bundles
3
9
  * are skipped by list(); get() reports their exact validation failure. */
4
10
  export declare class AppStore {
5
11
  private readonly directory;
6
- constructor(directory: string);
12
+ private readonly options;
13
+ constructor(directory: string, options?: AppStoreOptions);
7
14
  list(): SkillAppDefinition[];
8
15
  get(name: string): SkillAppDefinition | undefined;
9
16
  require(name: string): SkillAppDefinition;
10
17
  /** Resolve one v1 app-local Skill without profile/global fallback. */
11
18
  requireLocalSkillSource(appName: string, skillName: string): string;
19
+ requireProfileSkill(profile: string, skillName: string): MarifoldSkill;
12
20
  private validateLocalSkills;
21
+ private validateProfileSkills;
22
+ private validateOperationBindings;
13
23
  }
14
24
  //# sourceMappingURL=AppStore.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"AppStore.d.ts","sourceRoot":"","sources":["../../src/app/AppStore.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAK3D;0EAC0E;AAC1E,qBAAa,QAAQ;IACP,OAAO,CAAC,QAAQ,CAAC,SAAS;IAAtC,YAA6B,SAAS,EAAE,MAAM,EAAI;IAElD,IAAI,IAAI,kBAAkB,EAAE,CAa3B;IAED,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,kBAAkB,GAAG,SAAS,CAehD;IAED,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,kBAAkB,CAIxC;IAED,sEAAsE;IACtE,uBAAuB,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CASlE;IAED,OAAO,CAAC,mBAAmB;CAyC5B"}
1
+ {"version":3,"file":"AppStore.d.ts","sourceRoot":"","sources":["../../src/app/AppStore.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAE1D,OAAO,KAAK,EAAE,kBAAkB,EAA+B,MAAM,kBAAkB,CAAC;AAKxF,MAAM,WAAW,eAAe;IAC9B;sFACkF;IAClF,mBAAmB,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,KAAK,aAAa,GAAG,SAAS,CAAC;CACzF;AAED;0EAC0E;AAC1E,qBAAa,QAAQ;IAEjB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,OAAO;IAF1B,YACmB,SAAS,EAAE,MAAM,EACjB,OAAO,GAAE,eAAoB,EAC5C;IAEJ,IAAI,IAAI,kBAAkB,EAAE,CAa3B;IAED,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,kBAAkB,GAAG,SAAS,CAiBhD;IAED,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,kBAAkB,CAIxC;IAED,sEAAsE;IACtE,uBAAuB,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CASlE;IAED,mBAAmB,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,aAAa,CAIrE;IAED,OAAO,CAAC,mBAAmB;IAwB3B,OAAO,CAAC,qBAAqB;IA6C7B,OAAO,CAAC,yBAAyB;CA8BlC"}
@@ -35,6 +35,7 @@ var __importStar = (this && this.__importStar) || (function () {
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
36
  exports.AppStore = void 0;
37
37
  const fs = __importStar(require("fs"));
38
+ const os = __importStar(require("os"));
38
39
  const path = __importStar(require("path"));
39
40
  const MarifoldError_1 = require("../errors/MarifoldError");
40
41
  const SkillValidator_1 = require("../skill/SkillValidator");
@@ -45,8 +46,10 @@ const SKILL_APP_DEFINITION_FILE = 'skillapp.ts';
45
46
  * are skipped by list(); get() reports their exact validation failure. */
46
47
  class AppStore {
47
48
  directory;
48
- constructor(directory) {
49
+ options;
50
+ constructor(directory, options = {}) {
49
51
  this.directory = directory;
52
+ this.options = options;
50
53
  }
51
54
  list() {
52
55
  if (!fs.existsSync(this.directory))
@@ -77,7 +80,9 @@ class AppStore {
77
80
  if (definition.app.name !== name) {
78
81
  throw MarifoldError_1.MarifoldError.appInvalid(`App app.name '${definition.app.name}' must match bundle directory '${name}'.`, realSource);
79
82
  }
83
+ definition.permissions = resolvePermissions(bundle, definition.permissions ?? [], realSource);
80
84
  this.validateLocalSkills(name, definition);
85
+ this.validateProfileSkills(definition);
81
86
  return definition;
82
87
  }
83
88
  require(name) {
@@ -98,6 +103,12 @@ class AppStore {
98
103
  throw MarifoldError_1.MarifoldError.skillNotFound(skillName);
99
104
  return requireConfinedFile(bundle, source, `App-local skill '${skillName}'`);
100
105
  }
106
+ requireProfileSkill(profile, skillName) {
107
+ const skill = this.options.resolveProfileSkill?.(profile, skillName);
108
+ if (!skill)
109
+ throw MarifoldError_1.MarifoldError.skillNotFound(skillName);
110
+ return skill;
111
+ }
101
112
  validateLocalSkills(appName, definition) {
102
113
  for (const registered of definition.skills) {
103
114
  const source = this.requireLocalSkillSource(appName, registered.name);
@@ -108,27 +119,111 @@ class AppStore {
108
119
  if (skill.mode && skill.mode !== 'chat') {
109
120
  throw MarifoldError_1.MarifoldError.appInvalid(`SkillApp v1 only supports chat-mode Skills; '${skill.name}' uses '${skill.mode}'.`, source);
110
121
  }
111
- const variables = new Set(skill.variables.map(variable => variable.name));
112
- for (const operation of definition.operations.filter(candidate => candidate.skill === registered.name)) {
113
- const parameters = new Set(Object.keys(operation.parameters));
114
- const unknown = [...parameters].filter(name => !variables.has(name));
115
- if (unknown.length > 0) {
116
- throw MarifoldError_1.MarifoldError.appInvalid(`SkillApp operation '${operation.name}' supplies unknown Skill parameter(s): ${unknown.join(', ')}.`, source);
122
+ for (const operation of definition.operations.filter(candidate => candidate.profile === undefined && candidate.skill === registered.name)) {
123
+ operation.requiredInputs = this.validateOperationBindings(skill, operation, source);
124
+ }
125
+ }
126
+ }
127
+ validateProfileSkills(definition) {
128
+ for (const operation of definition.operations.filter(candidate => candidate.profile !== undefined)) {
129
+ const profile = (definition.profiles ?? []).find(candidate => candidate.name === operation.profile);
130
+ if (!profile) {
131
+ throw MarifoldError_1.MarifoldError.appInvalid(`SkillApp operation '${operation.name}' references missing profile '${operation.profile}'.`);
132
+ }
133
+ if (!this.options.resolveProfileSkill) {
134
+ throw MarifoldError_1.MarifoldError.appInvalid(`SkillApp '${definition.app.name}' requires profile-backed Skill resolution.`);
135
+ }
136
+ const skillNames = operation.skill ? [operation.skill] : (operation.skillOptions ?? []);
137
+ if (skillNames.length === 0) {
138
+ throw MarifoldError_1.MarifoldError.appInvalid(`SkillApp operation '${operation.name}' has no profile Skill candidates.`);
139
+ }
140
+ const requiredInputs = new Set([
141
+ ...(operation.skillState ? [operation.skillState] : []),
142
+ ...(operation.input ? [operation.input] : []),
143
+ ]);
144
+ for (const skillName of skillNames) {
145
+ const skill = this.requireProfileSkill(profile.profile, skillName);
146
+ if (operation.interactive && skill.mode === 'chat') {
147
+ throw MarifoldError_1.MarifoldError.appInvalid(`Interactive SkillApp operation '${operation.name}' cannot invoke chat-mode Skill '${skillName}'.`, skill.source);
148
+ }
149
+ if (skillName === 'skillapp-builder' && !operation.interactive) {
150
+ throw MarifoldError_1.MarifoldError.appInvalid(`SkillApp operation '${operation.name}' must invoke the built-in skillapp-builder interactively.`, skill.source);
117
151
  }
118
- const missing = skill.variables
119
- .filter(variable => variable.required && variable.default === undefined && !parameters.has(variable.name))
120
- .map(variable => variable.name);
121
- if (missing.length > 0) {
122
- throw MarifoldError_1.MarifoldError.appInvalid(`SkillApp operation '${operation.name}' does not bind required Skill parameter(s): ${missing.join(', ')}.`, source);
152
+ for (const input of this.validateOperationBindings(skill, operation, skill.source)) {
153
+ requiredInputs.add(input);
123
154
  }
124
- operation.requiredInputs = [...new Set(skill.variables
125
- .filter(variable => variable.required && variable.default === undefined)
126
- .map(variable => operation.parameters[variable.name]))];
127
155
  }
156
+ operation.requiredInputs = [...requiredInputs];
157
+ }
158
+ }
159
+ validateOperationBindings(skill, operation, source) {
160
+ const variables = new Set(skill.variables.map(variable => variable.name));
161
+ const parameters = new Set(Object.keys(operation.parameters));
162
+ const unknown = [...parameters].filter(name => !variables.has(name));
163
+ if (unknown.length > 0) {
164
+ throw MarifoldError_1.MarifoldError.appInvalid(`SkillApp operation '${operation.name}' supplies unknown Skill parameter(s): ${unknown.join(', ')}.`, source);
128
165
  }
166
+ const missing = skill.variables
167
+ .filter(variable => variable.required && variable.default === undefined && !parameters.has(variable.name))
168
+ .map(variable => variable.name);
169
+ if (missing.length > 0) {
170
+ throw MarifoldError_1.MarifoldError.appInvalid(`SkillApp operation '${operation.name}' does not bind required Skill parameter(s): ${missing.join(', ')}.`, source);
171
+ }
172
+ return [...new Set([
173
+ ...(operation.input ? [operation.input] : []),
174
+ ...skill.variables
175
+ .filter(variable => variable.required && variable.default === undefined)
176
+ .map(variable => operation.parameters[variable.name]),
177
+ ])];
129
178
  }
130
179
  }
131
180
  exports.AppStore = AppStore;
181
+ function resolvePermissions(bundle, permissions, source) {
182
+ const userHome = fs.realpathSync(os.homedir());
183
+ const privateAppHome = path.join(userHome, '.marifold');
184
+ const bundleRoot = fs.realpathSync(bundle);
185
+ return permissions.map(permission => {
186
+ const requested = permission.path === '~'
187
+ ? userHome
188
+ : permission.path.startsWith('~/')
189
+ ? path.join(userHome, permission.path.slice(2))
190
+ : path.isAbsolute(permission.path)
191
+ ? permission.path
192
+ : path.join(bundle, permission.path);
193
+ let resolved;
194
+ let stat;
195
+ try {
196
+ resolved = fs.realpathSync(requested);
197
+ stat = fs.statSync(resolved);
198
+ }
199
+ catch (error) {
200
+ throw MarifoldError_1.MarifoldError.appInvalid(`Declared ${permission.kind} permission '${permission.path}' cannot be resolved: ${error instanceof Error ? error.message : String(error)}`, source);
201
+ }
202
+ if (permission.kind === 'file' && !stat.isFile()) {
203
+ throw MarifoldError_1.MarifoldError.appInvalid(`Declared file permission '${permission.path}' is not a regular file.`, source);
204
+ }
205
+ if (permission.kind === 'folder' && !stat.isDirectory()) {
206
+ throw MarifoldError_1.MarifoldError.appInvalid(`Declared folder permission '${permission.path}' is not a directory.`, source);
207
+ }
208
+ if (permission.kind === 'folder' && isBroadPermissionRoot(resolved, userHome, privateAppHome)) {
209
+ throw MarifoldError_1.MarifoldError.appInvalid(`Declared folder permission '${permission.path}' is too broad or sensitive.`, source);
210
+ }
211
+ if (isInside(resolved, privateAppHome) && !isInside(resolved, bundleRoot)) {
212
+ throw MarifoldError_1.MarifoldError.appInvalid(`Declared permission '${permission.path}' cannot expose Marifold private state.`, source);
213
+ }
214
+ return { ...permission, path: resolved };
215
+ });
216
+ }
217
+ function isBroadPermissionRoot(target, userHome, privateAppHome) {
218
+ return target === path.parse(target).root
219
+ || target === userHome
220
+ || target === privateAppHome
221
+ || isInside(privateAppHome, target);
222
+ }
223
+ function isInside(target, root) {
224
+ const relative = path.relative(root, target);
225
+ return relative === '' || (!relative.startsWith('..') && !path.isAbsolute(relative));
226
+ }
132
227
  function requireConfinedFile(bundle, source, label) {
133
228
  const bundleRoot = fs.realpathSync(bundle);
134
229
  const realSource = fs.realpathSync(source);