@bevel-software/platform-shared 0.14.0 → 0.19.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/auth/types.d.ts +12 -0
- package/dist/auth/types.d.ts.map +1 -1
- package/dist/git/pr.types.d.ts +75 -11
- package/dist/git/pr.types.d.ts.map +1 -1
- package/dist/git/types.d.ts +75 -2
- package/dist/git/types.d.ts.map +1 -1
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -1
- package/dist/workflow/events.d.ts +39 -4
- package/dist/workflow/events.d.ts.map +1 -1
- package/dist/workflow/events.js.map +1 -1
- package/dist/workflow/interface.d.ts +137 -5
- package/dist/workflow/interface.d.ts.map +1 -1
- package/dist/workflow/types.d.ts +93 -0
- package/dist/workflow/types.d.ts.map +1 -1
- package/dist/workspace/access-verbs.d.ts +83 -0
- package/dist/workspace/access-verbs.d.ts.map +1 -0
- package/dist/workspace/access-verbs.js +110 -0
- package/dist/workspace/access-verbs.js.map +1 -0
- package/dist/workspace/agent-preamble.d.ts +33 -0
- package/dist/workspace/agent-preamble.d.ts.map +1 -0
- package/dist/workspace/agent-preamble.js +45 -0
- package/dist/workspace/agent-preamble.js.map +1 -0
- package/dist/workspace/entry-exists.d.ts +27 -0
- package/dist/workspace/entry-exists.d.ts.map +1 -0
- package/dist/workspace/entry-exists.js +33 -0
- package/dist/workspace/entry-exists.js.map +1 -0
- package/dist/workspace/filename.d.ts +15 -0
- package/dist/workspace/filename.d.ts.map +1 -1
- package/dist/workspace/filename.js +37 -3
- package/dist/workspace/filename.js.map +1 -1
- package/dist/workspace/frontmatter-carriers.d.ts +44 -0
- package/dist/workspace/frontmatter-carriers.d.ts.map +1 -0
- package/dist/workspace/frontmatter-carriers.js +52 -0
- package/dist/workspace/frontmatter-carriers.js.map +1 -0
- package/dist/workspace/frontmatter.d.ts +23 -4
- package/dist/workspace/frontmatter.d.ts.map +1 -1
- package/dist/workspace/frontmatter.js +59 -9
- package/dist/workspace/frontmatter.js.map +1 -1
- package/dist/workspace/kb-layout.d.ts +365 -19
- package/dist/workspace/kb-layout.d.ts.map +1 -1
- package/dist/workspace/kb-layout.js +619 -20
- package/dist/workspace/kb-layout.js.map +1 -1
- package/dist/workspace/placeholder.d.ts +21 -0
- package/dist/workspace/placeholder.d.ts.map +1 -0
- package/dist/workspace/placeholder.js +28 -0
- package/dist/workspace/placeholder.js.map +1 -0
- package/dist/workspace/platform-files.d.ts +105 -0
- package/dist/workspace/platform-files.d.ts.map +1 -0
- package/dist/workspace/platform-files.js +147 -0
- package/dist/workspace/platform-files.js.map +1 -0
- package/dist/workspace/types.d.ts +8 -0
- package/dist/workspace/types.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/auth/types.ts +12 -0
- package/src/git/pr.types.ts +77 -11
- package/src/git/types.ts +81 -3
- package/src/index.ts +6 -0
- package/src/workflow/events.ts +40 -3
- package/src/workflow/interface.ts +162 -6
- package/src/workflow/types.ts +70 -0
- package/src/workspace/access-verbs.ts +124 -0
- package/src/workspace/agent-preamble.ts +47 -0
- package/src/workspace/entry-exists.ts +36 -0
- package/src/workspace/filename.ts +38 -3
- package/src/workspace/frontmatter-carriers.ts +57 -0
- package/src/workspace/frontmatter.ts +57 -8
- package/src/workspace/kb-layout.ts +660 -24
- package/src/workspace/placeholder.ts +29 -0
- package/src/workspace/platform-files.ts +188 -0
- package/src/workspace/types.ts +8 -0
|
@@ -6,7 +6,8 @@
|
|
|
6
6
|
*
|
|
7
7
|
* <kbDirName>/
|
|
8
8
|
* ├── KnowledgeBase/ ← all team ontologies live here (the knowledge graph)
|
|
9
|
-
* ├──
|
|
9
|
+
* ├── Skills/ ← shared skills, organised by ownership; plugins LINK to them
|
|
10
|
+
* ├── Plugins/ ← one folder per plugin: manifest, MCP servers, tools, links
|
|
10
11
|
* ├── Data/ ← agent-produced records; parsed like KnowledgeBase/
|
|
11
12
|
* ├── Agents/ ← .agent files — agent role configurations (not the graph)
|
|
12
13
|
* ├── Pipelines/ ← .pipeline files — execution-layer processes (not the graph)
|
|
@@ -22,21 +23,44 @@
|
|
|
22
23
|
*
|
|
23
24
|
* These names are the single source of truth for both sides of the app:
|
|
24
25
|
* - Backend: the graph parser discovers ontologies under the
|
|
25
|
-
* {@link
|
|
26
|
+
* {@link ontologyRoots} (`KnowledgeBase/` and `Data/`); `Plugins/`,
|
|
26
27
|
* `Agents/`, `Pipelines/` (and anything else at the root) are ignored by
|
|
27
28
|
* parsing, validation, and the diagram.
|
|
28
29
|
* - Frontend: the file tree renders these root folders as distinct
|
|
29
30
|
* top-level sections.
|
|
30
31
|
*
|
|
31
32
|
* Don't hard-code these strings elsewhere — import them from here.
|
|
33
|
+
*
|
|
34
|
+
* CONFIGURABLE, WITH DEFAULTS. The three roots a deployment may rename
|
|
35
|
+
* (`KnowledgeBase/`, `Skills/`, `Plugins/`) are `let` bindings applied by
|
|
36
|
+
* {@link configureKbLayout} — the backend from its deployment settings, the
|
|
37
|
+
* browser from `GET /api/config` — the same live-binding pattern as the branch
|
|
38
|
+
* model in `git/protected.ts`. Unlike the branch model they carry defaults, so
|
|
39
|
+
* nothing has to wait for configuration; but the same rule applies: read them
|
|
40
|
+
* inside a function body, never capture one at module scope.
|
|
32
41
|
*/
|
|
33
42
|
/** Folder under the repo root that contains all team ontologies. */
|
|
34
|
-
export declare
|
|
43
|
+
export declare let KNOWLEDGE_BASE_DIR: string;
|
|
44
|
+
/**
|
|
45
|
+
* Folder under the repo root that holds SHARED skills, organised by ownership:
|
|
46
|
+
*
|
|
47
|
+
* Skills/<scope>/…/<skill>/SKILL.md a skill, at any depth
|
|
48
|
+
* Skills/<scope>/access.md who owns / may read the scope
|
|
49
|
+
*
|
|
50
|
+
* A skill's readability comes from ITS OWN path walk — the scope folders'
|
|
51
|
+
* `access.md` files — never from the plugins that link it. Plugins point at
|
|
52
|
+
* skills here by path (see `HEXIS_LINKED_SKILLS_KEY`), so one definition can
|
|
53
|
+
* ship in several plugins, and a skill in no plugin at all is a normal state.
|
|
54
|
+
* Inline skills under `Plugins/<Plugin>/skills/` remain supported (personal
|
|
55
|
+
* folders, legacy layouts); the catalog is the union of both trees.
|
|
56
|
+
*/
|
|
57
|
+
export declare let SKILLS_DIR: string;
|
|
35
58
|
/**
|
|
36
59
|
* Folder under the repo root that holds the plugins.
|
|
37
60
|
*
|
|
38
|
-
* Plugins/<Plugin>/plugin.json the Agent Plugins manifest
|
|
39
|
-
*
|
|
61
|
+
* Plugins/<Plugin>/plugin.json the Agent Plugins manifest; its
|
|
62
|
+
* hexis extension lists LINKED skills
|
|
63
|
+
* Plugins/<Plugin>/skills/<skill>/SKILL.md an inline skill
|
|
40
64
|
* Plugins/<Plugin>/mcp.json MCP servers
|
|
41
65
|
* Plugins/<Plugin>/software.bevel.hexis/tools/ http + inline `.tool` manuals
|
|
42
66
|
* Plugins/<Plugin>/access.md who can read/write the plugin
|
|
@@ -55,10 +79,11 @@ export declare const KNOWLEDGE_BASE_DIR = "KnowledgeBase";
|
|
|
55
79
|
* `inline` types the spec has no slot for. `mcp`-type manuals are emitted as
|
|
56
80
|
* real `mcp.json` entries instead, so the portable half stays portable.
|
|
57
81
|
*
|
|
58
|
-
*
|
|
59
|
-
*
|
|
60
|
-
*
|
|
61
|
-
*
|
|
82
|
+
* A plugin's own `access.md` governs what the plugin FOLDER holds: the
|
|
83
|
+
* manifest, the MCP servers, the tools, and any inline skills. Shared skills
|
|
84
|
+
* under `Skills/` are governed by their own scope and are made visible to a
|
|
85
|
+
* plugin's members by granting the plugin's principal (`plugin/<Name>/read`)
|
|
86
|
+
* on the skill — ownership decides, the plugin is a view.
|
|
62
87
|
*
|
|
63
88
|
* A plugin is not a registry of unique names — it is a folder. The same
|
|
64
89
|
* integration may exist in several plugins as separate files (`Everyone/…/
|
|
@@ -70,7 +95,222 @@ export declare const KNOWLEDGE_BASE_DIR = "KnowledgeBase";
|
|
|
70
95
|
* display casing. The lowercase slug the spec does constrain lives in the
|
|
71
96
|
* manifest's `name` field.
|
|
72
97
|
*/
|
|
73
|
-
export declare
|
|
98
|
+
export declare let PLUGINS_DIR: string;
|
|
99
|
+
/**
|
|
100
|
+
* The file name of the platform's MANAGED agent guide at the repository root —
|
|
101
|
+
* the document every connected agent is told to read first, written and
|
|
102
|
+
* refreshed from the packaged template on every start.
|
|
103
|
+
*
|
|
104
|
+
* Configurable for one reason: `AGENTS.md` is the name coding agents look for
|
|
105
|
+
* by convention, so a customer arriving with a repository of their own very
|
|
106
|
+
* often already HAS one, and under the default name the platform would
|
|
107
|
+
* overwrite it on the first boot and on every boot after. Renaming the managed
|
|
108
|
+
* guide (`HEXIS.md`, say) hands that name back: `AGENTS.md` becomes ordinary
|
|
109
|
+
* content the platform never writes, never refreshes and never hides, and the
|
|
110
|
+
* customer's file is the one that points at ours (see
|
|
111
|
+
* {@link agentsFilePointerSentence}).
|
|
112
|
+
*
|
|
113
|
+
* A live binding like the three roots above — read it inside a function body,
|
|
114
|
+
* never capture it at module scope.
|
|
115
|
+
*/
|
|
116
|
+
export declare let AGENTS_FILE: string;
|
|
117
|
+
/**
|
|
118
|
+
* The name the managed guide had when it was the only name it could have.
|
|
119
|
+
*
|
|
120
|
+
* Referenced ONLY by the code that has to tell OUR file from THEIRS — the
|
|
121
|
+
* boot-time removal of a platform-written `AGENTS.md`, the ignore rule that
|
|
122
|
+
* stops hiding it, the instruction telling an agent to read the customer's
|
|
123
|
+
* file too. In the spirit of {@link LEGACY_GROUPS_DIR}: a second live spelling
|
|
124
|
+
* of the CURRENT name is how two layouts start being supported by accident, so
|
|
125
|
+
* this one is a constant and means exactly one thing.
|
|
126
|
+
*/
|
|
127
|
+
export declare const LEGACY_AGENTS_FILE = "AGENTS.md";
|
|
128
|
+
/**
|
|
129
|
+
* The platform files whose names are FIXED — the ones no deployment renames.
|
|
130
|
+
* The guide is the fourth platform file and is deliberately absent here: its
|
|
131
|
+
* name is {@link AGENTS_FILE}, and `platform-files.ts` composes the two into
|
|
132
|
+
* the set every gate reads.
|
|
133
|
+
*
|
|
134
|
+
* It lives in this module rather than beside that composition because the
|
|
135
|
+
* LAYOUT has to validate against it (a guide may not be called `access.md`),
|
|
136
|
+
* and `platform-files.ts` already reads this module — the other direction
|
|
137
|
+
* would be a cycle.
|
|
138
|
+
*/
|
|
139
|
+
export declare const FIXED_PLATFORM_FILE_NAMES: readonly string[];
|
|
140
|
+
/**
|
|
141
|
+
* The three renameable roots and the guide's file name, as a deployment
|
|
142
|
+
* declares them and `/api/config` serves them.
|
|
143
|
+
*/
|
|
144
|
+
export interface KbLayout {
|
|
145
|
+
knowledgeBaseDir: string;
|
|
146
|
+
skillsDir: string;
|
|
147
|
+
pluginsDir: string;
|
|
148
|
+
/**
|
|
149
|
+
* The managed agent guide's file name. OPTIONAL, and deliberately: a layout
|
|
150
|
+
* that predates the setting — an older server's `/api/config` body, a saved
|
|
151
|
+
* deployment that never named one — carries three folders and no guide, and
|
|
152
|
+
* the right answer to that is the right answer to an unset field, which is
|
|
153
|
+
* `AGENTS.md`. Read it through {@link agentsFileOf} rather than directly, so
|
|
154
|
+
* "absent" and "the default" can never come to mean two different things.
|
|
155
|
+
*/
|
|
156
|
+
agentsFile?: string;
|
|
157
|
+
}
|
|
158
|
+
/** The layout a deployment gets when it names nothing. */
|
|
159
|
+
export declare const DEFAULT_KB_LAYOUT: Readonly<Required<KbLayout>>;
|
|
160
|
+
/** The guide's name in a layout, with the default standing in for an absent one. */
|
|
161
|
+
export declare function agentsFileOf(layout: KbLayout): string;
|
|
162
|
+
/**
|
|
163
|
+
* `name` as one literal gitignore pattern. The guide's name is the
|
|
164
|
+
* operator's, and the name rules admit characters gitignore reads as syntax:
|
|
165
|
+
* a leading `#` is a comment and a leading `!` a negation (the rule would
|
|
166
|
+
* silently hide nothing), `[`, `]`, `*` and `?` are globs, and a backslash is
|
|
167
|
+
* the escape itself. Each is escaped so the pattern names exactly the file.
|
|
168
|
+
*/
|
|
169
|
+
export declare function gitignoreLiteral(name: string): string;
|
|
170
|
+
/**
|
|
171
|
+
* The ONE sentence the platform offers to keep in a customer's own
|
|
172
|
+
* `AGENTS.md`, pointing at the managed guide beside it.
|
|
173
|
+
*
|
|
174
|
+
* Defined here, once, because two surfaces must produce the identical text:
|
|
175
|
+
* the deployment-settings field previews it before the admin consents, and the
|
|
176
|
+
* startup step appends it. A sentence written twice is a sentence that drifts,
|
|
177
|
+
* and a drifted one appends a SECOND copy to every customer file on the boot
|
|
178
|
+
* after the drift — which is the one thing this whole feature exists to stop.
|
|
179
|
+
*
|
|
180
|
+
* A guide name is a FILE NAME, not an identifier: everything `validateFilename`
|
|
181
|
+
* admits can appear in it — spaces, brackets, parentheses, `#`, `%` — and each
|
|
182
|
+
* of those means something in an inline link. So the link is BUILT rather than
|
|
183
|
+
* interpolated: the label backslash-escaped ({@link markdownLinkLabel}), the
|
|
184
|
+
* destination percent-encoded ({@link agentsFileLinkPath}). A name that only
|
|
185
|
+
* parenthesised would break the destination; `#` would turn the rest of the
|
|
186
|
+
* name into a URL fragment, and the link would point at the customer's own
|
|
187
|
+
* file.
|
|
188
|
+
*
|
|
189
|
+
* Neither spelling need match the name as it is on disk, so nothing may ask
|
|
190
|
+
* whether this sentence is present by searching for the RAW name — see
|
|
191
|
+
* {@link mentionsAgentsFile}, which is how the startup step asks.
|
|
192
|
+
*/
|
|
193
|
+
export declare function agentsFilePointerSentence(agentsFile?: string): string;
|
|
194
|
+
/**
|
|
195
|
+
* `text` with every pointer sentence THE PLATFORM WROTE aimed at `agentsFile`
|
|
196
|
+
* — or null when it holds none of ours.
|
|
197
|
+
*
|
|
198
|
+
* This is what a SECOND rename needs. The guide's name is a setting an admin
|
|
199
|
+
* may change again: a knowledge base whose `AGENTS.md` was given a sentence
|
|
200
|
+
* pointing at `HEXIS.md` and is then renamed to `GUIDE.md` must have that
|
|
201
|
+
* sentence aimed at the new file, not a second one appended beneath a first
|
|
202
|
+
* that now points at nothing. Asking only whether the NEW name is mentioned
|
|
203
|
+
* cannot see that — the old sentence does not mention it.
|
|
204
|
+
*
|
|
205
|
+
* Returning the text unchanged (rather than null) when the sentence is already
|
|
206
|
+
* right is deliberate: "ours and correct" and "not ours at all" are different
|
|
207
|
+
* answers, and only the caller knows that the second one means "consider
|
|
208
|
+
* appending".
|
|
209
|
+
*/
|
|
210
|
+
export declare function retargetAgentsFilePointer(text: string, agentsFile?: string): string | null;
|
|
211
|
+
/**
|
|
212
|
+
* Whether `text` already points at the guide — the ONE question the startup
|
|
213
|
+
* step asks before appending {@link agentsFilePointerSentence} to a customer's
|
|
214
|
+
* own `AGENTS.md`.
|
|
215
|
+
*
|
|
216
|
+
* The plain name is the answer that matters: a mention in the customer's own
|
|
217
|
+
* words, a heading, a link they wrote, all count, and the platform stays out
|
|
218
|
+
* of a file it does not own. The other two spellings are the platform's OWN,
|
|
219
|
+
* and they are here for idempotence: the sentence writes the name escaped in
|
|
220
|
+
* the label and encoded in the destination, so on a punctuated name the file
|
|
221
|
+
* the last boot wrote need not contain the raw name at all. Asking only for
|
|
222
|
+
* that one would append a second copy on the next boot, and a third on the
|
|
223
|
+
* one after — the exact failure this feature exists to prevent.
|
|
224
|
+
*/
|
|
225
|
+
export declare function mentionsAgentsFile(text: string, agentsFile?: string): boolean;
|
|
226
|
+
/**
|
|
227
|
+
* What is wrong with one root name, or null. A root is joined onto the repo
|
|
228
|
+
* root and onto `<dir>/.gitkeep`, so a separator or `..` would write outside
|
|
229
|
+
* the repository; a dot-prefixed name would be skipped by every scanner that
|
|
230
|
+
* treats dot-entries as bookkeeping; `.git` in any case would corrupt the clone.
|
|
231
|
+
*/
|
|
232
|
+
export declare function validateKbRootName(name: string): string | null;
|
|
233
|
+
/**
|
|
234
|
+
* What is wrong with the agent guide's file name, or null.
|
|
235
|
+
*
|
|
236
|
+
* The rules, and what each one is for:
|
|
237
|
+
*
|
|
238
|
+
* - ONE FILE NAME. The name is joined onto the repository root and read from
|
|
239
|
+
* there and nowhere else, so a separator would name a file the platform
|
|
240
|
+
* would write but never read back.
|
|
241
|
+
* - A MARKDOWN NAME. The guide is a markdown document that people open in the
|
|
242
|
+
* app and agents read as text; `.md` is also what the per-file access rules
|
|
243
|
+
* apply to, so a guide under any other extension would take its folder's
|
|
244
|
+
* rules and stop being readable by everyone.
|
|
245
|
+
* - NOT `CLAUDE.md`. That is the guide's own pre-rename name; knowledge bases
|
|
246
|
+
* seeded before the rename still carry one, and it stays legacy content
|
|
247
|
+
* rather than becoming a second managed file.
|
|
248
|
+
* - NOT ANOTHER PLATFORM FILE. Two platform roles on one path means whichever
|
|
249
|
+
* writer runs last wins, silently.
|
|
250
|
+
* - NOT A ROOT FOLDER'S NAME, compared case-insensitively like the roots are
|
|
251
|
+
* to each other: the workspaces live on case-insensitive filesystems, where
|
|
252
|
+
* a file `Docs.md` and a folder `docs.md` are one entry.
|
|
253
|
+
*
|
|
254
|
+
* `roots` is the layout the name is judged against — the names this save would
|
|
255
|
+
* put in effect, not necessarily the ones running now.
|
|
256
|
+
*/
|
|
257
|
+
export declare function validateAgentsFileName(name: string, roots?: Pick<KbLayout, 'knowledgeBaseDir' | 'skillsDir' | 'pluginsDir'>): string | null;
|
|
258
|
+
/**
|
|
259
|
+
* What is wrong with a layout, or null — the same rule {@link configureKbLayout}
|
|
260
|
+
* enforces, without applying anything. Separate so the setup screen can judge a
|
|
261
|
+
* proposed layout before it is saved. The three folder names must differ,
|
|
262
|
+
* compared case-insensitively: the workspaces live on case-insensitive
|
|
263
|
+
* filesystems too, where `Skills` and `skills` are one folder. The guide's
|
|
264
|
+
* file name is judged against all three by the same rule (see
|
|
265
|
+
* {@link validateAgentsFileName}), which makes the four names distinct.
|
|
266
|
+
*/
|
|
267
|
+
export declare function validateKbLayout(layout: KbLayout): string | null;
|
|
268
|
+
/**
|
|
269
|
+
* Be told when {@link configureKbLayout} runs — for the few things that cannot
|
|
270
|
+
* read a live binding at the moment they are used.
|
|
271
|
+
*
|
|
272
|
+
* Almost nothing needs this: the roots and the guide's name are `let` bindings
|
|
273
|
+
* read inside function bodies, so code that follows the rule follows the
|
|
274
|
+
* layout for free. The exception is a value BUILT ONCE and handed to something
|
|
275
|
+
* that keeps it — the tool catalog's descriptions, which are validated into
|
|
276
|
+
* frozen-ish defs at registration and then served to agents from a map. Boot
|
|
277
|
+
* applies the layout before they are built, but the save that completes
|
|
278
|
+
* FIRST-RUN SETUP applies it afterwards (see `setup.routes.ts`, which must, so
|
|
279
|
+
* the KB phase that runs in the same request scaffolds the names the admin
|
|
280
|
+
* just chose) — and without this the catalog would go on naming `AGENTS.md`
|
|
281
|
+
* until someone restarted the server.
|
|
282
|
+
*
|
|
283
|
+
* Listeners run in registration order, after the bindings are updated and only
|
|
284
|
+
* when the layout was accepted.
|
|
285
|
+
*/
|
|
286
|
+
export declare function onKbLayoutApplied(listener: () => void): void;
|
|
287
|
+
/**
|
|
288
|
+
* Apply the layout. Called once during boot on each side; throws on an invalid
|
|
289
|
+
* one so a bad deployment setting fails beside the rest of the wiring rather
|
|
290
|
+
* than scattering a half-renamed tree. Applying the defaults is a no-op.
|
|
291
|
+
*/
|
|
292
|
+
export declare function configureKbLayout(layout: KbLayout): void;
|
|
293
|
+
/** The layout currently in effect. */
|
|
294
|
+
export declare function currentKbLayout(): Required<KbLayout>;
|
|
295
|
+
/**
|
|
296
|
+
* Whether a layout — the one in effect, unless one is given — is the default
|
|
297
|
+
* one. The setup-completing save applies the stored names while this holds,
|
|
298
|
+
* the same "only from none to some" rule the branch model follows — and also
|
|
299
|
+
* on a retry after its own failed initialization run, when the process holds
|
|
300
|
+
* names setup applied but the app never opened (see `setup.routes.ts`). A
|
|
301
|
+
* layout the process booted with is never replaced here.
|
|
302
|
+
*/
|
|
303
|
+
export declare function isDefaultKbLayout(layout?: KbLayout): boolean;
|
|
304
|
+
/**
|
|
305
|
+
* Render the layout placeholders a managed template carries —
|
|
306
|
+
* `{{knowledgeBaseDir}}`, `{{skillsDir}}`, `{{pluginsDir}}`, `{{agentsFile}}`
|
|
307
|
+
* — with the names in effect. The packaged guide and `.bevelignore` are
|
|
308
|
+
* written this way so a deployment that renamed its roots hands the agent a
|
|
309
|
+
* guide that names the folders it will actually find, and a deployment that
|
|
310
|
+
* renamed the guide gets a guide naming the file it lives in. Text without
|
|
311
|
+
* placeholders passes through unchanged.
|
|
312
|
+
*/
|
|
313
|
+
export declare function renderKbLayoutPlaceholders(text: string, layout?: KbLayout): string;
|
|
74
314
|
/**
|
|
75
315
|
* The pre-rename name of {@link PLUGINS_DIR}. Referenced ONLY by the migration
|
|
76
316
|
* that renames it — every other consumer should be reading the new name, and a
|
|
@@ -93,6 +333,46 @@ export declare const PLUGIN_SKILLS_DIR = "skills";
|
|
|
93
333
|
export declare const HEXIS_EXTENSION_NS = "software.bevel.hexis";
|
|
94
334
|
/** UTCP manuals whose `http`/`inline` types the spec cannot express. */
|
|
95
335
|
export declare const HEXIS_TOOLS_DIR = "software.bevel.hexis/tools";
|
|
336
|
+
/**
|
|
337
|
+
* The manifest key under which a plugin LINKS shared skills:
|
|
338
|
+
*
|
|
339
|
+
* plugin.json → extensions["software.bevel.hexis"].skills: [
|
|
340
|
+
* "Skills/Engineering/deploy", ← one skill folder
|
|
341
|
+
* "Skills/Sales" ← a folder of skills: every skill beneath
|
|
342
|
+
* ]
|
|
343
|
+
*
|
|
344
|
+
* Entries are repo-root-relative folder paths. A plugin's effective skill set
|
|
345
|
+
* is its inline `skills/` folder PLUS everything these roots resolve to. The
|
|
346
|
+
* spec reserves `extensions` for exactly this kind of client-specific data, so
|
|
347
|
+
* a conformant client that ignores it still gets a valid manifest; the
|
|
348
|
+
* compiled distribution copies the linked skills in for it.
|
|
349
|
+
*
|
|
350
|
+
* Linking is a reference, not a grant: a member of the plugin can read a
|
|
351
|
+
* linked skill only because the skill's own access rules name the plugin's
|
|
352
|
+
* principal (`plugin/<Name>/read`). The link service writes both together.
|
|
353
|
+
*/
|
|
354
|
+
export declare const HEXIS_LINKED_SKILLS_KEY = "skills";
|
|
355
|
+
/**
|
|
356
|
+
* Normalise a linked-skill root, or null when it cannot be one: a
|
|
357
|
+
* repo-root-relative POSIX folder path with no `..`, no leading slash, no
|
|
358
|
+
* backslashes and no empty segments. Trailing slashes are dropped.
|
|
359
|
+
*/
|
|
360
|
+
export declare function normalizeSkillRoot(raw: string): string | null;
|
|
361
|
+
/**
|
|
362
|
+
* The linked-skill roots a parsed manifest declares — invalid entries are
|
|
363
|
+
* dropped, duplicates collapsed, order kept. A manifest with no extension
|
|
364
|
+
* block links nothing.
|
|
365
|
+
*/
|
|
366
|
+
export declare function linkedSkillRoots(manifest: unknown): string[];
|
|
367
|
+
/**
|
|
368
|
+
* The manifest with its linked-skill roots REPLACED by `roots`, every other
|
|
369
|
+
* byte of the object preserved (the MCP extension block beside it, the
|
|
370
|
+
* portable fields above it). An empty list removes the key rather than
|
|
371
|
+
* leaving `skills: []` behind.
|
|
372
|
+
*/
|
|
373
|
+
export declare function withLinkedSkillRoots(manifest: Record<string, unknown>, roots: readonly string[]): Record<string, unknown>;
|
|
374
|
+
/** Whether `skillPath` (a skill folder) falls under `root` (a skill folder or a folder of skills). */
|
|
375
|
+
export declare function skillUnderRoot(skillPath: string, root: string): boolean;
|
|
96
376
|
/**
|
|
97
377
|
* The manifest `name` for a plugin folder: lowercased, anything outside
|
|
98
378
|
* `[a-z0-9.-]` folded to `-`, runs collapsed, ends trimmed to alphanumerics.
|
|
@@ -109,16 +389,57 @@ export declare const AGENT_PLUGINS_SCHEMA_VERSION = "1.0.0";
|
|
|
109
389
|
export declare const PLUGIN_MANIFEST_SCHEMA = "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json";
|
|
110
390
|
export declare const PLUGIN_MCP_SCHEMA = "https://agent-plugins.org/schemas/1.0.0/mcp.schema.json";
|
|
111
391
|
/**
|
|
112
|
-
*
|
|
392
|
+
* The Agent Plugins `name`: a kebab-case identifier — lowercase letters and
|
|
393
|
+
* digits in hyphen-separated runs, nothing else. It is the plugin's IDENTITY:
|
|
394
|
+
* what the marketplace publishes it as, what the access principals are
|
|
395
|
+
* spelled from (`plugin/<name>/<verb>`), what the catalog and the URLs key
|
|
396
|
+
* on. `pluginManifestName` folds any spelling into one of these.
|
|
397
|
+
*/
|
|
398
|
+
export declare const PLUGIN_IDENTIFIER_RE: RegExp;
|
|
399
|
+
export declare function isPluginIdentifier(name: unknown): name is string;
|
|
400
|
+
/**
|
|
401
|
+
* The identity of a plugin folder: the manifest's `name` when it IS an
|
|
402
|
+
* identifier, else the folder name folded into one. A manifest naming
|
|
403
|
+
* something that cannot be an identifier is not silently reinterpreted; the
|
|
404
|
+
* folder stands in, and discovery says so.
|
|
405
|
+
*/
|
|
406
|
+
export declare function pluginIdentityOf(manifest: Record<string, unknown> | null, folderName: string): string;
|
|
407
|
+
/**
|
|
408
|
+
* What a person sees the plugin called: the manifest's `displayName` (the
|
|
409
|
+
* vendor field Claude Code shows in its picker; any casing, spaces allowed),
|
|
410
|
+
* else the manifest's `name`.
|
|
411
|
+
*
|
|
412
|
+
* THE MANIFEST IS THE ONLY SOURCE — there is no folder argument, on purpose.
|
|
413
|
+
* The folder's spelling used to stand in here, which made where a plugin
|
|
414
|
+
* happens to live a hidden input to what everyone sees it called: the API
|
|
415
|
+
* always answered with a display name while the file sometimes omitted the
|
|
416
|
+
* field, and moving or re-casing a folder silently renamed the plugin. Every
|
|
417
|
+
* write path now persists the field (see {@link renderPluginManifest} and
|
|
418
|
+
* the rename service), and one startup step backfilled the folder's spelling
|
|
419
|
+
* into the manifests written before that, so nothing renames itself.
|
|
420
|
+
*
|
|
421
|
+
* Empty only for a manifest that names nothing at all — the shape discovery
|
|
422
|
+
* already warns about and stands the folder in as the IDENTITY for; its
|
|
423
|
+
* display name then follows that identity, never the folder directly.
|
|
424
|
+
*/
|
|
425
|
+
export declare function pluginDisplayNameOf(manifest: Record<string, unknown> | null): string;
|
|
426
|
+
/**
|
|
427
|
+
* A minimal, valid `plugin.json` for a plugin folder: the identifier the
|
|
428
|
+
* folder name folds into, and the name a person sees it by — `displayName`,
|
|
429
|
+
* ALWAYS written, so a client's picker shows "Sales Team" for `sales-team`
|
|
430
|
+
* and every reader has the one field to read.
|
|
113
431
|
*
|
|
114
|
-
*
|
|
115
|
-
*
|
|
116
|
-
*
|
|
117
|
-
*
|
|
432
|
+
* ONE argument, deliberately: `folderName` is the folder's own leaf, and on
|
|
433
|
+
* the creation path that leaf IS the name its creator typed, trimmed — the
|
|
434
|
+
* dialog's route and the `create_plugin` tool make the folder out of the
|
|
435
|
+
* typed name and hand the same string to both. A second `displayName`
|
|
436
|
+
* parameter would be a way for the two to disagree that no caller needs.
|
|
437
|
+
* The field is written even when it equals the identifier: a manifest that
|
|
438
|
+
* omits it when the two agree is a manifest whose readers need a second rule.
|
|
118
439
|
*
|
|
119
|
-
*
|
|
120
|
-
*
|
|
121
|
-
*
|
|
440
|
+
* Nothing else: `version`, `license` and the rest are metadata about a
|
|
441
|
+
* DISTRIBUTED package, and inventing values for a folder someone just made
|
|
442
|
+
* in the app would be asserting things nobody said.
|
|
122
443
|
*/
|
|
123
444
|
export declare function renderPluginManifest(folderName: string): string;
|
|
124
445
|
/**
|
|
@@ -144,6 +465,14 @@ export declare const PERSONAL_PLUGIN_PREFIX = "personal-";
|
|
|
144
465
|
export declare function personalPluginFolderName(userId: string): string;
|
|
145
466
|
/** Whether a `Plugins/` child is somebody's personal folder. */
|
|
146
467
|
export declare function isPersonalPluginFolder(folderName: string): boolean;
|
|
468
|
+
/**
|
|
469
|
+
* THE structural rule for a personal shelf: a repo-relative folder that is a
|
|
470
|
+
* DIRECT child of the plugins root and carries the personal prefix. A deeper
|
|
471
|
+
* folder so named is just a name, and a plugin whose manifest name happens
|
|
472
|
+
* to start with the prefix is a plugin — discovery, the principal picker and
|
|
473
|
+
* the item pages all ask this one question of the FOLDER.
|
|
474
|
+
*/
|
|
475
|
+
export declare function isPersonalPluginDir(repoRelDir: string): boolean;
|
|
147
476
|
/**
|
|
148
477
|
* The plugin a repo-root-relative path belongs to, or `null` for content that
|
|
149
478
|
* sits outside any plugin.
|
|
@@ -171,8 +500,25 @@ export declare const PIPELINES_DIR = "Pipelines";
|
|
|
171
500
|
/**
|
|
172
501
|
* The roots whose subfolders are discovered as ontologies by the graph parser
|
|
173
502
|
* (each subfolder with both `NodeTypes/` and `Knowledge/` is an ontology).
|
|
503
|
+
* A function, not a constant: `KNOWLEDGE_BASE_DIR` is configurable, and a
|
|
504
|
+
* module-scope array would snapshot the default before configuration.
|
|
505
|
+
*/
|
|
506
|
+
export declare function ontologyRoots(): readonly string[];
|
|
507
|
+
/**
|
|
508
|
+
* Every reserved root name, as currently configured — the set the file tree
|
|
509
|
+
* renders as its own sections rather than folding into Knowledge.
|
|
510
|
+
*/
|
|
511
|
+
export declare function reservedRootDirNames(): ReadonlySet<string>;
|
|
512
|
+
/**
|
|
513
|
+
* The roots anyone may start a new folder in — knowledge, skills and plugins
|
|
514
|
+
* — whatever the root's own `access.md` grants them. Everywhere else a change
|
|
515
|
+
* needs read access to where it lands (the "read before write" rule); a new
|
|
516
|
+
* folder directly under one of these three is the one place that rule does
|
|
517
|
+
* not apply, because the new folder carries its creator's own grant. A
|
|
518
|
+
* function, like {@link reservedRootDirNames}, because the names are
|
|
519
|
+
* configurable.
|
|
174
520
|
*/
|
|
175
|
-
export declare
|
|
521
|
+
export declare function creatableRootDirNames(): ReadonlySet<string>;
|
|
176
522
|
/** The `Knowledge/` marker subfolder of an ontology (holds the graph nodes). */
|
|
177
523
|
export declare const KNOWLEDGE_DIR = "Knowledge";
|
|
178
524
|
/** The `NodeTypes/` marker subfolder of an ontology (holds the type definitions). */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"kb-layout.d.ts","sourceRoot":"","sources":["../../src/workspace/kb-layout.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"kb-layout.d.ts","sourceRoot":"","sources":["../../src/workspace/kb-layout.ts"],"names":[],"mappings":"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"}
|