@loomweaver/devkit 0.7.5 → 0.7.7

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 (80) hide show
  1. package/package.json +1 -1
  2. package/src/generators/auth-source/generator.js +4 -7
  3. package/src/generators/auth-source/generator.js.map +1 -1
  4. package/src/generators/distribution/generator.js +51 -53
  5. package/src/generators/distribution/generator.js.map +1 -1
  6. package/src/generators/distribution/nx-files.js +23 -16
  7. package/src/generators/distribution/nx-files.js.map +1 -1
  8. package/src/generators/frame-plugin/generator.js +7 -10
  9. package/src/generators/frame-plugin/generator.js.map +1 -1
  10. package/src/generators/layout/generator.js +4 -7
  11. package/src/generators/layout/generator.js.map +1 -1
  12. package/src/generators/nx-scaffold-shared.js +2 -3
  13. package/src/generators/nx-scaffold-shared.js.map +1 -1
  14. package/src/generators/settings-store/generator.js +4 -7
  15. package/src/generators/settings-store/generator.js.map +1 -1
  16. package/src/generators/shared.d.ts +1 -1
  17. package/src/generators/shared.js +23 -20
  18. package/src/generators/shared.js.map +1 -1
  19. package/src/generators/theme/generator.js +4 -7
  20. package/src/generators/theme/generator.js.map +1 -1
  21. package/src/generators/weaver/generator.d.ts +2 -2
  22. package/src/generators/weaver/generator.js +66 -56
  23. package/src/generators/weaver/generator.js.map +1 -1
  24. package/src/generators/weaver/nx-files.js +20 -15
  25. package/src/generators/weaver/nx-files.js.map +1 -1
  26. package/src/generators/weaver/schema.json +5 -0
  27. package/src/index.d.ts +6 -6
  28. package/src/index.js +2 -1
  29. package/src/index.js.map +1 -1
  30. package/src/lib/amend/compose.js +37 -8
  31. package/src/lib/amend/compose.js.map +1 -1
  32. package/src/lib/amend/describe.js +3 -0
  33. package/src/lib/amend/describe.js.map +1 -1
  34. package/src/lib/amend/merge.d.ts +8 -1
  35. package/src/lib/amend/merge.js +64 -22
  36. package/src/lib/amend/merge.js.map +1 -1
  37. package/src/lib/amend/types.d.ts +12 -1
  38. package/src/lib/generate/generate.js +2 -3
  39. package/src/lib/generate/generate.js.map +1 -1
  40. package/src/lib/scaffolds/inputs.d.ts +1 -0
  41. package/src/lib/scaffolds/inputs.js +5 -5
  42. package/src/lib/scaffolds/inputs.js.map +1 -1
  43. package/src/lib/scaffolds/scaffolds.js +24 -18
  44. package/src/lib/scaffolds/scaffolds.js.map +1 -1
  45. package/src/lib/validate/catalog.js +20 -6
  46. package/src/lib/validate/catalog.js.map +1 -1
  47. package/src/lib/validate/i18n.js +1 -1
  48. package/src/lib/validate/i18n.js.map +1 -1
  49. package/src/recipes/angular-distribution/recipe.js +16 -5
  50. package/src/recipes/angular-distribution/recipe.js.map +1 -1
  51. package/src/recipes/angular-weaver/agent-files.d.ts +12 -0
  52. package/src/recipes/angular-weaver/agent-files.js +169 -0
  53. package/src/recipes/angular-weaver/agent-files.js.map +1 -0
  54. package/src/recipes/angular-weaver/agent-panel.d.ts +3 -0
  55. package/src/recipes/angular-weaver/agent-panel.js +193 -0
  56. package/src/recipes/angular-weaver/agent-panel.js.map +1 -0
  57. package/src/recipes/angular-weaver/agent-stand-in.d.ts +2 -0
  58. package/src/recipes/angular-weaver/agent-stand-in.js +93 -0
  59. package/src/recipes/angular-weaver/agent-stand-in.js.map +1 -0
  60. package/src/recipes/angular-weaver/amendments.d.ts +1 -1
  61. package/src/recipes/angular-weaver/amendments.js +19 -2
  62. package/src/recipes/angular-weaver/amendments.js.map +1 -1
  63. package/src/recipes/angular-weaver/recipe.d.ts +2 -0
  64. package/src/recipes/angular-weaver/recipe.js +48 -136
  65. package/src/recipes/angular-weaver/recipe.js.map +1 -1
  66. package/src/recipes/angular-weaver/weaver-i18n.d.ts +1 -1
  67. package/src/recipes/angular-weaver/weaver-i18n.js +11 -0
  68. package/src/recipes/angular-weaver/weaver-i18n.js.map +1 -1
  69. package/src/recipes/angular-weaver/weaver-readme.d.ts +2 -0
  70. package/src/recipes/angular-weaver/weaver-readme.js +142 -0
  71. package/src/recipes/angular-weaver/weaver-readme.js.map +1 -0
  72. package/src/recipes/angular-weaver/weaver-terms.d.ts +2 -0
  73. package/src/recipes/angular-weaver/weaver-terms.js +9 -0
  74. package/src/recipes/angular-weaver/weaver-terms.js.map +1 -0
  75. package/src/recipes/frame-plugin/recipe.js +1 -2
  76. package/src/recipes/frame-plugin/recipe.js.map +1 -1
  77. package/src/recipes/layout/recipe.js +2 -3
  78. package/src/recipes/layout/recipe.js.map +1 -1
  79. package/src/recipes/theme/recipe.js +1 -2
  80. package/src/recipes/theme/recipe.js.map +1 -1
@@ -9,11 +9,10 @@ const logo_1 = require("./logo");
9
9
  const readme_1 = require("./readme");
10
10
  const STYLES = ['tailwind', 'precompiled'];
11
11
  function resolveDistributionInput(input) {
12
- var _a, _b;
13
12
  if (!(0, casing_1.isKebabId)(input.name)) {
14
13
  throw new Error(`Distribution name must be kebab-case (e.g. "acme-studio"); got "${input.name}".`);
15
14
  }
16
- const styles = (_a = input.styles) !== null && _a !== void 0 ? _a : 'tailwind';
15
+ const styles = input.styles ?? 'tailwind';
17
16
  if (!STYLES.includes(styles)) {
18
17
  throw new Error(`Unknown styles option "${styles}"; expected one of ${STYLES.join(', ')}.`);
19
18
  }
@@ -23,7 +22,7 @@ function resolveDistributionInput(input) {
23
22
  const depth = directory.split('/').filter(Boolean).length;
24
23
  return {
25
24
  name: input.name,
26
- title: ((_b = input.title) === null || _b === void 0 ? void 0 : _b.trim()) || (0, casing_1.toTitleCase)(input.name),
25
+ title: input.title?.trim() || (0, casing_1.toTitleCase)(input.name),
27
26
  nodeModulesFromSrc: `${'../'.repeat(depth + 1)}node_modules`,
28
27
  withTests: input.withTests !== false,
29
28
  styles,
@@ -54,7 +53,7 @@ import { provideProductIdentity } from '@loomweaver/plugin-sdk';
54
53
  'status-bar' (bar) are what the scaffolded weaver targets. */
55
54
  export const layout: ShellLayout = {
56
55
  regions: [
57
- ${(0, shell_regions_1.renderRegions)(' ')}
56
+ ${(0, shell_regions_1.renderRegions)(' '.repeat(4))}
58
57
  ],
59
58
  };
60
59
 
@@ -227,7 +226,19 @@ exports.angularDistribution = {
227
226
  },
228
227
  build(input) {
229
228
  const d = resolveDistributionInput(input);
230
- return Object.assign(Object.assign({ 'src/main.ts': mainTs(), 'src/app/app.config.ts': appConfigTs(d) }, (d.withTests ? { 'src/app/app.config.spec.ts': appConfigSpec() } : {})), { 'src/app/app.ts': appTs(), 'src/app/app.html': appHtml(), 'src/index.html': indexHtml(d), 'src/styles.css': stylesCss(d), 'public/logo.svg': logo_1.PLACEHOLDER_LOGO_SVG, 'public/manifest.webmanifest': manifest(d) + '\n', 'ngsw-config.json': ngswConfig() + '\n', 'LOOMWEAVER.md': (0, readme_1.readme)(d) });
229
+ return {
230
+ 'src/main.ts': mainTs(),
231
+ 'src/app/app.config.ts': appConfigTs(d),
232
+ ...(d.withTests && { 'src/app/app.config.spec.ts': appConfigSpec() }),
233
+ 'src/app/app.ts': appTs(),
234
+ 'src/app/app.html': appHtml(),
235
+ 'src/index.html': indexHtml(d),
236
+ 'src/styles.css': stylesCss(d),
237
+ 'public/logo.svg': logo_1.PLACEHOLDER_LOGO_SVG,
238
+ 'public/manifest.webmanifest': manifest(d) + '\n',
239
+ 'ngsw-config.json': ngswConfig() + '\n',
240
+ 'LOOMWEAVER.md': (0, readme_1.readme)(d),
241
+ };
231
242
  },
232
243
  };
233
244
  //# sourceMappingURL=recipe.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"recipe.js","sourceRoot":"","sources":["../../../../../../../libs/tooling/devkit/src/recipes/angular-distribution/recipe.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"recipe.js","sourceRoot":"","sources":["../../../../../../../libs/tooling/devkit/src/recipes/angular-distribution/recipe.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ import { FileMap } from '../../lib/generate/types';
2
+ import type { ResolvedWeaver } from './recipe';
3
+ /**
4
+ * The adapter is published on the platform's own version line, so a generated weaver asks for the
5
+ * version of the generator that wrote it. The protocol package is pinned to the range the adapter
6
+ * declares as a peer: two different ranges resolve to two copies, and an event built by one is not
7
+ * the event the other switches on. `check-agent-versions` fails the build when either drifts.
8
+ */
9
+ export declare const AG_UI_ADAPTER_VERSION = "0.7.7";
10
+ export declare const AG_UI_PROTOCOL_VERSION = "0.0.x";
11
+ export declare function agentSurfaceBlock(w: ResolvedWeaver): string;
12
+ export declare function agentFiles(w: ResolvedWeaver): FileMap;
@@ -0,0 +1,169 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.AG_UI_PROTOCOL_VERSION = exports.AG_UI_ADAPTER_VERSION = void 0;
4
+ exports.agentSurfaceBlock = agentSurfaceBlock;
5
+ exports.agentFiles = agentFiles;
6
+ const agent_panel_1 = require("./agent-panel");
7
+ const agent_stand_in_1 = require("./agent-stand-in");
8
+ /**
9
+ * The adapter is published on the platform's own version line, so a generated weaver asks for the
10
+ * version of the generator that wrote it. The protocol package is pinned to the range the adapter
11
+ * declares as a peer: two different ranges resolve to two copies, and an event built by one is not
12
+ * the event the other switches on. `check-agent-versions` fails the build when either drifts.
13
+ */
14
+ exports.AG_UI_ADAPTER_VERSION = '0.7.7';
15
+ exports.AG_UI_PROTOCOL_VERSION = '0.0.x';
16
+ function connectionFile(w) {
17
+ return `import { signal } from '@angular/core';
18
+ import {
19
+ commandTools,
20
+ type CommandTools,
21
+ type PendingToolCall,
22
+ type ToolDecision,
23
+ } from '@loomweaver/ag-ui';
24
+ import type { PluginContext } from '@loomweaver/plugin-sdk';
25
+
26
+ // Commands an agent may not run on its own word. Each one asks the person at the keyboard first, and
27
+ // declining stops it: the workbench never sees the call. This weaver's own command is listed as an
28
+ // example — replace it with the ones that actually cost something.
29
+ const CONSEQUENTIAL = new Set(['${w.id}.hello']);
30
+
31
+ // A factory, not a module-level connection: everything a run needs lives in the closure, so a second
32
+ // one never shares state with the first.
33
+ export function ${w.propertyName}Connection(ctx: PluginContext): CommandTools {
34
+ return commandTools(ctx, { before: (call) => decide(ctx, call) });
35
+ }
36
+
37
+ // The one connection this plugin activates, published for its panel. Set in activate(), cleared in
38
+ // deactivate(), so the panel renders an honest empty state either side of that.
39
+ export const ${w.propertyName}Agent = signal<CommandTools | null>(null);
40
+
41
+ async function decide(
42
+ ctx: PluginContext,
43
+ call: PendingToolCall,
44
+ ): Promise<ToolDecision> {
45
+ if (!CONSEQUENTIAL.has(call.commandId)) {
46
+ return { decision: 'run' };
47
+ }
48
+ const yes = await ctx.ui.confirm({
49
+ title: '${w.id}.agent.confirm.title',
50
+ message: '${w.id}.agent.confirm.message',
51
+ confirmLabel: '${w.id}.agent.confirm.yes',
52
+ cancelLabel: '${w.id}.agent.confirm.no',
53
+ tone: 'warning',
54
+ });
55
+ // A decision can only narrow. Letting a call through does not make it reachable: the workbench
56
+ // still refuses whatever it always refused.
57
+ return yes
58
+ ? { decision: 'run' }
59
+ : { decision: 'decline', reason: 'the person at the keyboard said no.' };
60
+ }
61
+ `;
62
+ }
63
+ function specFile(w) {
64
+ return `import { EventType, type BaseEvent } from '@ag-ui/core';
65
+ import type { CommandArguments, PluginContext } from '@loomweaver/plugin-sdk';
66
+ import { ${w.propertyName}Connection } from './${w.id}-agent';
67
+
68
+ interface Asked {
69
+ readonly id: string;
70
+ readonly args?: CommandArguments;
71
+ }
72
+
73
+ function contextThat(confirms: boolean, ran: Asked[]): PluginContext {
74
+ return {
75
+ invocableCommands: () => [
76
+ { id: '${w.id}.hello', title: '${w.name} action', description: 'Shows a short message.' },
77
+ ],
78
+ invokeCommand: (id: string, args?: CommandArguments) => {
79
+ ran.push({ id, args });
80
+ return Promise.resolve({ outcome: 'answered', value: 'it ran' });
81
+ },
82
+ ui: { confirm: () => Promise.resolve(confirms) },
83
+ } as unknown as PluginContext;
84
+ }
85
+
86
+ function event(type: EventType, fields: Record<string, unknown>): BaseEvent {
87
+ return { type, ...fields } as unknown as BaseEvent;
88
+ }
89
+
90
+ describe('${w.propertyName}Connection', () => {
91
+ it('offers what the workbench offers', () => {
92
+ const tools = ${w.propertyName}Connection(contextThat(true, []));
93
+ expect(tools.list().map((tool) => tool.name)).toEqual(['${w.id}.hello']);
94
+ });
95
+
96
+ it('assembles a call from its events and answers with the outcome', async () => {
97
+ const ran: Asked[] = [];
98
+ const tools = ${w.propertyName}Connection(contextThat(true, ran));
99
+
100
+ expect(
101
+ await tools.receive(
102
+ event(EventType.TOOL_CALL_START, {
103
+ toolCallId: 'c1',
104
+ toolCallName: '${w.id}.hello',
105
+ }),
106
+ ),
107
+ ).toBeNull();
108
+ await tools.receive(
109
+ event(EventType.TOOL_CALL_ARGS, { toolCallId: 'c1', delta: '{"who"' }),
110
+ );
111
+ await tools.receive(
112
+ event(EventType.TOOL_CALL_ARGS, { toolCallId: 'c1', delta: ':"you"}' }),
113
+ );
114
+ const answer = await tools.receive(
115
+ event(EventType.TOOL_CALL_END, { toolCallId: 'c1' }),
116
+ );
117
+
118
+ expect(ran).toEqual([{ id: '${w.id}.hello', args: { who: 'you' } }]);
119
+ expect(answer?.content).toBe('it ran');
120
+ expect(answer?.error).toBeUndefined();
121
+ });
122
+
123
+ it('never reaches the workbench when a consequential call is declined', async () => {
124
+ const ran: Asked[] = [];
125
+ const tools = ${w.propertyName}Connection(contextThat(false, ran));
126
+
127
+ await tools.receive(
128
+ event(EventType.TOOL_CALL_START, {
129
+ toolCallId: 'c2',
130
+ toolCallName: '${w.id}.hello',
131
+ }),
132
+ );
133
+ await tools.receive(
134
+ event(EventType.TOOL_CALL_ARGS, { toolCallId: 'c2', delta: '{}' }),
135
+ );
136
+ const answer = await tools.receive(
137
+ event(EventType.TOOL_CALL_END, { toolCallId: 'c2' }),
138
+ );
139
+
140
+ expect(ran).toEqual([]);
141
+ expect(answer?.error).toContain('did not run');
142
+ });
143
+ });
144
+ `;
145
+ }
146
+ function agentSurfaceBlock(w) {
147
+ return [
148
+ ' ctx.registerSurface({',
149
+ ` id: '${w.id}.agent',`,
150
+ ` title: '${w.id}.agent.title',`,
151
+ ` icon: '${w.id}',`,
152
+ " docks: ['right-panel'],",
153
+ ` component: ${w.className}AgentPanel,`,
154
+ ' });',
155
+ ].join('\n');
156
+ }
157
+ function agentFiles(w) {
158
+ const files = {
159
+ [`src/lib/agent/${w.id}-agent.ts`]: connectionFile(w),
160
+ [`src/lib/agent/${w.id}-agent-source.ts`]: (0, agent_stand_in_1.standInFile)(w),
161
+ [`src/lib/agent/${w.id}-agent-panel.ts`]: (0, agent_panel_1.panelFile)(w),
162
+ [`src/lib/agent/${w.id}-agent-panel.html`]: (0, agent_panel_1.panelTemplateFile)(w),
163
+ };
164
+ if (w.features.spec) {
165
+ files[`src/lib/agent/${w.id}-agent.spec.ts`] = specFile(w);
166
+ }
167
+ return files;
168
+ }
169
+ //# sourceMappingURL=agent-files.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-files.js","sourceRoot":"","sources":["../../../../../../../libs/tooling/devkit/src/recipes/angular-weaver/agent-files.ts"],"names":[],"mappings":";;;AAkJA,8CAUC;AAED,gCAWC;AAvKD,+CAA6D;AAC7D,qDAA+C;AAE/C;;;;;GAKG;AACU,QAAA,qBAAqB,GAAG,OAAO,CAAC;AAChC,QAAA,sBAAsB,GAAG,OAAO,CAAC;AAE9C,SAAS,cAAc,CAAC,CAAiB;IACvC,OAAO;;;;;;;;;;;;kCAYyB,CAAC,CAAC,EAAE;;;;kBAIpB,CAAC,CAAC,YAAY;;;;;;eAMjB,CAAC,CAAC,YAAY;;;;;;;;;;cAUf,CAAC,CAAC,EAAE;gBACF,CAAC,CAAC,EAAE;qBACC,CAAC,CAAC,EAAE;oBACL,CAAC,CAAC,EAAE;;;;;;;;;CASvB,CAAC;AACF,CAAC;AAED,SAAS,QAAQ,CAAC,CAAiB;IACjC,OAAO;;WAEE,CAAC,CAAC,YAAY,wBAAwB,CAAC,CAAC,EAAE;;;;;;;;;;eAUtC,CAAC,CAAC,EAAE,oBAAoB,CAAC,CAAC,IAAI;;;;;;;;;;;;;;YAcjC,CAAC,CAAC,YAAY;;oBAEN,CAAC,CAAC,YAAY;8DAC4B,CAAC,CAAC,EAAE;;;;;oBAK9C,CAAC,CAAC,YAAY;;;;;;2BAMP,CAAC,CAAC,EAAE;;;;;;;;;;;;;;kCAcG,CAAC,CAAC,EAAE;;;;;;;oBAOlB,CAAC,CAAC,YAAY;;;;;yBAKT,CAAC,CAAC,EAAE;;;;;;;;;;;;;;CAc5B,CAAC;AACF,CAAC;AAED,SAAgB,iBAAiB,CAAC,CAAiB;IACjD,OAAO;QACL,2BAA2B;QAC3B,cAAc,CAAC,CAAC,EAAE,UAAU;QAC5B,iBAAiB,CAAC,CAAC,EAAE,gBAAgB;QACrC,gBAAgB,CAAC,CAAC,EAAE,IAAI;QACxB,+BAA+B;QAC/B,oBAAoB,CAAC,CAAC,SAAS,aAAa;QAC5C,SAAS;KACV,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACf,CAAC;AAED,SAAgB,UAAU,CAAC,CAAiB;IAC1C,MAAM,KAAK,GAA2B;QACpC,CAAC,iBAAiB,CAAC,CAAC,EAAE,WAAW,CAAC,EAAE,cAAc,CAAC,CAAC,CAAC;QACrD,CAAC,iBAAiB,CAAC,CAAC,EAAE,kBAAkB,CAAC,EAAE,IAAA,4BAAW,EAAC,CAAC,CAAC;QACzD,CAAC,iBAAiB,CAAC,CAAC,EAAE,iBAAiB,CAAC,EAAE,IAAA,uBAAS,EAAC,CAAC,CAAC;QACtD,CAAC,iBAAiB,CAAC,CAAC,EAAE,mBAAmB,CAAC,EAAE,IAAA,+BAAiB,EAAC,CAAC,CAAC;KACjE,CAAC;IACF,IAAI,CAAC,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;QACpB,KAAK,CAAC,iBAAiB,CAAC,CAAC,EAAE,gBAAgB,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;IAC7D,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { ResolvedWeaver } from './recipe';
2
+ export declare function panelFile(w: ResolvedWeaver): string;
3
+ export declare function panelTemplateFile(w: ResolvedWeaver): string;
@@ -0,0 +1,193 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.panelFile = panelFile;
4
+ exports.panelTemplateFile = panelTemplateFile;
5
+ function panelFile(w) {
6
+ return `import { ChangeDetectionStrategy, Component, signal } from '@angular/core';
7
+ import { EventType, type BaseEvent, type Tool } from '@ag-ui/core';
8
+ import { ${w.propertyName}Agent } from './${w.id}-agent';
9
+ import { askAgent } from './${w.id}-agent-source';
10
+
11
+ interface Line {
12
+ readonly kind: 'you' | 'agent' | 'call' | 'result' | 'note';
13
+ readonly text: string;
14
+ readonly args?: string;
15
+ readonly failed?: boolean;
16
+ }
17
+
18
+ @Component({
19
+ selector: '${w.prefix}-${w.id}-agent-panel',
20
+ templateUrl: './${w.id}-agent-panel.html',
21
+ changeDetection: ChangeDetectionStrategy.OnPush,
22
+ })
23
+ export class ${w.className}AgentPanel {
24
+ protected readonly offered = signal<readonly Tool[]>([]);
25
+
26
+ protected readonly lines = signal<readonly Line[]>([]);
27
+
28
+ protected readonly busy = signal(false);
29
+
30
+ private runs = 0;
31
+
32
+ constructor() {
33
+ this.offered.set(${w.propertyName}Agent()?.list() ?? []);
34
+ }
35
+
36
+ protected async ask(name: string): Promise<void> {
37
+ const tools = ${w.propertyName}Agent();
38
+ if (!tools || this.busy()) {
39
+ return;
40
+ }
41
+ this.busy.set(true);
42
+ try {
43
+ // Ask for the list again, every run. What a plugin may reach changes as plugins load and the
44
+ // session changes, and a list kept from earlier offers actions that are no longer there.
45
+ const offered = tools.list();
46
+ this.offered.set(offered);
47
+ this.push({ kind: 'you', text: \`Run \${name}\` });
48
+ this.push({ kind: 'note', text: \`\${offered.length} tool(s) offered right now\` });
49
+
50
+ const request = {
51
+ runId: \`run-\${++this.runs}\`,
52
+ prompt: name,
53
+ tools: offered,
54
+ };
55
+ for await (const event of askAgent(request)) {
56
+ this.draw(event);
57
+ // Every event goes over, unfiltered. The adapter decides which ones matter; a filter here is
58
+ // how a call ends up half-assembled.
59
+ const message = await tools.receive(event);
60
+ if (message) {
61
+ this.push({
62
+ kind: 'result',
63
+ text: message.error ?? message.content,
64
+ failed: Boolean(message.error),
65
+ });
66
+ }
67
+ }
68
+ // A run that ends without its closing event leaves a call open; flush() answers it.
69
+ const last = await tools.flush();
70
+ if (last) {
71
+ this.push({
72
+ kind: 'result',
73
+ text: last.error ?? last.content,
74
+ failed: Boolean(last.error),
75
+ });
76
+ }
77
+ } finally {
78
+ this.busy.set(false);
79
+ }
80
+ }
81
+
82
+ private draw(event: BaseEvent): void {
83
+ const raw = event as unknown as Record<string, unknown>;
84
+ switch (event.type) {
85
+ case EventType.TEXT_MESSAGE_START:
86
+ this.push({ kind: 'agent', text: '' });
87
+ break;
88
+ case EventType.TEXT_MESSAGE_CONTENT:
89
+ this.grow('text', String(raw['delta'] ?? ''));
90
+ break;
91
+ case EventType.TOOL_CALL_START:
92
+ this.push({
93
+ kind: 'call',
94
+ text: String(raw['toolCallName'] ?? ''),
95
+ args: '',
96
+ });
97
+ break;
98
+ case EventType.TOOL_CALL_ARGS:
99
+ this.grow('args', String(raw['delta'] ?? ''));
100
+ break;
101
+ default:
102
+ break;
103
+ }
104
+ }
105
+
106
+ private push(line: Line): void {
107
+ this.lines.update((all) => [...all, line]);
108
+ }
109
+
110
+ private grow(field: 'text' | 'args', delta: string): void {
111
+ this.lines.update((all) => {
112
+ const last = all[all.length - 1];
113
+ return [
114
+ ...all.slice(0, -1),
115
+ { ...last, [field]: \`\${last[field] ?? ''}\${delta}\` },
116
+ ];
117
+ });
118
+ }
119
+ }
120
+ `;
121
+ }
122
+ function panelTemplateFile(w) {
123
+ return `<div class="flex h-full flex-col gap-3">
124
+ <p
125
+ class="shrink-0 rounded-md border border-border bg-surface-raised px-3 py-2 text-xs text-content-muted"
126
+ >
127
+ This is a stand-in, not an assistant. It speaks the protocol so you can watch the whole path;
128
+ replace <code class="text-content">${w.id}-agent-source.ts</code> with your own transport.
129
+ </p>
130
+
131
+ <div class="min-h-0 flex-1 overflow-auto">
132
+ <ul class="flex flex-col gap-2.5">
133
+ @for (line of lines(); track $index) {
134
+ @if (line.kind === 'you') {
135
+ <li class="max-w-full self-end rounded-lg bg-brand-fill px-3 py-2 text-sm text-on-brand">
136
+ {{ line.text }}
137
+ </li>
138
+ } @else if (line.kind === 'agent') {
139
+ <li
140
+ class="max-w-full self-start rounded-lg bg-surface-raised px-3 py-2 text-sm text-content"
141
+ >
142
+ {{ line.text }}
143
+ </li>
144
+ } @else if (line.kind === 'call') {
145
+ <li
146
+ class="rounded-md border border-border px-3 py-2 font-mono text-xs break-all text-content-muted"
147
+ >
148
+ {{ line.text }}<span class="text-content-faint">({{ line.args }})</span>
149
+ </li>
150
+ } @else if (line.kind === 'result') {
151
+ <li
152
+ class="px-1 text-xs"
153
+ [class.text-negative]="line.failed"
154
+ [class.text-content-muted]="!line.failed"
155
+ >
156
+ {{ line.text }}
157
+ </li>
158
+ } @else {
159
+ <li class="px-1 text-xs text-content-faint">{{ line.text }}</li>
160
+ }
161
+ } @empty {
162
+ <li class="px-1 py-6 text-center text-sm text-content-muted">
163
+ Pick something below and watch the call go through.
164
+ </li>
165
+ }
166
+ </ul>
167
+ </div>
168
+
169
+ <div class="flex shrink-0 flex-col gap-2 border-t border-border pt-3">
170
+ <span class="px-1 text-xs font-medium text-content-muted">
171
+ Offered right now ({{ offered().length }})
172
+ </span>
173
+ @for (tool of offered(); track tool.name) {
174
+ <button
175
+ type="button"
176
+ class="lw-btn lw-btn--default lw-btn--sm h-auto justify-start py-2 text-left whitespace-normal"
177
+ [disabled]="busy()"
178
+ (click)="ask(tool.name)"
179
+ >
180
+ {{ tool.description }}
181
+ </button>
182
+ } @empty {
183
+ <span class="px-1 text-xs text-content-faint">
184
+ Nothing is offered. A command reaches this list only when it is registered with
185
+ <code class="text-content">callable: true</code>, and reaching another plugin's commands
186
+ needs the <code class="text-content">automation</code> capability granted.
187
+ </span>
188
+ }
189
+ </div>
190
+ </div>
191
+ `;
192
+ }
193
+ //# sourceMappingURL=agent-panel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-panel.js","sourceRoot":"","sources":["../../../../../../../libs/tooling/devkit/src/recipes/angular-weaver/agent-panel.ts"],"names":[],"mappings":";;AAEA,8BAoHC;AAED,8CAsEC;AA5LD,SAAgB,SAAS,CAAC,CAAiB;IACzC,OAAO;;WAEE,CAAC,CAAC,YAAY,mBAAmB,CAAC,CAAC,EAAE;8BAClB,CAAC,CAAC,EAAE;;;;;;;;;;eAUnB,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,EAAE;oBACX,CAAC,CAAC,EAAE;;;eAGT,CAAC,CAAC,SAAS;;;;;;;;;;uBAUH,CAAC,CAAC,YAAY;;;;oBAIjB,CAAC,CAAC,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAmFjC,CAAC;AACF,CAAC;AAED,SAAgB,iBAAiB,CAAC,CAAiB;IACjD,OAAO;;;;;yCAKgC,CAAC,CAAC,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA+D5C,CAAC;AACF,CAAC"}
@@ -0,0 +1,2 @@
1
+ import type { ResolvedWeaver } from './recipe';
2
+ export declare function standInFile(w: ResolvedWeaver): string;
@@ -0,0 +1,93 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.standInFile = standInFile;
4
+ function standInFile(w) {
5
+ return `import { EventType, type BaseEvent, type Tool } from '@ag-ui/core';
6
+
7
+ // WHAT THIS IS: a stand-in for an agent, and not an agent. It speaks the AG-UI protocol and nothing
8
+ // else — no model, no network, no judgement — so that the whole path from the offered tools through
9
+ // a call to its outcome runs on the first serve, before you have connected anything.
10
+ //
11
+ // WHAT REPLACES IT: this file, and only this file. Point askAgent at your own endpoint and yield the
12
+ // events it streams back. The panel and the connection beside it stay exactly as they are.
13
+
14
+ const PACE = 40;
15
+
16
+ export interface AgentRequest {
17
+ readonly runId: string;
18
+ readonly prompt: string;
19
+ /** What the workbench offers right now — the same list a real agent would be handed. */
20
+ readonly tools: readonly Tool[];
21
+ }
22
+
23
+ export async function* askAgent(
24
+ request: AgentRequest,
25
+ ): AsyncGenerator<BaseEvent> {
26
+ const picked = request.tools.find((tool) =>
27
+ request.prompt.includes(tool.name),
28
+ );
29
+
30
+ yield event(EventType.RUN_STARTED, {
31
+ threadId: '${w.id}-stand-in',
32
+ runId: request.runId,
33
+ });
34
+ yield* speak(
35
+ \`\${request.runId}.says\`,
36
+ picked
37
+ ? \`You asked for "\${request.prompt}". I can see \${request.tools.length} tool(s) and \${picked.name} is one of them, so I will call it.\`
38
+ : \`You asked for "\${request.prompt}", and nothing among the \${request.tools.length} tool(s) I was offered matches it, so I will not call anything.\`,
39
+ );
40
+
41
+ if (picked) {
42
+ const toolCallId = \`\${request.runId}.call\`;
43
+ yield event(EventType.TOOL_CALL_START, {
44
+ toolCallId,
45
+ toolCallName: picked.name,
46
+ });
47
+ // Arguments arrive in pieces, exactly as they do from a real model. The adapter assembles them;
48
+ // nothing downstream ever sees a half-written call. A real agent fills them from the JSON Schema
49
+ // the workbench described in picked.parameters; a stand-in has nothing to fill them from, so it
50
+ // sends none and lets the command apply its own defaults.
51
+ for (const piece of chunks(JSON.stringify({}), 4)) {
52
+ yield event(EventType.TOOL_CALL_ARGS, { toolCallId, delta: piece });
53
+ await pause();
54
+ }
55
+ yield event(EventType.TOOL_CALL_END, { toolCallId });
56
+ }
57
+
58
+ yield event(EventType.RUN_FINISHED, {
59
+ threadId: '${w.id}-stand-in',
60
+ runId: request.runId,
61
+ });
62
+ }
63
+
64
+ async function* speak(
65
+ messageId: string,
66
+ text: string,
67
+ ): AsyncGenerator<BaseEvent> {
68
+ yield event(EventType.TEXT_MESSAGE_START, { messageId, role: 'assistant' });
69
+ for (const piece of chunks(text, 10)) {
70
+ yield event(EventType.TEXT_MESSAGE_CONTENT, { messageId, delta: piece });
71
+ await pause();
72
+ }
73
+ yield event(EventType.TEXT_MESSAGE_END, { messageId });
74
+ }
75
+
76
+ function chunks(text: string, size: number): readonly string[] {
77
+ const pieces: string[] = [];
78
+ for (let at = 0; at < text.length; at += size) {
79
+ pieces.push(text.slice(at, at + size));
80
+ }
81
+ return pieces;
82
+ }
83
+
84
+ function event(type: EventType, fields: Record<string, unknown>): BaseEvent {
85
+ return { type, ...fields } as unknown as BaseEvent;
86
+ }
87
+
88
+ function pause(): Promise<void> {
89
+ return new Promise((done) => setTimeout(done, PACE));
90
+ }
91
+ `;
92
+ }
93
+ //# sourceMappingURL=agent-stand-in.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-stand-in.js","sourceRoot":"","sources":["../../../../../../../libs/tooling/devkit/src/recipes/angular-weaver/agent-stand-in.ts"],"names":[],"mappings":";;AAEA,kCAwFC;AAxFD,SAAgB,WAAW,CAAC,CAAiB;IAC3C,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;iBA0BQ,CAAC,CAAC,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBA4BJ,CAAC,CAAC,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAgCpB,CAAC;AACF,CAAC"}
@@ -1,3 +1,3 @@
1
1
  import { Amendment } from '../../lib/amend/types';
2
- import { WeaverInput } from './recipe';
2
+ import { type WeaverInput } from './recipe';
3
3
  export declare function weaverAmendments(input: WeaverInput, where: string | undefined): readonly Amendment[];
@@ -1,14 +1,31 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.weaverAmendments = weaverAmendments;
4
+ const merge_1 = require("../../lib/amend/merge");
5
+ const agent_files_1 = require("./agent-files");
4
6
  const recipe_1 = require("./recipe");
5
7
  function weaverAmendments(input, where) {
6
8
  const w = (0, recipe_1.resolveWeaverInput)(input);
7
- const directory = (where !== null && where !== void 0 ? where : '').replace(/^\.?\/*/, '').replace(/\/+$/, '');
9
+ const packages = w.features.agent
10
+ ? [
11
+ {
12
+ kind: 'package',
13
+ name: '@loomweaver/ag-ui',
14
+ version: `^${agent_files_1.AG_UI_ADAPTER_VERSION}`,
15
+ },
16
+ {
17
+ kind: 'package',
18
+ name: '@ag-ui/core',
19
+ version: agent_files_1.AG_UI_PROTOCOL_VERSION,
20
+ },
21
+ ]
22
+ : [];
23
+ const directory = (0, merge_1.normalizeProjectRoot)(where ?? '');
8
24
  if (!directory) {
9
- return [];
25
+ return packages;
10
26
  }
11
27
  return [
28
+ ...packages,
12
29
  {
13
30
  kind: 'build-target',
14
31
  styles: [],
@@ -1 +1 @@
1
- {"version":3,"file":"amendments.js","sourceRoot":"","sources":["../../../../../../../libs/tooling/devkit/src/recipes/angular-weaver/amendments.ts"],"names":[],"mappings":";;AAGA,4CA+BC;AAjCD,qCAA2D;AAE3D,SAAgB,gBAAgB,CAC9B,KAAkB,EAClB,KAAyB;IAEzB,MAAM,CAAC,GAAG,IAAA,2BAAkB,EAAC,KAAK,CAAC,CAAC;IACpC,MAAM,SAAS,GAAG,CAAC,KAAK,aAAL,KAAK,cAAL,KAAK,GAAI,EAAE,CAAC,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IAC3E,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,OAAO;QACL;YACE,IAAI,EAAE,cAAc;YACpB,MAAM,EAAE,EAAE;YACV,MAAM,EAAE;gBACN;oBACE,IAAI,EAAE,WAAW;oBACjB,KAAK,EAAE,GAAG,SAAS,eAAe;oBAClC,IAAI,EAAE,WAAW;oBACjB,MAAM,EAAE,QAAQ,CAAC,CAAC,EAAE,EAAE;iBACvB;aACF;SACF;QACD,EAAE,IAAI,EAAE,mBAAmB,EAAE,UAAU,EAAE,GAAG,SAAS,MAAM,EAAE;QAC7D;YACE,IAAI,EAAE,gBAAgB;YACtB,EAAE,EAAE,CAAC,CAAC,EAAE;YACR,MAAM,EAAE,GAAG,CAAC,CAAC,YAAY,QAAQ;YACjC,YAAY,EAAE,CAAC,CAAC,YAAY;YAC5B,UAAU,EAAE,GAAG,SAAS,MAAM;SAC/B;KACF,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"amendments.js","sourceRoot":"","sources":["../../../../../../../libs/tooling/devkit/src/recipes/angular-weaver/amendments.ts"],"names":[],"mappings":";;AAKA,4CA8CC;AAnDD,iDAA6D;AAE7D,+CAA8E;AAC9E,qCAAgE;AAEhE,SAAgB,gBAAgB,CAC9B,KAAkB,EAClB,KAAyB;IAEzB,MAAM,CAAC,GAAG,IAAA,2BAAkB,EAAC,KAAK,CAAC,CAAC;IACpC,MAAM,QAAQ,GAAyB,CAAC,CAAC,QAAQ,CAAC,KAAK;QACrD,CAAC,CAAC;YACE;gBACE,IAAI,EAAE,SAAS;gBACf,IAAI,EAAE,mBAAmB;gBACzB,OAAO,EAAE,IAAI,mCAAqB,EAAE;aACrC;YACD;gBACE,IAAI,EAAE,SAAS;gBACf,IAAI,EAAE,aAAa;gBACnB,OAAO,EAAE,oCAAsB;aAChC;SACF;QACH,CAAC,CAAC,EAAE,CAAC;IACP,MAAM,SAAS,GAAG,IAAA,4BAAoB,EAAC,KAAK,IAAI,EAAE,CAAC,CAAC;IACpD,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,OAAO,QAAQ,CAAC;IAClB,CAAC;IACD,OAAO;QACL,GAAG,QAAQ;QACX;YACE,IAAI,EAAE,cAAc;YACpB,MAAM,EAAE,EAAE;YACV,MAAM,EAAE;gBACN;oBACE,IAAI,EAAE,WAAW;oBACjB,KAAK,EAAE,GAAG,SAAS,eAAe;oBAClC,IAAI,EAAE,WAAW;oBACjB,MAAM,EAAE,QAAQ,CAAC,CAAC,EAAE,EAAE;iBACvB;aACF;SACF;QACD,EAAE,IAAI,EAAE,mBAAmB,EAAE,UAAU,EAAE,GAAG,SAAS,MAAM,EAAE;QAC7D;YACE,IAAI,EAAE,gBAAgB;YACtB,EAAE,EAAE,CAAC,CAAC,EAAE;YACR,MAAM,EAAE,GAAG,CAAC,CAAC,YAAY,QAAQ;YACjC,YAAY,EAAE,CAAC,CAAC,YAAY;YAC5B,UAAU,EAAE,GAAG,SAAS,MAAM;SAC/B;KACF,CAAC;AACJ,CAAC"}
@@ -9,6 +9,7 @@ export interface WeaverFeatures {
9
9
  readonly about?: boolean;
10
10
  readonly instanceable?: boolean;
11
11
  readonly container?: boolean;
12
+ readonly agent?: boolean;
12
13
  readonly spec?: boolean;
13
14
  }
14
15
  export interface WeaverInput {
@@ -31,6 +32,7 @@ interface ResolvedFeatures {
31
32
  readonly about: boolean;
32
33
  readonly instanceable: boolean;
33
34
  readonly container: boolean;
35
+ readonly agent: boolean;
34
36
  readonly spec: boolean;
35
37
  }
36
38
  export interface ResolvedWeaver {