@loomweaver/devkit 0.7.6 → 0.7.8

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 (43) hide show
  1. package/package.json +1 -1
  2. package/src/generators/weaver/generator.d.ts +2 -2
  3. package/src/generators/weaver/generator.js +18 -2
  4. package/src/generators/weaver/generator.js.map +1 -1
  5. package/src/generators/weaver/schema.json +5 -0
  6. package/src/index.d.ts +6 -6
  7. package/src/index.js +2 -1
  8. package/src/index.js.map +1 -1
  9. package/src/lib/amend/describe.js +3 -0
  10. package/src/lib/amend/describe.js.map +1 -1
  11. package/src/lib/amend/merge.d.ts +7 -1
  12. package/src/lib/amend/merge.js +31 -0
  13. package/src/lib/amend/merge.js.map +1 -1
  14. package/src/lib/amend/types.d.ts +12 -1
  15. package/src/lib/scaffolds/inputs.d.ts +1 -0
  16. package/src/lib/scaffolds/inputs.js +3 -1
  17. package/src/lib/scaffolds/inputs.js.map +1 -1
  18. package/src/lib/scaffolds/scaffolds.js +6 -0
  19. package/src/lib/scaffolds/scaffolds.js.map +1 -1
  20. package/src/recipes/angular-weaver/agent-files.d.ts +12 -0
  21. package/src/recipes/angular-weaver/agent-files.js +169 -0
  22. package/src/recipes/angular-weaver/agent-files.js.map +1 -0
  23. package/src/recipes/angular-weaver/agent-panel.d.ts +3 -0
  24. package/src/recipes/angular-weaver/agent-panel.js +193 -0
  25. package/src/recipes/angular-weaver/agent-panel.js.map +1 -0
  26. package/src/recipes/angular-weaver/agent-stand-in.d.ts +2 -0
  27. package/src/recipes/angular-weaver/agent-stand-in.js +93 -0
  28. package/src/recipes/angular-weaver/agent-stand-in.js.map +1 -0
  29. package/src/recipes/angular-weaver/amendments.d.ts +1 -1
  30. package/src/recipes/angular-weaver/amendments.js +17 -1
  31. package/src/recipes/angular-weaver/amendments.js.map +1 -1
  32. package/src/recipes/angular-weaver/recipe.d.ts +2 -0
  33. package/src/recipes/angular-weaver/recipe.js +29 -115
  34. package/src/recipes/angular-weaver/recipe.js.map +1 -1
  35. package/src/recipes/angular-weaver/weaver-i18n.d.ts +1 -1
  36. package/src/recipes/angular-weaver/weaver-i18n.js +11 -0
  37. package/src/recipes/angular-weaver/weaver-i18n.js.map +1 -1
  38. package/src/recipes/angular-weaver/weaver-readme.d.ts +2 -0
  39. package/src/recipes/angular-weaver/weaver-readme.js +142 -0
  40. package/src/recipes/angular-weaver/weaver-readme.js.map +1 -0
  41. package/src/recipes/angular-weaver/weaver-terms.d.ts +2 -0
  42. package/src/recipes/angular-weaver/weaver-terms.js +9 -0
  43. package/src/recipes/angular-weaver/weaver-terms.js.map +1 -0
@@ -1,3 +1,3 @@
1
- import { ResolvedWeaver } from './recipe';
1
+ import type { ResolvedWeaver } from './recipe';
2
2
  export declare function i18nBundle(w: ResolvedWeaver): Record<string, unknown>;
3
3
  export declare function i18nFile(w: ResolvedWeaver): string;
@@ -14,6 +14,17 @@ function i18nBundle(w) {
14
14
  }
15
15
  if (w.features.about)
16
16
  bundle['about'] = `About ${w.name}`;
17
+ if (w.features.agent) {
18
+ bundle['agent'] = {
19
+ title: `${w.name} assistant`,
20
+ confirm: {
21
+ title: 'Run this command?',
22
+ message: 'An agent asked to run a command that was marked consequential.',
23
+ yes: 'Run it',
24
+ no: 'Not now',
25
+ },
26
+ };
27
+ }
17
28
  if (w.features.settings)
18
29
  bundle['settings'] = { title: w.name, enabled: 'Enabled', note: 'Note' };
19
30
  return bundle;
@@ -1 +1 @@
1
- {"version":3,"file":"weaver-i18n.js","sourceRoot":"","sources":["../../../../../../../libs/tooling/devkit/src/recipes/angular-weaver/weaver-i18n.ts"],"names":[],"mappings":";;AAEA,gCAcC;AAED,4BAEC;AAlBD,SAAgB,UAAU,CAAC,CAAiB;IAC1C,MAAM,MAAM,GAA4B,EAAE,KAAK,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;IAC1D,IAAI,CAAC,CAAC,QAAQ,CAAC,SAAS,EAAE,CAAC;QACzB,MAAM,CAAC,QAAQ,CAAC,GAAG,QAAQ,CAAC;QAC5B,MAAM,CAAC,SAAS,CAAC,GAAG,SAAS,CAAC;IAChC,CAAC;IACD,IAAI,CAAC,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC;QACvB,MAAM,CAAC,QAAQ,CAAC,GAAG,GAAG,CAAC,CAAC,IAAI,SAAS,CAAC;QACtC,MAAM,CAAC,mBAAmB,CAAC,GAAG,iBAAiB,CAAC,CAAC,IAAI,WAAW,CAAC;IACnE,CAAC;IACD,IAAI,CAAC,CAAC,QAAQ,CAAC,KAAK;QAAE,MAAM,CAAC,OAAO,CAAC,GAAG,SAAS,CAAC,CAAC,IAAI,EAAE,CAAC;IAC1D,IAAI,CAAC,CAAC,QAAQ,CAAC,QAAQ;QACrB,MAAM,CAAC,UAAU,CAAC,GAAG,EAAE,KAAK,EAAE,CAAC,CAAC,IAAI,EAAE,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;IAC3E,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,SAAgB,QAAQ,CAAC,CAAiB;IACxC,OAAO,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC;AACvD,CAAC"}
1
+ {"version":3,"file":"weaver-i18n.js","sourceRoot":"","sources":["../../../../../../../libs/tooling/devkit/src/recipes/angular-weaver/weaver-i18n.ts"],"names":[],"mappings":";;AAEA,gCA0BC;AAED,4BAEC;AA9BD,SAAgB,UAAU,CAAC,CAAiB;IAC1C,MAAM,MAAM,GAA4B,EAAE,KAAK,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;IAC1D,IAAI,CAAC,CAAC,QAAQ,CAAC,SAAS,EAAE,CAAC;QACzB,MAAM,CAAC,QAAQ,CAAC,GAAG,QAAQ,CAAC;QAC5B,MAAM,CAAC,SAAS,CAAC,GAAG,SAAS,CAAC;IAChC,CAAC;IACD,IAAI,CAAC,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC;QACvB,MAAM,CAAC,QAAQ,CAAC,GAAG,GAAG,CAAC,CAAC,IAAI,SAAS,CAAC;QACtC,MAAM,CAAC,mBAAmB,CAAC,GAAG,iBAAiB,CAAC,CAAC,IAAI,WAAW,CAAC;IACnE,CAAC;IACD,IAAI,CAAC,CAAC,QAAQ,CAAC,KAAK;QAAE,MAAM,CAAC,OAAO,CAAC,GAAG,SAAS,CAAC,CAAC,IAAI,EAAE,CAAC;IAC1D,IAAI,CAAC,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAC;QACrB,MAAM,CAAC,OAAO,CAAC,GAAG;YAChB,KAAK,EAAE,GAAG,CAAC,CAAC,IAAI,YAAY;YAC5B,OAAO,EAAE;gBACP,KAAK,EAAE,mBAAmB;gBAC1B,OAAO,EACL,gEAAgE;gBAClE,GAAG,EAAE,QAAQ;gBACb,EAAE,EAAE,SAAS;aACd;SACF,CAAC;IACJ,CAAC;IACD,IAAI,CAAC,CAAC,QAAQ,CAAC,QAAQ;QACrB,MAAM,CAAC,UAAU,CAAC,GAAG,EAAE,KAAK,EAAE,CAAC,CAAC,IAAI,EAAE,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;IAC3E,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,SAAgB,QAAQ,CAAC,CAAiB;IACxC,OAAO,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC;AACvD,CAAC"}
@@ -0,0 +1,2 @@
1
+ import type { ResolvedWeaver } from './recipe';
2
+ export declare function readmeFile(w: ResolvedWeaver): string;
@@ -0,0 +1,142 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.readmeFile = readmeFile;
4
+ const weaver_terms_1 = require("./weaver-terms");
5
+ function surfaceNotes(w) {
6
+ const railNote = 'Rail and bar items reference region ids (`primary`, `status`) that must exist in your layout.';
7
+ if (w.features.container) {
8
+ return [
9
+ `The surface is a **container**: it is routable at \`/${w.id}/:id\`, and its tab holds a`,
10
+ 'nested pane tree of child surfaces. The host draws the inner tabs, splits and drag targets; this',
11
+ 'weaver only declares which children it offers.',
12
+ '',
13
+ `- \`children\` is what the inner "new tab" picker lists — the host access-gates it for you.`,
14
+ '- `initial` is what a freshly opened container tab starts with.',
15
+ `- The children declare \`docks: []\`. That is the container-only convention: they are never seeded`,
16
+ ' into a sidebar, they exist solely inside this container.',
17
+ `- Each child reads the container's \`:id\` from an injected \`ActivatedRoute\` — the host supplies a`,
18
+ ' synthetic one, so a child needs no knowledge of where it is mounted. Two open container tabs are',
19
+ ' two independent trees, each scoped to its own id.',
20
+ `- The inner tree is **sealed**: a child cannot be dragged out, and nothing can be dragged in. It`,
21
+ ' travels with the tab, including into a sidebar or a pop-out window.',
22
+ '',
23
+ `The rail item opens the fixed id \`${weaver_terms_1.CONTAINER_EXAMPLE_ID}\`. Replace that with whatever the user`,
24
+ 'actually picked — a document, a run, a project.',
25
+ '',
26
+ railNote,
27
+ ];
28
+ }
29
+ if (w.features.instanceable) {
30
+ return [
31
+ `The surface is **docked** into the \`primary\` region and marked \`instanceable\`, so the host shows a`,
32
+ 'switcher for saving, naming, renaming and deleting several configurations of it, each with its own',
33
+ '`VIEW_STATE` blob.',
34
+ '',
35
+ 'It is deliberately **not** routable. Named instances exist only for a docked surface — a routable',
36
+ 'one holds the URL pane instead, and the host drops `instanceable` on that path. The rail item',
37
+ 'therefore reveals the surface (`ctx.revealSurface`) rather than navigating to a URL, which focuses',
38
+ 'it wherever the user has since moved it.',
39
+ '',
40
+ 'The generated view already uses that blob for its sort order, because a hidden surface is destroyed',
41
+ 'as soon as it is clean: state kept in a component field survives neither a tab switch nor',
42
+ 'a collapsed sidebar, and never survived a reload. The rule is *evictable = reload-safe* — anything',
43
+ 'that must not be lost goes through `VIEW_STATE`, and `set()` replaces the whole blob, so spread it.',
44
+ '',
45
+ railNote,
46
+ ];
47
+ }
48
+ return [
49
+ `The surface is routable at \`/${w.id}\`; ${railNote.charAt(0).toLowerCase()}${railNote.slice(1)}`,
50
+ '',
51
+ 'A routable surface has **no `VIEW_STATE` handle** — injecting the token there throws. It owns a URL,',
52
+ 'so anything shareable (a filter, the active sub-tab) belongs in route params or `subRoutes`, where it',
53
+ 'survives a deep link too; unsaved edits are `DirtySurface`, and an instance that is expensive to',
54
+ "rebuild declares `retain: 'always'`. Generate with `--instanceable` for the docked, `VIEW_STATE`",
55
+ 'flavour instead.',
56
+ ];
57
+ }
58
+ function agentNotes(w) {
59
+ return [
60
+ '',
61
+ '## The agent connection',
62
+ '',
63
+ `\`src/lib/agent/\` holds three files and one of them is meant to be thrown away.`,
64
+ '',
65
+ `- \`${w.id}-agent.ts\` is the connection: the workbench's own commands offered as tools, and a`,
66
+ ' seam where this weaver decides about a call before it runs. Nothing is registered twice — the',
67
+ ' list comes from the workbench, already narrowed by everything that would refuse the call.',
68
+ `- \`${w.id}-agent-panel.ts\` shows what is offered, the call as it streams, and the outcome.`,
69
+ `- \`${w.id}-agent-source.ts\` is a **stand-in**, not an assistant: it produces the protocol's own`,
70
+ ' events so the whole path runs before you have connected anything. Replace that one file with',
71
+ ' your transport and nothing else changes. No transport, credential or model is generated for',
72
+ ' you, because none of them can be guessed.',
73
+ '',
74
+ 'Three things are easy to get wrong and invisible when they are, so the generated code does them',
75
+ 'rather than explaining them: the offered list is asked for again every run, every event is handed',
76
+ 'over unfiltered, and a decision before a call can only narrow what the workbench would have',
77
+ 'allowed anyway.',
78
+ '',
79
+ `The generated weaver needs two packages your project may not carry yet:`,
80
+ '',
81
+ '```bash',
82
+ `npm i @loomweaver/ag-ui @ag-ui/core`,
83
+ '```',
84
+ '',
85
+ 'The Nx generator and the CLI record them for you; the MCP route names them instead.',
86
+ ];
87
+ }
88
+ function readmeFile(w) {
89
+ return [
90
+ `# ${w.name} weaver`,
91
+ '',
92
+ `A LoomWeaver weaver (a domain plugin bundle). It consumes only the public \`@loomweaver/plugin-sdk\` contract.`,
93
+ '',
94
+ '## Wire it into a distribution',
95
+ '',
96
+ `1. Add the plugin to \`providePlugins\` in \`src/app/app.config.ts\`. It is **variadic** and`,
97
+ ` returns an array, so spread it:`,
98
+ '',
99
+ ' ```ts',
100
+ ` import { ${w.propertyName}Plugin } from '${w.importPath}'; // Nx: the workspace alias; without one, a relative path to this library's src/index.ts`,
101
+ ` ...providePlugins(${w.propertyName}Plugin),`,
102
+ ' ```',
103
+ '',
104
+ `2. Grant its capabilities (default-deny) via \`provideCapabilityGrants\`:`,
105
+ '',
106
+ ' ```ts',
107
+ ` provideCapabilityGrants({ '${w.id}': [${(0, weaver_terms_1.capabilityItems)(w.capabilities)}] });`,
108
+ ' ```',
109
+ '',
110
+ `3. Compose its translations with \`provideTranslationNamespaces('${w.id}')\` — and serve the`,
111
+ ` bundle by adding an assets glob to your application's build target, so the loader can fetch`,
112
+ ` \`/i18n/${w.id}/<lang>.json\` (the Nx generator adds this glob for you):`,
113
+ '',
114
+ ' ```json',
115
+ ` { "glob": "**/*.json", "input": "<path to this library>/src/lib/i18n", "output": "i18n/${w.id}" }`,
116
+ ' ```',
117
+ '',
118
+ `4. If your application compiles the shell's theme with Tailwind, name this library as a source`,
119
+ ` for it, so the utility classes in these templates are emitted. Tailwind also detects sources`,
120
+ ` by itself, but that depends on where it resolves the project root and on \`.gitignore\`, and`,
121
+ ` what the scaffold names covers the application alone (the Nx generator adds this line for`,
122
+ ` you). Applications scaffolded with \`--styles precompiled\` run no Tailwind and need nothing:`,
123
+ '',
124
+ ' ```css',
125
+ ` @source '<path from that stylesheet to this library>/src';`,
126
+ ' ```',
127
+ '',
128
+ ...surfaceNotes(w),
129
+ ...(w.features.agent ? agentNotes(w) : []),
130
+ '',
131
+ '## After scaffolding',
132
+ '',
133
+ '- `src/lib/i18n/de.json` starts as a copy of the English strings — translate it.',
134
+ `- A scaffolded command defaults its shortcut to \`mod+shift+<first letter of the id>\` — two weavers whose ids share a first letter collide; pass \`--shortcut\` or edit the command.`,
135
+ '- The project is generated **untagged**: Nx tags belong to your `depConstraints`, and inventing',
136
+ ' one would fail a lint policy you never opted this project into. If your workspace enforces',
137
+ ' module boundaries, give it tags your constraints allow — `--tags` at generation time, or',
138
+ ' `tags` in `project.json` afterwards.',
139
+ '',
140
+ ].join('\n');
141
+ }
142
+ //# sourceMappingURL=weaver-readme.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"weaver-readme.js","sourceRoot":"","sources":["../../../../../../../libs/tooling/devkit/src/recipes/angular-weaver/weaver-readme.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare const CONTAINER_EXAMPLE_ID = "example";
2
+ export declare function capabilityItems(capabilities: readonly string[]): string;
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CONTAINER_EXAMPLE_ID = void 0;
4
+ exports.capabilityItems = capabilityItems;
5
+ exports.CONTAINER_EXAMPLE_ID = 'example';
6
+ function capabilityItems(capabilities) {
7
+ return capabilities.map((capability) => `'${capability}'`).join(', ');
8
+ }
9
+ //# sourceMappingURL=weaver-terms.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"weaver-terms.js","sourceRoot":"","sources":["../../../../../../../libs/tooling/devkit/src/recipes/angular-weaver/weaver-terms.ts"],"names":[],"mappings":";;;AAEA,0CAEC;AAJY,QAAA,oBAAoB,GAAG,SAAS,CAAC;AAE9C,SAAgB,eAAe,CAAC,YAA+B;IAC7D,OAAO,YAAY,CAAC,GAAG,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,IAAI,UAAU,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACxE,CAAC"}