dna-sdk 0.4.0 → 0.6.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.
package/dist/index.d.ts CHANGED
@@ -22,8 +22,12 @@ export { ReportBuilder } from "./kernel/reports.js";
22
22
  export { serializeRawToFiles } from "./kernel/serialize-to-files.js";
23
23
  export * from "./viz/index.js";
24
24
  export { createKernelWithBuiltins, quickInstance, createRuntimeWithBuiltins, quickManifest, fromConfig } from "./bootstrap.js";
25
- export { AgentNotFound } from "./kernel/errors.js";
25
+ export { AgentNotFound, ToolNotFound, UnknownLayout } from "./kernel/errors.js";
26
26
  export { PromptLibrary, loadPrompts } from "./prompts.js";
27
+ export { ToolLibrary, loadTools } from "./tools.js";
28
+ export type { ToolSurface } from "./tools.js";
29
+ export type { LoadPromptsOptions } from "./prompts.js";
30
+ export { anchorScopesRoot, PackageScopeNotFound, DEFAULT_SUBPATH } from "./package-scope.js";
27
31
  export { loadConfig, findConfig, CONFIG_FILENAME } from "./config.js";
28
32
  export type { DnaConfig, SearchMode, EmbeddingMode } from "./config.js";
29
33
  export { sourceFromUrl, resolveDefaultFsUrl, UnsupportedSourceScheme } from "./adapters/source-url.js";
package/dist/index.js CHANGED
@@ -27,8 +27,10 @@ export * from "./viz/index.js";
27
27
  export { createKernelWithBuiltins, quickInstance, createRuntimeWithBuiltins, quickManifest, fromConfig } from "./bootstrap.js";
28
28
  // DX consumer surface (s-dx-*): fail-loud prompt building + the collapse-the-
29
29
  // shim helper + declarative port wiring.
30
- export { AgentNotFound } from "./kernel/errors.js";
30
+ export { AgentNotFound, ToolNotFound, UnknownLayout } from "./kernel/errors.js";
31
31
  export { PromptLibrary, loadPrompts } from "./prompts.js";
32
+ export { ToolLibrary, loadTools } from "./tools.js";
33
+ export { anchorScopesRoot, PackageScopeNotFound, DEFAULT_SUBPATH } from "./package-scope.js";
32
34
  export { loadConfig, findConfig, CONFIG_FILENAME } from "./config.js";
33
35
  export { sourceFromUrl, resolveDefaultFsUrl, UnsupportedSourceScheme } from "./adapters/source-url.js";
34
36
  export { HookRegistry, KNOWN_HOOK_NAMES } from "./kernel/hooks.js";
@@ -31,6 +31,41 @@ export declare class AgentNotFound extends Error {
31
31
  readonly agent: string | null;
32
32
  constructor(agent: string | null);
33
33
  }
34
+ /**
35
+ * `loadTools(scope).get(name)` was asked for a Tool that no `Tool` document in
36
+ * the scope declares (missing, renamed, or in another scope).
37
+ *
38
+ * Fail-loud contract (s-load-tools-helper), the twin of `AgentNotFound`: the
39
+ * agent-facing tool surface is data, so a miss must throw a typed error —
40
+ * never return an empty surface that would silently reach a model as a tool
41
+ * with no description.
42
+ *
43
+ * 1:1 parity with python `dna.ToolNotFound` (a `LookupError` subclass).
44
+ * Exported publicly from the package root.
45
+ */
46
+ export declare class ToolNotFound extends Error {
47
+ readonly toolName: string | null;
48
+ readonly scope: string | null;
49
+ readonly available: string[];
50
+ constructor(name: string | null, scope?: string | null, available?: string[]);
51
+ }
52
+ /**
53
+ * `buildPrompt` hit an Agent whose `layout:` names a preset the Kind does not
54
+ * offer (s-dx-named-layouts).
55
+ *
56
+ * Fail-loud DX: a typo'd layout (`persona_first` for `persona-first`) must not
57
+ * silently fall through to the Kind default and compose in the wrong order —
58
+ * it throws with the valid names listed.
59
+ *
60
+ * 1:1 parity with python `dna.UnknownLayout` (a `ValueError` subclass).
61
+ * Exported publicly from the package root.
62
+ */
63
+ export declare class UnknownLayout extends Error {
64
+ readonly layout: string;
65
+ readonly available: string[];
66
+ readonly agent: string | null;
67
+ constructor(layout: string, available?: string[], agent?: string | null);
68
+ }
34
69
  /** Base class for kernel registration validation failures. */
35
70
  export declare class KernelRegistrationError extends Error {
36
71
  constructor(message?: string);
@@ -36,6 +36,59 @@ export class AgentNotFound extends Error {
36
36
  Object.setPrototypeOf(this, new.target.prototype);
37
37
  }
38
38
  }
39
+ /**
40
+ * `loadTools(scope).get(name)` was asked for a Tool that no `Tool` document in
41
+ * the scope declares (missing, renamed, or in another scope).
42
+ *
43
+ * Fail-loud contract (s-load-tools-helper), the twin of `AgentNotFound`: the
44
+ * agent-facing tool surface is data, so a miss must throw a typed error —
45
+ * never return an empty surface that would silently reach a model as a tool
46
+ * with no description.
47
+ *
48
+ * 1:1 parity with python `dna.ToolNotFound` (a `LookupError` subclass).
49
+ * Exported publicly from the package root.
50
+ */
51
+ export class ToolNotFound extends Error {
52
+ toolName;
53
+ scope;
54
+ available;
55
+ constructor(name, scope = null, available = []) {
56
+ const where = scope ? ` in scope '${scope}'` : "";
57
+ const hint = available.length ? ` — available: ${available.join(", ")}` : "";
58
+ super(`Tool '${name}' not found${where}${hint}`);
59
+ this.name = "ToolNotFound";
60
+ this.toolName = name;
61
+ this.scope = scope;
62
+ this.available = available;
63
+ Object.setPrototypeOf(this, new.target.prototype);
64
+ }
65
+ }
66
+ /**
67
+ * `buildPrompt` hit an Agent whose `layout:` names a preset the Kind does not
68
+ * offer (s-dx-named-layouts).
69
+ *
70
+ * Fail-loud DX: a typo'd layout (`persona_first` for `persona-first`) must not
71
+ * silently fall through to the Kind default and compose in the wrong order —
72
+ * it throws with the valid names listed.
73
+ *
74
+ * 1:1 parity with python `dna.UnknownLayout` (a `ValueError` subclass).
75
+ * Exported publicly from the package root.
76
+ */
77
+ export class UnknownLayout extends Error {
78
+ layout;
79
+ available;
80
+ agent;
81
+ constructor(layout, available = [], agent = null) {
82
+ const where = agent ? ` on agent '${agent}'` : "";
83
+ const hint = available.length ? ` — available: ${available.join(", ")}` : "";
84
+ super(`Unknown layout '${layout}'${where}${hint}`);
85
+ this.name = "UnknownLayout";
86
+ this.layout = layout;
87
+ this.available = available;
88
+ this.agent = agent;
89
+ Object.setPrototypeOf(this, new.target.prototype);
90
+ }
91
+ }
39
92
  /** Base class for kernel registration validation failures. */
40
93
  export class KernelRegistrationError extends Error {
41
94
  constructor(message) {
@@ -115,7 +115,9 @@ export function generateAlias(owner, kind) {
115
115
  export const EXPLICIT_ALIAS_ALLOWLIST = new Set([
116
116
  // helix
117
117
  "helix-genome", "helix-agent", "helix-actor",
118
- "helix-usecase", "helix-tool", "policy-layer-policy",
118
+ // helix-tool migrated to a descriptor (s-tool-kind-descriptor): its alias
119
+ // lives in helix/kinds/tool.kind.yaml (parity-critical) — shrink-only.
120
+ "helix-usecase", "policy-layer-policy",
119
121
  "helix-canvas",
120
122
  "helix-setting", "helix-theme", "helix-user-profile",
121
123
  // sdlc (classes; descriptors are outside the ratchet)
@@ -94,6 +94,19 @@ export declare abstract class KindBase implements Omit<KindPort, "apiVersion" |
94
94
  describe(_doc: Document): string | null;
95
95
  summary(doc: Document): Record<string, unknown> | null;
96
96
  promptTemplate(): string | null;
97
+ /**
98
+ * Resolve a NAMED composition layout to an embedded template
99
+ * (s-dx-named-layouts). Prompt-target Kinds override this to expose
100
+ * author-friendly presets (persona-first, instruction-first) so the common
101
+ * case never hand-writes Mustache. Returns null for an unknown name (the
102
+ * prompt builder fails loud). Twin of Python ``KindBase.layout_template``.
103
+ */
104
+ layoutTemplate(_name: string): string | null;
105
+ /**
106
+ * Public layout names this Kind offers (s-dx-named-layouts) — powers
107
+ * discovery + fail-loud error messages. Twin of Python ``layout_names``.
108
+ */
109
+ layoutNames(): string[];
97
110
  protected canonicalSpec(spec: Record<string, unknown>): Record<string, unknown>;
98
111
  /** Stable SHA-256 of the doc's authored identity — basis for source
99
112
  * diff/sync. Invariant to key order, formatting, volatile stamps, and
@@ -215,6 +215,23 @@ export class KindBase {
215
215
  promptTemplate() {
216
216
  return null;
217
217
  }
218
+ /**
219
+ * Resolve a NAMED composition layout to an embedded template
220
+ * (s-dx-named-layouts). Prompt-target Kinds override this to expose
221
+ * author-friendly presets (persona-first, instruction-first) so the common
222
+ * case never hand-writes Mustache. Returns null for an unknown name (the
223
+ * prompt builder fails loud). Twin of Python ``KindBase.layout_template``.
224
+ */
225
+ layoutTemplate(_name) {
226
+ return null;
227
+ }
228
+ /**
229
+ * Public layout names this Kind offers (s-dx-named-layouts) — powers
230
+ * discovery + fail-loud error messages. Twin of Python ``layout_names``.
231
+ */
232
+ layoutNames() {
233
+ return [];
234
+ }
218
235
  // ---- Source-sync digest (s-sync-s1; twin of Python canonical_digest) ----
219
236
  canonicalSpec(spec) {
220
237
  const out = {};
@@ -384,6 +384,7 @@ export declare const AgentSpecSchema: z.ZodObject<{
384
384
  tags: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
385
385
  guardrails: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
386
386
  promptTemplate: z.ZodOptional<z.ZodString>;
387
+ layout: z.ZodOptional<z.ZodString>;
387
388
  tool_groups: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
388
389
  mcp_servers: z.ZodDefault<z.ZodArray<z.ZodUnion<[z.ZodString, z.ZodObject<{
389
390
  ref: z.ZodString;
@@ -481,6 +482,7 @@ export declare const AgentSpecSchema: z.ZodObject<{
481
482
  reads: Record<string, Record<string, any>>;
482
483
  type?: string | undefined;
483
484
  promptTemplate?: string | undefined;
485
+ layout?: string | undefined;
484
486
  model?: string | undefined;
485
487
  instruction_file?: string | undefined;
486
488
  soul?: string | undefined;
@@ -517,6 +519,7 @@ export declare const AgentSpecSchema: z.ZodObject<{
517
519
  guardrails?: string[] | undefined;
518
520
  instruction?: string | undefined;
519
521
  promptTemplate?: string | undefined;
522
+ layout?: string | undefined;
520
523
  model?: string | undefined;
521
524
  instruction_file?: string | undefined;
522
525
  tags?: string[] | undefined;
@@ -601,6 +604,7 @@ export declare const AgentSchema: z.ZodObject<{
601
604
  tags: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
602
605
  guardrails: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
603
606
  promptTemplate: z.ZodOptional<z.ZodString>;
607
+ layout: z.ZodOptional<z.ZodString>;
604
608
  tool_groups: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
605
609
  mcp_servers: z.ZodDefault<z.ZodArray<z.ZodUnion<[z.ZodString, z.ZodObject<{
606
610
  ref: z.ZodString;
@@ -698,6 +702,7 @@ export declare const AgentSchema: z.ZodObject<{
698
702
  reads: Record<string, Record<string, any>>;
699
703
  type?: string | undefined;
700
704
  promptTemplate?: string | undefined;
705
+ layout?: string | undefined;
701
706
  model?: string | undefined;
702
707
  instruction_file?: string | undefined;
703
708
  soul?: string | undefined;
@@ -734,6 +739,7 @@ export declare const AgentSchema: z.ZodObject<{
734
739
  guardrails?: string[] | undefined;
735
740
  instruction?: string | undefined;
736
741
  promptTemplate?: string | undefined;
742
+ layout?: string | undefined;
737
743
  model?: string | undefined;
738
744
  instruction_file?: string | undefined;
739
745
  tags?: string[] | undefined;
@@ -810,6 +816,7 @@ export declare const AgentSchema: z.ZodObject<{
810
816
  reads: Record<string, Record<string, any>>;
811
817
  type?: string | undefined;
812
818
  promptTemplate?: string | undefined;
819
+ layout?: string | undefined;
813
820
  model?: string | undefined;
814
821
  instruction_file?: string | undefined;
815
822
  soul?: string | undefined;
@@ -860,6 +867,7 @@ export declare const AgentSchema: z.ZodObject<{
860
867
  guardrails?: string[] | undefined;
861
868
  instruction?: string | undefined;
862
869
  promptTemplate?: string | undefined;
870
+ layout?: string | undefined;
863
871
  model?: string | undefined;
864
872
  instruction_file?: string | undefined;
865
873
  tags?: string[] | undefined;
@@ -1158,197 +1166,6 @@ export declare const UseCaseSchema: z.ZodObject<{
1158
1166
  } | undefined;
1159
1167
  }>;
1160
1168
  export type TypedUseCase = z.output<typeof UseCaseSchema>;
1161
- export declare const ToolTypeEnum: z.ZodEnum<["http", "mcp", "python", "shell", "builtin"]>;
1162
- export declare const ToolAuthTypeEnum: z.ZodEnum<["none", "api_key", "bearer", "oauth2"]>;
1163
- export declare const ToolSpecSchema: z.ZodObject<{
1164
- type: z.ZodDefault<z.ZodEnum<["http", "mcp", "python", "shell", "builtin"]>>;
1165
- endpoint: z.ZodDefault<z.ZodOptional<z.ZodString>>;
1166
- method: z.ZodDefault<z.ZodOptional<z.ZodString>>;
1167
- mcp_server: z.ZodDefault<z.ZodOptional<z.ZodString>>;
1168
- mcp_tool: z.ZodDefault<z.ZodOptional<z.ZodString>>;
1169
- python_module: z.ZodDefault<z.ZodOptional<z.ZodString>>;
1170
- python_callable: z.ZodDefault<z.ZodOptional<z.ZodString>>;
1171
- shell_command: z.ZodDefault<z.ZodOptional<z.ZodString>>;
1172
- input_schema: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
1173
- output_schema: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
1174
- auth_type: z.ZodDefault<z.ZodEnum<["none", "api_key", "bearer", "oauth2"]>>;
1175
- auth_env_var: z.ZodDefault<z.ZodOptional<z.ZodString>>;
1176
- read_only: z.ZodDefault<z.ZodBoolean>;
1177
- requires_confirmation: z.ZodDefault<z.ZodBoolean>;
1178
- tags: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
1179
- examples: z.ZodDefault<z.ZodArray<z.ZodRecord<z.ZodString, z.ZodUnknown>, "many">>;
1180
- }, "strip", z.ZodTypeAny, {
1181
- type: "http" | "mcp" | "python" | "shell" | "builtin";
1182
- tags: string[];
1183
- input_schema: Record<string, unknown>;
1184
- endpoint: string;
1185
- method: string;
1186
- mcp_server: string;
1187
- mcp_tool: string;
1188
- python_module: string;
1189
- python_callable: string;
1190
- shell_command: string;
1191
- output_schema: Record<string, unknown>;
1192
- auth_type: "none" | "api_key" | "bearer" | "oauth2";
1193
- auth_env_var: string;
1194
- read_only: boolean;
1195
- requires_confirmation: boolean;
1196
- examples: Record<string, unknown>[];
1197
- }, {
1198
- type?: "http" | "mcp" | "python" | "shell" | "builtin" | undefined;
1199
- tags?: string[] | undefined;
1200
- input_schema?: Record<string, unknown> | undefined;
1201
- endpoint?: string | undefined;
1202
- method?: string | undefined;
1203
- mcp_server?: string | undefined;
1204
- mcp_tool?: string | undefined;
1205
- python_module?: string | undefined;
1206
- python_callable?: string | undefined;
1207
- shell_command?: string | undefined;
1208
- output_schema?: Record<string, unknown> | undefined;
1209
- auth_type?: "none" | "api_key" | "bearer" | "oauth2" | undefined;
1210
- auth_env_var?: string | undefined;
1211
- read_only?: boolean | undefined;
1212
- requires_confirmation?: boolean | undefined;
1213
- examples?: Record<string, unknown>[] | undefined;
1214
- }>;
1215
- export declare const ToolSchema: z.ZodObject<{
1216
- apiVersion: z.ZodLiteral<"github.com/ruinosus/dna/v1">;
1217
- kind: z.ZodLiteral<"Tool">;
1218
- metadata: z.ZodObject<{
1219
- name: z.ZodString;
1220
- description: z.ZodDefault<z.ZodOptional<z.ZodString>>;
1221
- version: z.ZodDefault<z.ZodOptional<z.ZodString>>;
1222
- icon: z.ZodDefault<z.ZodOptional<z.ZodString>>;
1223
- group: z.ZodDefault<z.ZodOptional<z.ZodString>>;
1224
- labels: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodString>>;
1225
- }, "strip", z.ZodTypeAny, {
1226
- name: string;
1227
- description: string;
1228
- version: string;
1229
- icon: string;
1230
- group: string;
1231
- labels: Record<string, string>;
1232
- }, {
1233
- name: string;
1234
- description?: string | undefined;
1235
- version?: string | undefined;
1236
- icon?: string | undefined;
1237
- group?: string | undefined;
1238
- labels?: Record<string, string> | undefined;
1239
- }>;
1240
- spec: z.ZodDefault<z.ZodObject<{
1241
- type: z.ZodDefault<z.ZodEnum<["http", "mcp", "python", "shell", "builtin"]>>;
1242
- endpoint: z.ZodDefault<z.ZodOptional<z.ZodString>>;
1243
- method: z.ZodDefault<z.ZodOptional<z.ZodString>>;
1244
- mcp_server: z.ZodDefault<z.ZodOptional<z.ZodString>>;
1245
- mcp_tool: z.ZodDefault<z.ZodOptional<z.ZodString>>;
1246
- python_module: z.ZodDefault<z.ZodOptional<z.ZodString>>;
1247
- python_callable: z.ZodDefault<z.ZodOptional<z.ZodString>>;
1248
- shell_command: z.ZodDefault<z.ZodOptional<z.ZodString>>;
1249
- input_schema: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
1250
- output_schema: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
1251
- auth_type: z.ZodDefault<z.ZodEnum<["none", "api_key", "bearer", "oauth2"]>>;
1252
- auth_env_var: z.ZodDefault<z.ZodOptional<z.ZodString>>;
1253
- read_only: z.ZodDefault<z.ZodBoolean>;
1254
- requires_confirmation: z.ZodDefault<z.ZodBoolean>;
1255
- tags: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
1256
- examples: z.ZodDefault<z.ZodArray<z.ZodRecord<z.ZodString, z.ZodUnknown>, "many">>;
1257
- }, "strip", z.ZodTypeAny, {
1258
- type: "http" | "mcp" | "python" | "shell" | "builtin";
1259
- tags: string[];
1260
- input_schema: Record<string, unknown>;
1261
- endpoint: string;
1262
- method: string;
1263
- mcp_server: string;
1264
- mcp_tool: string;
1265
- python_module: string;
1266
- python_callable: string;
1267
- shell_command: string;
1268
- output_schema: Record<string, unknown>;
1269
- auth_type: "none" | "api_key" | "bearer" | "oauth2";
1270
- auth_env_var: string;
1271
- read_only: boolean;
1272
- requires_confirmation: boolean;
1273
- examples: Record<string, unknown>[];
1274
- }, {
1275
- type?: "http" | "mcp" | "python" | "shell" | "builtin" | undefined;
1276
- tags?: string[] | undefined;
1277
- input_schema?: Record<string, unknown> | undefined;
1278
- endpoint?: string | undefined;
1279
- method?: string | undefined;
1280
- mcp_server?: string | undefined;
1281
- mcp_tool?: string | undefined;
1282
- python_module?: string | undefined;
1283
- python_callable?: string | undefined;
1284
- shell_command?: string | undefined;
1285
- output_schema?: Record<string, unknown> | undefined;
1286
- auth_type?: "none" | "api_key" | "bearer" | "oauth2" | undefined;
1287
- auth_env_var?: string | undefined;
1288
- read_only?: boolean | undefined;
1289
- requires_confirmation?: boolean | undefined;
1290
- examples?: Record<string, unknown>[] | undefined;
1291
- }>>;
1292
- }, "strip", z.ZodTypeAny, {
1293
- metadata: {
1294
- name: string;
1295
- description: string;
1296
- version: string;
1297
- icon: string;
1298
- group: string;
1299
- labels: Record<string, string>;
1300
- };
1301
- spec: {
1302
- type: "http" | "mcp" | "python" | "shell" | "builtin";
1303
- tags: string[];
1304
- input_schema: Record<string, unknown>;
1305
- endpoint: string;
1306
- method: string;
1307
- mcp_server: string;
1308
- mcp_tool: string;
1309
- python_module: string;
1310
- python_callable: string;
1311
- shell_command: string;
1312
- output_schema: Record<string, unknown>;
1313
- auth_type: "none" | "api_key" | "bearer" | "oauth2";
1314
- auth_env_var: string;
1315
- read_only: boolean;
1316
- requires_confirmation: boolean;
1317
- examples: Record<string, unknown>[];
1318
- };
1319
- apiVersion: "github.com/ruinosus/dna/v1";
1320
- kind: "Tool";
1321
- }, {
1322
- metadata: {
1323
- name: string;
1324
- description?: string | undefined;
1325
- version?: string | undefined;
1326
- icon?: string | undefined;
1327
- group?: string | undefined;
1328
- labels?: Record<string, string> | undefined;
1329
- };
1330
- apiVersion: "github.com/ruinosus/dna/v1";
1331
- kind: "Tool";
1332
- spec?: {
1333
- type?: "http" | "mcp" | "python" | "shell" | "builtin" | undefined;
1334
- tags?: string[] | undefined;
1335
- input_schema?: Record<string, unknown> | undefined;
1336
- endpoint?: string | undefined;
1337
- method?: string | undefined;
1338
- mcp_server?: string | undefined;
1339
- mcp_tool?: string | undefined;
1340
- python_module?: string | undefined;
1341
- python_callable?: string | undefined;
1342
- shell_command?: string | undefined;
1343
- output_schema?: Record<string, unknown> | undefined;
1344
- auth_type?: "none" | "api_key" | "bearer" | "oauth2" | undefined;
1345
- auth_env_var?: string | undefined;
1346
- read_only?: boolean | undefined;
1347
- requires_confirmation?: boolean | undefined;
1348
- examples?: Record<string, unknown>[] | undefined;
1349
- } | undefined;
1350
- }>;
1351
- export type TypedTool = z.output<typeof ToolSchema>;
1352
1169
  export declare const SkillSpecSchema: z.ZodObject<{
1353
1170
  instruction: z.ZodDefault<z.ZodOptional<z.ZodString>>;
1354
1171
  scripts: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodString>>;
@@ -1551,6 +1368,83 @@ export declare const SoulSchema: z.ZodObject<{
1551
1368
  } | undefined;
1552
1369
  }>;
1553
1370
  export type TypedSoul = z.output<typeof SoulSchema>;
1371
+ export declare const HtmlArtifactSpecSchema: z.ZodObject<{
1372
+ html: z.ZodDefault<z.ZodOptional<z.ZodString>>;
1373
+ artifact_json: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
1374
+ }, "strip", z.ZodTypeAny, {
1375
+ html: string;
1376
+ artifact_json?: Record<string, unknown> | undefined;
1377
+ }, {
1378
+ html?: string | undefined;
1379
+ artifact_json?: Record<string, unknown> | undefined;
1380
+ }>;
1381
+ export declare const HtmlArtifactSchema: z.ZodObject<{
1382
+ apiVersion: z.ZodLiteral<"github.com/ruinosus/dna/sdlc/v1">;
1383
+ kind: z.ZodLiteral<"HtmlArtifact">;
1384
+ metadata: z.ZodObject<{
1385
+ name: z.ZodString;
1386
+ description: z.ZodDefault<z.ZodOptional<z.ZodString>>;
1387
+ version: z.ZodDefault<z.ZodOptional<z.ZodString>>;
1388
+ icon: z.ZodDefault<z.ZodOptional<z.ZodString>>;
1389
+ group: z.ZodDefault<z.ZodOptional<z.ZodString>>;
1390
+ labels: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodString>>;
1391
+ }, "strip", z.ZodTypeAny, {
1392
+ name: string;
1393
+ description: string;
1394
+ version: string;
1395
+ icon: string;
1396
+ group: string;
1397
+ labels: Record<string, string>;
1398
+ }, {
1399
+ name: string;
1400
+ description?: string | undefined;
1401
+ version?: string | undefined;
1402
+ icon?: string | undefined;
1403
+ group?: string | undefined;
1404
+ labels?: Record<string, string> | undefined;
1405
+ }>;
1406
+ spec: z.ZodDefault<z.ZodObject<{
1407
+ html: z.ZodDefault<z.ZodOptional<z.ZodString>>;
1408
+ artifact_json: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
1409
+ }, "strip", z.ZodTypeAny, {
1410
+ html: string;
1411
+ artifact_json?: Record<string, unknown> | undefined;
1412
+ }, {
1413
+ html?: string | undefined;
1414
+ artifact_json?: Record<string, unknown> | undefined;
1415
+ }>>;
1416
+ }, "strip", z.ZodTypeAny, {
1417
+ metadata: {
1418
+ name: string;
1419
+ description: string;
1420
+ version: string;
1421
+ icon: string;
1422
+ group: string;
1423
+ labels: Record<string, string>;
1424
+ };
1425
+ spec: {
1426
+ html: string;
1427
+ artifact_json?: Record<string, unknown> | undefined;
1428
+ };
1429
+ apiVersion: "github.com/ruinosus/dna/sdlc/v1";
1430
+ kind: "HtmlArtifact";
1431
+ }, {
1432
+ metadata: {
1433
+ name: string;
1434
+ description?: string | undefined;
1435
+ version?: string | undefined;
1436
+ icon?: string | undefined;
1437
+ group?: string | undefined;
1438
+ labels?: Record<string, string> | undefined;
1439
+ };
1440
+ apiVersion: "github.com/ruinosus/dna/sdlc/v1";
1441
+ kind: "HtmlArtifact";
1442
+ spec?: {
1443
+ html?: string | undefined;
1444
+ artifact_json?: Record<string, unknown> | undefined;
1445
+ } | undefined;
1446
+ }>;
1447
+ export type TypedHtmlArtifact = z.output<typeof HtmlArtifactSchema>;
1554
1448
  export declare const AgentDefinitionSpecSchema: z.ZodObject<{
1555
1449
  content: z.ZodDefault<z.ZodOptional<z.ZodString>>;
1556
1450
  }, "strip", z.ZodTypeAny, {
@@ -128,6 +128,12 @@ export const AgentSpecSchema = z.object({
128
128
  tags: z.array(z.string()).default([]),
129
129
  guardrails: z.array(z.string()).default([]),
130
130
  promptTemplate: z.string().optional(),
131
+ // s-dx-named-layouts — pick the composition ORDER by name instead of
132
+ // hand-writing raw Mustache. "persona-first" puts the Soul before the
133
+ // instruction; "instruction-first" (a.k.a. "default") keeps the historic
134
+ // order. Resolved by the Kind's layoutTemplate() into an embedded preset.
135
+ // A raw promptTemplate still wins over layout when both are set.
136
+ layout: z.string().optional(),
131
137
  // Phase 14x — tool-group specialization (TS parity with Python).
132
138
  tool_groups: z.array(z.string()).default([]),
133
139
  // s-mcp-servers-on-agent (2026-07-07, spec
@@ -329,38 +335,6 @@ export const UseCaseSchema = z.object({
329
335
  spec: UseCaseSpecSchema.default({}),
330
336
  });
331
337
  // ---------------------------------------------------------------------------
332
- // Tool (github.com/ruinosus/dna/v1)
333
- //
334
- // Declarative, invocable capability an agent can call. Bridges helix with
335
- // OpenAI/Anthropic tool-calling conventions.
336
- // ---------------------------------------------------------------------------
337
- export const ToolTypeEnum = z.enum(["http", "mcp", "python", "shell", "builtin"]);
338
- export const ToolAuthTypeEnum = z.enum(["none", "api_key", "bearer", "oauth2"]);
339
- export const ToolSpecSchema = z.object({
340
- type: ToolTypeEnum.default("builtin"),
341
- endpoint: z.string().optional().default(""),
342
- method: z.string().optional().default("POST"),
343
- mcp_server: z.string().optional().default(""),
344
- mcp_tool: z.string().optional().default(""),
345
- python_module: z.string().optional().default(""),
346
- python_callable: z.string().optional().default(""),
347
- shell_command: z.string().optional().default(""),
348
- input_schema: z.record(z.unknown()).default({}),
349
- output_schema: z.record(z.unknown()).default({}),
350
- auth_type: ToolAuthTypeEnum.default("none"),
351
- auth_env_var: z.string().optional().default(""),
352
- read_only: z.boolean().default(true),
353
- requires_confirmation: z.boolean().default(false),
354
- tags: z.array(z.string()).default([]),
355
- examples: z.array(z.record(z.unknown())).default([]),
356
- });
357
- export const ToolSchema = z.object({
358
- apiVersion: z.literal("github.com/ruinosus/dna/v1"),
359
- kind: z.literal("Tool"),
360
- metadata: MetadataSchema,
361
- spec: ToolSpecSchema.default({}),
362
- });
363
- // ---------------------------------------------------------------------------
364
338
  // Skill (agentskills.io/v1)
365
339
  // ---------------------------------------------------------------------------
366
340
  export const SkillSpecSchema = z.object({
@@ -393,6 +367,19 @@ export const SoulSchema = z.object({
393
367
  spec: SoulSpecSchema.default({}),
394
368
  });
395
369
  // ---------------------------------------------------------------------------
370
+ // HtmlArtifact (github.com/ruinosus/dna/sdlc/v1)
371
+ // ---------------------------------------------------------------------------
372
+ export const HtmlArtifactSpecSchema = z.object({
373
+ html: z.string().optional().default(""),
374
+ artifact_json: z.record(z.unknown()).optional(),
375
+ });
376
+ export const HtmlArtifactSchema = z.object({
377
+ apiVersion: z.literal("github.com/ruinosus/dna/sdlc/v1"),
378
+ kind: z.literal("HtmlArtifact"),
379
+ metadata: MetadataSchema,
380
+ spec: HtmlArtifactSpecSchema.default({}),
381
+ });
382
+ // ---------------------------------------------------------------------------
396
383
  // AgentDefinition (agents.md/v1)
397
384
  // ---------------------------------------------------------------------------
398
385
  export const AgentDefinitionSpecSchema = z.object({
@@ -10,7 +10,7 @@
10
10
  */
11
11
  import Mustache from "mustache";
12
12
  import { stripPromptBlock } from "./_text.js";
13
- import { AgentNotFound } from "./errors.js";
13
+ import { AgentNotFound, UnknownLayout } from "./errors.js";
14
14
  // ---------------------------------------------------------------------------
15
15
  // PromptBuilder
16
16
  // ---------------------------------------------------------------------------
@@ -206,22 +206,33 @@ export class PromptBuilder {
206
206
  async _renderPrompt(ctx, agentDoc) {
207
207
  const agentSpec = agentDoc.spec;
208
208
  const kinds = this.host._kinds;
209
- // 1. Agent-level template override
209
+ // 1. Agent-level raw template override (poweruser escape hatch).
210
210
  const agentTemplate = agentSpec.promptTemplate ??
211
211
  agentSpec.prompt_template ??
212
212
  null;
213
213
  if (agentTemplate) {
214
214
  return await this._mustacheRender(agentTemplate, ctx);
215
215
  }
216
- // 2. Kind default template
217
216
  const agentKp = kinds.get(`${agentDoc.apiVersion}\0${agentDoc.kind}`);
217
+ // 2. Named layout preset (s-dx-named-layouts) — author picks the
218
+ // composition order by NAME; the kernel resolves it to an embedded
219
+ // template so the common case never hand-writes Mustache.
220
+ const layout = agentSpec.layout;
221
+ if (layout && agentKp) {
222
+ const layoutTmpl = agentKp.layoutTemplate(layout);
223
+ if (layoutTmpl == null) {
224
+ throw new UnknownLayout(layout, agentKp.layoutNames(), agentDoc.name);
225
+ }
226
+ return await this._mustacheRender(layoutTmpl, ctx);
227
+ }
228
+ // 3. Kind default template
218
229
  if (agentKp) {
219
230
  const kindTemplate = agentKp.promptTemplate();
220
231
  if (kindTemplate) {
221
232
  return await this._mustacheRender(kindTemplate, ctx);
222
233
  }
223
234
  }
224
- // 3. Fallback: agent instruction as plain text
235
+ // 4. Fallback: agent instruction as plain text
225
236
  const agent = ctx.agent;
226
237
  return agent?.instruction ?? "";
227
238
  }
@@ -0,0 +1,18 @@
1
+ /** The conventional scopes-root sub-directory inside a package (matches the
2
+ * repo's own `.dna/<scope>/` layout). */
3
+ export declare const DEFAULT_SUBPATH = ".dna";
4
+ /** Raised when an `anchor` package / subpath can't be resolved to a real
5
+ * on-disk scopes-root directory. */
6
+ export declare class PackageScopeNotFound extends Error {
7
+ constructor(message: string);
8
+ }
9
+ /**
10
+ * Resolve the `.dna` scopes-root embedded in package `anchor`.
11
+ *
12
+ * `anchor` is a resolvable package specifier (e.g. `"app"`); `subpath` is the
13
+ * scopes-root dir inside it (default `.dna`). Returns the concrete filesystem
14
+ * path of `<anchor-package>/<subpath>` — the `baseDir` a FilesystemSource
15
+ * consumes. Fails loud (`PackageScopeNotFound`) when the package cannot be
16
+ * resolved or the subpath does not exist in the installed package.
17
+ */
18
+ export declare function anchorScopesRoot(anchor: string, subpath?: string): string;