@bevel-software/platform-shared 0.1.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/LICENSE +202 -0
- package/dist/auth/types.d.ts +15 -0
- package/dist/auth/types.d.ts.map +1 -0
- package/dist/auth/types.js +2 -0
- package/dist/auth/types.js.map +1 -0
- package/dist/chat/types.d.ts +39 -0
- package/dist/chat/types.d.ts.map +1 -0
- package/dist/chat/types.js +13 -0
- package/dist/chat/types.js.map +1 -0
- package/dist/git/branchAuthor.d.ts +28 -0
- package/dist/git/branchAuthor.d.ts.map +1 -0
- package/dist/git/branchAuthor.js +45 -0
- package/dist/git/branchAuthor.js.map +1 -0
- package/dist/git/pr.types.d.ts +264 -0
- package/dist/git/pr.types.d.ts.map +1 -0
- package/dist/git/pr.types.js +2 -0
- package/dist/git/pr.types.js.map +1 -0
- package/dist/git/protected.d.ts +52 -0
- package/dist/git/protected.d.ts.map +1 -0
- package/dist/git/protected.js +92 -0
- package/dist/git/protected.js.map +1 -0
- package/dist/git/review.types.d.ts +49 -0
- package/dist/git/review.types.d.ts.map +1 -0
- package/dist/git/review.types.js +2 -0
- package/dist/git/review.types.js.map +1 -0
- package/dist/git/types.d.ts +107 -0
- package/dist/git/types.d.ts.map +1 -0
- package/dist/git/types.js +2 -0
- package/dist/git/types.js.map +1 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +20 -0
- package/dist/index.js.map +1 -0
- package/dist/workflow/events.d.ts +218 -0
- package/dist/workflow/events.d.ts.map +1 -0
- package/dist/workflow/events.js +48 -0
- package/dist/workflow/events.js.map +1 -0
- package/dist/workflow/interface.d.ts +233 -0
- package/dist/workflow/interface.d.ts.map +1 -0
- package/dist/workflow/interface.js +20 -0
- package/dist/workflow/interface.js.map +1 -0
- package/dist/workflow/types.d.ts +131 -0
- package/dist/workflow/types.d.ts.map +1 -0
- package/dist/workflow/types.js +17 -0
- package/dist/workflow/types.js.map +1 -0
- package/dist/workspace/filename.d.ts +33 -0
- package/dist/workspace/filename.d.ts.map +1 -0
- package/dist/workspace/filename.js +98 -0
- package/dist/workspace/filename.js.map +1 -0
- package/dist/workspace/frontmatter.d.ts +23 -0
- package/dist/workspace/frontmatter.d.ts.map +1 -0
- package/dist/workspace/frontmatter.js +48 -0
- package/dist/workspace/frontmatter.js.map +1 -0
- package/dist/workspace/kb-layout.d.ts +66 -0
- package/dist/workspace/kb-layout.d.ts.map +1 -0
- package/dist/workspace/kb-layout.js +63 -0
- package/dist/workspace/kb-layout.js.map +1 -0
- package/dist/workspace/types.d.ts +57 -0
- package/dist/workspace/types.d.ts.map +1 -0
- package/dist/workspace/types.js +2 -0
- package/dist/workspace/types.js.map +1 -0
- package/package.json +41 -0
- package/src/auth/types.ts +16 -0
- package/src/chat/types.ts +53 -0
- package/src/git/branchAuthor.ts +46 -0
- package/src/git/pr.types.ts +274 -0
- package/src/git/protected.ts +121 -0
- package/src/git/review.types.ts +51 -0
- package/src/git/types.ts +170 -0
- package/src/index.ts +23 -0
- package/src/workflow/events.ts +271 -0
- package/src/workflow/interface.ts +357 -0
- package/src/workflow/types.ts +156 -0
- package/src/workspace/filename.ts +102 -0
- package/src/workspace/frontmatter.ts +45 -0
- package/src/workspace/kb-layout.ts +81 -0
- package/src/workspace/types.ts +59 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"frontmatter.d.ts","sourceRoot":"","sources":["../../src/workspace/frontmatter.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG;IAAE,WAAW,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAI7F;AAED;;;;;;;;;GASG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAqBpF"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The ONE `---` frontmatter splitter, shared by backend and frontend so no file
|
|
3
|
+
* type grows its own regex. Splits a leading `---`-fenced YAML block from the
|
|
4
|
+
* body; null when the text doesn't open with a fence. Parsing the YAML inside is
|
|
5
|
+
* the caller's concern (the access-control resolver deliberately keeps its own
|
|
6
|
+
* hardened line-based reader — see `modules/access/access-splice.ts`).
|
|
7
|
+
*/
|
|
8
|
+
export function extractFrontmatter(text) {
|
|
9
|
+
const m = text.match(/^---\r?\n([\s\S]*?)\r?\n---\r?\n?([\s\S]*)$/);
|
|
10
|
+
if (!m)
|
|
11
|
+
return null;
|
|
12
|
+
return { frontmatter: m[1], body: m[2] };
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Set a top-level scalar key in a file's `---` frontmatter, LINE-based: replace an
|
|
16
|
+
* existing `<key>:` line's value, else insert `<key>: <value>` at the top of the
|
|
17
|
+
* block (creating a `---` block if the file has none). Deliberately NOT a
|
|
18
|
+
* parse-and-re-serialize — a KB node's `nodeType:` quoted-markdown-link and access
|
|
19
|
+
* lines are read by a hand-rolled regex parser that a full YAML re-emit would
|
|
20
|
+
* corrupt, so every other line is preserved byte-for-byte. `value` is emitted as a
|
|
21
|
+
* bare scalar; callers pass simple id/name strings (no quoting/escaping needed for
|
|
22
|
+
* the `[a-z0-9_-]` id grammar).
|
|
23
|
+
*/
|
|
24
|
+
export function setFrontmatterField(text, key, value) {
|
|
25
|
+
const fm = extractFrontmatter(text);
|
|
26
|
+
const line = `${key}: ${value}`;
|
|
27
|
+
// Escape the key before interpolating — callers pass plain `id`/`name`, but a
|
|
28
|
+
// metacharacter must never silently change what the line-matcher matches.
|
|
29
|
+
const keyRe = new RegExp(`^(\\s*)${key.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}:.*$`);
|
|
30
|
+
// Preserve the file's own line-ending convention: rebuilding a CRLF file with
|
|
31
|
+
// bare `\n` would dirty every frontmatter line, breaking the byte-for-byte
|
|
32
|
+
// guarantee this helper exists for. Judged from the FIRST line ending (the
|
|
33
|
+
// fence line's own), so a stray CRLF deep in the body can't flip the block.
|
|
34
|
+
const firstNl = text.indexOf('\n');
|
|
35
|
+
const eol = firstNl > 0 && text[firstNl - 1] === '\r' ? '\r\n' : '\n';
|
|
36
|
+
if (!fm) {
|
|
37
|
+
// No frontmatter — prepend a fresh block, keeping the original body intact.
|
|
38
|
+
return `---${eol}${line}${eol}---${eol}${text}`;
|
|
39
|
+
}
|
|
40
|
+
const fmLines = fm.frontmatter.split(/\r?\n/);
|
|
41
|
+
const idx = fmLines.findIndex((l) => keyRe.test(l));
|
|
42
|
+
if (idx >= 0)
|
|
43
|
+
fmLines[idx] = line;
|
|
44
|
+
else
|
|
45
|
+
fmLines.unshift(line);
|
|
46
|
+
return `---${eol}${fmLines.join(eol)}${eol}---${eol}${fm.body}`;
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=frontmatter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"frontmatter.js","sourceRoot":"","sources":["../../src/workspace/frontmatter.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,MAAM,UAAU,kBAAkB,CAAC,IAAY;IAC7C,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,6CAA6C,CAAC,CAAC;IACpE,IAAI,CAAC,CAAC;QAAE,OAAO,IAAI,CAAC;IACpB,OAAO,EAAE,WAAW,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;AAC3C,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,mBAAmB,CAAC,IAAY,EAAE,GAAW,EAAE,KAAa;IAC1E,MAAM,EAAE,GAAG,kBAAkB,CAAC,IAAI,CAAC,CAAC;IACpC,MAAM,IAAI,GAAG,GAAG,GAAG,KAAK,KAAK,EAAE,CAAC;IAChC,8EAA8E;IAC9E,0EAA0E;IAC1E,MAAM,KAAK,GAAG,IAAI,MAAM,CAAC,UAAU,GAAG,CAAC,OAAO,CAAC,qBAAqB,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;IACrF,8EAA8E;IAC9E,2EAA2E;IAC3E,2EAA2E;IAC3E,4EAA4E;IAC5E,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IACnC,MAAM,GAAG,GAAG,OAAO,GAAG,CAAC,IAAI,IAAI,CAAC,OAAO,GAAG,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC;IACtE,IAAI,CAAC,EAAE,EAAE,CAAC;QACR,4EAA4E;QAC5E,OAAO,MAAM,GAAG,GAAG,IAAI,GAAG,GAAG,MAAM,GAAG,GAAG,IAAI,EAAE,CAAC;IAClD,CAAC;IACD,MAAM,OAAO,GAAG,EAAE,CAAC,WAAW,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAC9C,MAAM,GAAG,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;IACpD,IAAI,GAAG,IAAI,CAAC;QAAE,OAAO,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC;;QAC7B,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3B,OAAO,MAAM,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,GAAG,MAAM,GAAG,GAAG,EAAE,CAAC,IAAI,EAAE,CAAC;AAClE,CAAC"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Top-level layout of the KB repo (inside the `KB_DIR_NAME` clone).
|
|
3
|
+
*
|
|
4
|
+
* The repo root holds a small, fixed set of special folders that the app
|
|
5
|
+
* treats distinctly:
|
|
6
|
+
*
|
|
7
|
+
* <kbDirName>/
|
|
8
|
+
* ├── KnowledgeBase/ ← all team ontologies live here (the knowledge graph)
|
|
9
|
+
* ├── Data/ ← agent-produced records; parsed like KnowledgeBase/
|
|
10
|
+
* ├── Agents/ ← .agent files — agent role configurations (not the graph)
|
|
11
|
+
* ├── Pipelines/ ← .pipeline files — execution-layer processes (not the graph)
|
|
12
|
+
* ├── Skills/ ← reusable agent skills (NOT part of the graph)
|
|
13
|
+
* ├── Tools/ ← user-authored tool manuals (*.tool; not the graph)
|
|
14
|
+
* ├── roles.yaml ← identity → role mapping
|
|
15
|
+
* └── access.md ← repo-root access-control rules
|
|
16
|
+
*
|
|
17
|
+
* These names are the single source of truth for both sides of the app:
|
|
18
|
+
* - Backend: the graph parser discovers ontologies under the
|
|
19
|
+
* {@link ONTOLOGY_ROOTS} (`KnowledgeBase/` and `Data/`); `Skills/`,
|
|
20
|
+
* `Tools/`, `Agents/`, `Pipelines/` (and anything else at the root) are
|
|
21
|
+
* ignored by parsing, validation, and the diagram.
|
|
22
|
+
* - Frontend: the file tree renders these root folders as distinct
|
|
23
|
+
* top-level sections.
|
|
24
|
+
*
|
|
25
|
+
* Don't hard-code these strings elsewhere — import them from here.
|
|
26
|
+
*/
|
|
27
|
+
/** Folder under the repo root that contains all team ontologies. */
|
|
28
|
+
export declare const KNOWLEDGE_BASE_DIR = "KnowledgeBase";
|
|
29
|
+
/** Folder under the repo root that holds reusable agent skills (not graph nodes). */
|
|
30
|
+
export declare const SKILLS_DIR = "Skills";
|
|
31
|
+
/**
|
|
32
|
+
* Folder under the repo root that holds user-authored tool manuals (`*.tool`
|
|
33
|
+
* files). Each `.tool` is a UTCP manual (inline / http / mcp) that the MCP/UTCP
|
|
34
|
+
* endpoint loads for any user who can read it (access-controlled like Skills).
|
|
35
|
+
* Not part of the knowledge graph.
|
|
36
|
+
*/
|
|
37
|
+
export declare const TOOLS_DIR = "Tools";
|
|
38
|
+
/**
|
|
39
|
+
* Folder under the repo root for agent-produced records (pipeline instances,
|
|
40
|
+
* work items, intermediate outputs). Parsed exactly like `KnowledgeBase/`:
|
|
41
|
+
* its direct subfolders are self-contained ontologies.
|
|
42
|
+
*/
|
|
43
|
+
export declare const DATA_DIR = "Data";
|
|
44
|
+
/** Folder under the repo root that holds `.agent` files — agent role configurations (not graph nodes). */
|
|
45
|
+
export declare const AGENTS_DIR = "Agents";
|
|
46
|
+
/** Folder under the repo root that holds `.pipeline` files — execution-layer processes (not graph nodes). */
|
|
47
|
+
export declare const PIPELINES_DIR = "Pipelines";
|
|
48
|
+
/**
|
|
49
|
+
* The roots whose subfolders are discovered as ontologies by the graph parser
|
|
50
|
+
* (each subfolder with both `NodeTypes/` and `Knowledge/` is an ontology).
|
|
51
|
+
*/
|
|
52
|
+
export declare const ONTOLOGY_ROOTS: readonly string[];
|
|
53
|
+
/** The `Knowledge/` marker subfolder of an ontology (holds the graph nodes). */
|
|
54
|
+
export declare const KNOWLEDGE_DIR = "Knowledge";
|
|
55
|
+
/** The `NodeTypes/` marker subfolder of an ontology (holds the type definitions). */
|
|
56
|
+
export declare const NODETYPE_DIR = "NodeTypes";
|
|
57
|
+
/** The marker subfolders that make a directory an ontology (it needs BOTH). */
|
|
58
|
+
export declare const ONTOLOGY_MARKERS: Set<string>;
|
|
59
|
+
/**
|
|
60
|
+
* A named ontology id, or `null` for the neutral bucket — content that belongs
|
|
61
|
+
* to no named ontology (root config, `Skills/`, root-level `Knowledge/`, etc.).
|
|
62
|
+
* The named id is the repo-root-relative path of the ontology directory,
|
|
63
|
+
* e.g. `KnowledgeBase/Product` or `KnowledgeBase/IT Architecture`.
|
|
64
|
+
*/
|
|
65
|
+
export type Ontology = string | null;
|
|
66
|
+
//# sourceMappingURL=kb-layout.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"kb-layout.d.ts","sourceRoot":"","sources":["../../src/workspace/kb-layout.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,oEAAoE;AACpE,eAAO,MAAM,kBAAkB,kBAAkB,CAAC;AAElD,qFAAqF;AACrF,eAAO,MAAM,UAAU,WAAW,CAAC;AAEnC;;;;;GAKG;AACH,eAAO,MAAM,SAAS,UAAU,CAAC;AAEjC;;;;GAIG;AACH,eAAO,MAAM,QAAQ,SAAS,CAAC;AAE/B,0GAA0G;AAC1G,eAAO,MAAM,UAAU,WAAW,CAAC;AAEnC,6GAA6G;AAC7G,eAAO,MAAM,aAAa,cAAc,CAAC;AAEzC;;;GAGG;AACH,eAAO,MAAM,cAAc,EAAE,SAAS,MAAM,EAAmC,CAAC;AAEhF,gFAAgF;AAChF,eAAO,MAAM,aAAa,cAAc,CAAC;AAEzC,qFAAqF;AACrF,eAAO,MAAM,YAAY,cAAc,CAAC;AAExC,+EAA+E;AAC/E,eAAO,MAAM,gBAAgB,aAAyC,CAAC;AAEvE;;;;;GAKG;AACH,MAAM,MAAM,QAAQ,GAAG,MAAM,GAAG,IAAI,CAAC"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Top-level layout of the KB repo (inside the `KB_DIR_NAME` clone).
|
|
3
|
+
*
|
|
4
|
+
* The repo root holds a small, fixed set of special folders that the app
|
|
5
|
+
* treats distinctly:
|
|
6
|
+
*
|
|
7
|
+
* <kbDirName>/
|
|
8
|
+
* ├── KnowledgeBase/ ← all team ontologies live here (the knowledge graph)
|
|
9
|
+
* ├── Data/ ← agent-produced records; parsed like KnowledgeBase/
|
|
10
|
+
* ├── Agents/ ← .agent files — agent role configurations (not the graph)
|
|
11
|
+
* ├── Pipelines/ ← .pipeline files — execution-layer processes (not the graph)
|
|
12
|
+
* ├── Skills/ ← reusable agent skills (NOT part of the graph)
|
|
13
|
+
* ├── Tools/ ← user-authored tool manuals (*.tool; not the graph)
|
|
14
|
+
* ├── roles.yaml ← identity → role mapping
|
|
15
|
+
* └── access.md ← repo-root access-control rules
|
|
16
|
+
*
|
|
17
|
+
* These names are the single source of truth for both sides of the app:
|
|
18
|
+
* - Backend: the graph parser discovers ontologies under the
|
|
19
|
+
* {@link ONTOLOGY_ROOTS} (`KnowledgeBase/` and `Data/`); `Skills/`,
|
|
20
|
+
* `Tools/`, `Agents/`, `Pipelines/` (and anything else at the root) are
|
|
21
|
+
* ignored by parsing, validation, and the diagram.
|
|
22
|
+
* - Frontend: the file tree renders these root folders as distinct
|
|
23
|
+
* top-level sections.
|
|
24
|
+
*
|
|
25
|
+
* Don't hard-code these strings elsewhere — import them from here.
|
|
26
|
+
*/
|
|
27
|
+
/** Folder under the repo root that contains all team ontologies. */
|
|
28
|
+
export const KNOWLEDGE_BASE_DIR = 'KnowledgeBase';
|
|
29
|
+
/** Folder under the repo root that holds reusable agent skills (not graph nodes). */
|
|
30
|
+
export const SKILLS_DIR = 'Skills';
|
|
31
|
+
/**
|
|
32
|
+
* Folder under the repo root that holds user-authored tool manuals (`*.tool`
|
|
33
|
+
* files). Each `.tool` is a UTCP manual (inline / http / mcp) that the MCP/UTCP
|
|
34
|
+
* endpoint loads for any user who can read it (access-controlled like Skills).
|
|
35
|
+
* Not part of the knowledge graph.
|
|
36
|
+
*/
|
|
37
|
+
export const TOOLS_DIR = 'Tools';
|
|
38
|
+
/**
|
|
39
|
+
* Folder under the repo root for agent-produced records (pipeline instances,
|
|
40
|
+
* work items, intermediate outputs). Parsed exactly like `KnowledgeBase/`:
|
|
41
|
+
* its direct subfolders are self-contained ontologies.
|
|
42
|
+
*/
|
|
43
|
+
export const DATA_DIR = 'Data';
|
|
44
|
+
/** Folder under the repo root that holds `.agent` files — agent role configurations (not graph nodes). */
|
|
45
|
+
export const AGENTS_DIR = 'Agents';
|
|
46
|
+
/** Folder under the repo root that holds `.pipeline` files — execution-layer processes (not graph nodes). */
|
|
47
|
+
export const PIPELINES_DIR = 'Pipelines';
|
|
48
|
+
/**
|
|
49
|
+
* The roots whose subfolders are discovered as ontologies by the graph parser
|
|
50
|
+
* (each subfolder with both `NodeTypes/` and `Knowledge/` is an ontology).
|
|
51
|
+
*/
|
|
52
|
+
export const ONTOLOGY_ROOTS = [KNOWLEDGE_BASE_DIR, DATA_DIR];
|
|
53
|
+
/** The `Knowledge/` marker subfolder of an ontology (holds the graph nodes). */
|
|
54
|
+
export const KNOWLEDGE_DIR = 'Knowledge';
|
|
55
|
+
/** The `NodeTypes/` marker subfolder of an ontology (holds the type definitions). */
|
|
56
|
+
export const NODETYPE_DIR = 'NodeTypes';
|
|
57
|
+
/** The marker subfolders that make a directory an ontology (it needs BOTH). */
|
|
58
|
+
export const ONTOLOGY_MARKERS = new Set([KNOWLEDGE_DIR, NODETYPE_DIR]);
|
|
59
|
+
// The implementation that resolves a path to its `Ontology` (`ontologyOf`) is
|
|
60
|
+
// backend-only — it lives in `packages/backend/src/shared/kb-layout.ts`, built
|
|
61
|
+
// from the `KNOWLEDGE_BASE_DIR` / `ONTOLOGY_MARKERS` constants above. This
|
|
62
|
+
// package holds only the cross-cutting constants and types, not logic.
|
|
63
|
+
//# sourceMappingURL=kb-layout.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"kb-layout.js","sourceRoot":"","sources":["../../src/workspace/kb-layout.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,oEAAoE;AACpE,MAAM,CAAC,MAAM,kBAAkB,GAAG,eAAe,CAAC;AAElD,qFAAqF;AACrF,MAAM,CAAC,MAAM,UAAU,GAAG,QAAQ,CAAC;AAEnC;;;;;GAKG;AACH,MAAM,CAAC,MAAM,SAAS,GAAG,OAAO,CAAC;AAEjC;;;;GAIG;AACH,MAAM,CAAC,MAAM,QAAQ,GAAG,MAAM,CAAC;AAE/B,0GAA0G;AAC1G,MAAM,CAAC,MAAM,UAAU,GAAG,QAAQ,CAAC;AAEnC,6GAA6G;AAC7G,MAAM,CAAC,MAAM,aAAa,GAAG,WAAW,CAAC;AAEzC;;;GAGG;AACH,MAAM,CAAC,MAAM,cAAc,GAAsB,CAAC,kBAAkB,EAAE,QAAQ,CAAC,CAAC;AAEhF,gFAAgF;AAChF,MAAM,CAAC,MAAM,aAAa,GAAG,WAAW,CAAC;AAEzC,qFAAqF;AACrF,MAAM,CAAC,MAAM,YAAY,GAAG,WAAW,CAAC;AAExC,+EAA+E;AAC/E,MAAM,CAAC,MAAM,gBAAgB,GAAG,IAAI,GAAG,CAAC,CAAC,aAAa,EAAE,YAAY,CAAC,CAAC,CAAC;AAUvE,8EAA8E;AAC9E,+EAA+E;AAC/E,2EAA2E;AAC3E,uEAAuE"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
export interface WorkspaceInfo {
|
|
2
|
+
/**
|
|
3
|
+
* Workspace id = `encodeURIComponent(branch)`. Stable across users — a
|
|
4
|
+
* branch's workspace is shared by everyone editing it (PLAN §3).
|
|
5
|
+
* Decoding rule: callers can derive the branch via
|
|
6
|
+
* `decodeURIComponent(id)` without a backend round-trip.
|
|
7
|
+
*/
|
|
8
|
+
id: string;
|
|
9
|
+
/** Display name. Currently the branch name verbatim. */
|
|
10
|
+
name: string;
|
|
11
|
+
/** Absolute path on the backend's filesystem (debug / log surface only). */
|
|
12
|
+
absolutePath: string;
|
|
13
|
+
/** ISO timestamp. Per-branch workspaces have no meaningful creation time; epoch is fine. */
|
|
14
|
+
createdAt: string;
|
|
15
|
+
/**
|
|
16
|
+
* Directory name (relative to `absolutePath`) where the KB clone lives.
|
|
17
|
+
* Configured via `KB_DIR_NAME` on the backend; surfaced to the frontend
|
|
18
|
+
* so renderers and chat cards can build correct KB-relative paths
|
|
19
|
+
* without hardcoding the repo name.
|
|
20
|
+
*/
|
|
21
|
+
kbDirName: string;
|
|
22
|
+
}
|
|
23
|
+
export interface FileTreeEntry {
|
|
24
|
+
name: string;
|
|
25
|
+
relativePath: string;
|
|
26
|
+
type: 'file' | 'directory';
|
|
27
|
+
children?: FileTreeEntry[];
|
|
28
|
+
}
|
|
29
|
+
import type { AuthUser } from '../auth/types.js';
|
|
30
|
+
export interface IWorkspaceService {
|
|
31
|
+
/**
|
|
32
|
+
* Get-or-create the workspace for a branch. Workspaces are per-branch
|
|
33
|
+
* (PLAN §3) — every user editing `branch` shares the same on-disk clone,
|
|
34
|
+
* coordinated by the file-lock service.
|
|
35
|
+
*/
|
|
36
|
+
getOrCreateForBranch(branch: string): Promise<WorkspaceInfo>;
|
|
37
|
+
/**
|
|
38
|
+
* Convenience wrapper that defaults to the configured default branch
|
|
39
|
+
* (`DEFAULT_BRANCH`) when no branch is provided. Kept on the interface so route handlers that
|
|
40
|
+
* receive a logged-in user but no explicit branch can still bootstrap a
|
|
41
|
+
* workspace.
|
|
42
|
+
*/
|
|
43
|
+
getOrCreateForUser(user: AuthUser, branch?: string): Promise<WorkspaceInfo>;
|
|
44
|
+
getMetadata(workspaceId: string): Promise<WorkspaceInfo | null>;
|
|
45
|
+
deleteWorkspace(workspaceId: string): Promise<void>;
|
|
46
|
+
listFiles(workspaceId: string): Promise<FileTreeEntry>;
|
|
47
|
+
readFile(workspaceId: string, relativePath: string): Promise<string>;
|
|
48
|
+
writeFile(workspaceId: string, relativePath: string, content: string): Promise<void>;
|
|
49
|
+
createDirectory(workspaceId: string, relativePath: string): Promise<void>;
|
|
50
|
+
writeFileBinary(workspaceId: string, relativePath: string, data: Uint8Array): Promise<void>;
|
|
51
|
+
deleteFile(workspaceId: string, relativePath: string): Promise<void>;
|
|
52
|
+
moveEntry(workspaceId: string, oldRelativePath: string, newRelativePath: string): Promise<void>;
|
|
53
|
+
getWorkspacePath(workspaceId: string): Promise<string>;
|
|
54
|
+
/** Remove the workspace's transient `tmp/` dir (staged docs, tool-chain spills). */
|
|
55
|
+
clearTmp(workspaceId: string): Promise<void>;
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/workspace/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,aAAa;IAC5B;;;;;OAKG;IACH,EAAE,EAAE,MAAM,CAAC;IACX,wDAAwD;IACxD,IAAI,EAAE,MAAM,CAAC;IACb,4EAA4E;IAC5E,YAAY,EAAE,MAAM,CAAC;IACrB,4FAA4F;IAC5F,SAAS,EAAE,MAAM,CAAC;IAClB;;;;;OAKG;IACH,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,MAAM,GAAG,WAAW,CAAC;IAC3B,QAAQ,CAAC,EAAE,aAAa,EAAE,CAAC;CAC5B;AAED,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAEjD,MAAM,WAAW,iBAAiB;IAChC;;;;OAIG;IACH,oBAAoB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC;IAC7D;;;;;OAKG;IACH,kBAAkB,CAAC,IAAI,EAAE,QAAQ,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC;IAC5E,WAAW,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC,CAAC;IAChE,eAAe,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACpD,SAAS,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC;IACvD,QAAQ,CAAC,WAAW,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACrE,SAAS,CAAC,WAAW,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACrF,eAAe,CAAC,WAAW,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1E,eAAe,CAAC,WAAW,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5F,UAAU,CAAC,WAAW,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACrE,SAAS,CAAC,WAAW,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAChG,gBAAgB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACvD,oFAAoF;IACpF,QAAQ,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC9C"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/workspace/types.ts"],"names":[],"mappings":""}
|
package/package.json
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@bevel-software/platform-shared",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Shared types and pure domain utilities of the Bevel core platform (auth, workspace, git/workflow contracts, branch registry).",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"default": "./dist/index.js"
|
|
12
|
+
},
|
|
13
|
+
"./package.json": "./package.json"
|
|
14
|
+
},
|
|
15
|
+
"files": [
|
|
16
|
+
"dist",
|
|
17
|
+
"src"
|
|
18
|
+
],
|
|
19
|
+
"engines": {
|
|
20
|
+
"node": ">=22 <23"
|
|
21
|
+
},
|
|
22
|
+
"dependencies": {
|
|
23
|
+
"ai": "^6.0.161"
|
|
24
|
+
},
|
|
25
|
+
"devDependencies": {
|
|
26
|
+
"typescript": "^5.8.0"
|
|
27
|
+
},
|
|
28
|
+
"license": "Apache-2.0",
|
|
29
|
+
"repository": {
|
|
30
|
+
"type": "git",
|
|
31
|
+
"url": "git+https://github.com/Bevel-Software/skill-and-tool-management.git",
|
|
32
|
+
"directory": "packages/shared"
|
|
33
|
+
},
|
|
34
|
+
"publishConfig": {
|
|
35
|
+
"access": "public"
|
|
36
|
+
},
|
|
37
|
+
"scripts": {
|
|
38
|
+
"build": "tsc -p tsconfig.json",
|
|
39
|
+
"typecheck": "tsc -p tsconfig.json --noEmit"
|
|
40
|
+
}
|
|
41
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export interface AuthUser {
|
|
2
|
+
id: string;
|
|
3
|
+
email: string;
|
|
4
|
+
name: string;
|
|
5
|
+
avatarUrl?: string;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export interface LoginRequest {
|
|
9
|
+
email: string;
|
|
10
|
+
password: string;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export interface LoginResponse {
|
|
14
|
+
token: string;
|
|
15
|
+
user: AuthUser;
|
|
16
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import type { UIMessage } from 'ai';
|
|
2
|
+
import type { AuthUser } from '../auth/types.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Domain-owned alias for the AI SDK v5 UIMessage shape.
|
|
6
|
+
*
|
|
7
|
+
* Backend and frontend both import `ChatUIMessage` rather than `UIMessage`
|
|
8
|
+
* directly so the seam is renameable if the SDK type shifts.
|
|
9
|
+
*/
|
|
10
|
+
export type ChatUIMessage = UIMessage;
|
|
11
|
+
|
|
12
|
+
export interface ChatThread {
|
|
13
|
+
id: string;
|
|
14
|
+
title: string;
|
|
15
|
+
createdAt: number;
|
|
16
|
+
updatedAt: number;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
// Calibrated for gpt-5.1 (~400k context) with current agent.instructions.ts size
|
|
20
|
+
// + typical KB file tree. Lower than the raw window because the system prompt
|
|
21
|
+
// and workspace state occupy ~40-80k before the user types. Re-tune if the
|
|
22
|
+
// model changes or the system prompt grows materially.
|
|
23
|
+
//
|
|
24
|
+
// Both thresholds drive the agent's input processors in BaseAgentFactory:
|
|
25
|
+
// - softLimit → SummaryCompactor recaps the middle of the transcript
|
|
26
|
+
// - hardLimit → TokenLimiterProcessor backstops with truncation
|
|
27
|
+
// The composer's context-usage gauge also reads these via the UsagePartData
|
|
28
|
+
// emitted at end-of-turn.
|
|
29
|
+
export const COMPACTION_SOFT_LIMIT_TOKENS = 200_000;
|
|
30
|
+
export const COMPACTION_HARD_LIMIT_TOKENS = 350_000;
|
|
31
|
+
|
|
32
|
+
/** Per-turn token usage attached to the assistant message via a `data-usage` part. */
|
|
33
|
+
export interface UsagePartData {
|
|
34
|
+
used: number;
|
|
35
|
+
softLimit: number;
|
|
36
|
+
hardLimit: number;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export interface IChatService {
|
|
40
|
+
streamResponse(params: {
|
|
41
|
+
message: string;
|
|
42
|
+
resourceId: string;
|
|
43
|
+
threadId: string;
|
|
44
|
+
workspaceId: string;
|
|
45
|
+
/**
|
|
46
|
+
* Required — the agent authors every git commit as the user, and the
|
|
47
|
+
* author marker it pastes into PR bodies is derived from the user's email.
|
|
48
|
+
* Backend reads `user.name` and `user.email` unconditionally.
|
|
49
|
+
*/
|
|
50
|
+
user: AuthUser;
|
|
51
|
+
abortSignal?: AbortSignal;
|
|
52
|
+
}): Promise<ReadableStream<unknown>>;
|
|
53
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Derive the kebab-cased branch-author localpart from an email.
|
|
3
|
+
*
|
|
4
|
+
* The frontend's `slugifyDraftName` lowercases the email's localpart and
|
|
5
|
+
* replaces non-alphanumeric runs with `-` when building a new branch name
|
|
6
|
+
* (e.g. `Alice@example.com` → `alice/<slug>`, `john.doe@…` → `john-doe/…`).
|
|
7
|
+
* Authorship lookup must use the same transformation so a branch the user
|
|
8
|
+
* could create via the UI is also recognised as theirs on delete.
|
|
9
|
+
*
|
|
10
|
+
* Returns `null` when the email is missing or sanitizes to an empty string —
|
|
11
|
+
* authorship MUST NOT silently fall back to a default identity like `user`.
|
|
12
|
+
* If the helper returned a fallback, any user without a valid localpart
|
|
13
|
+
* would be granted ownership of every `user/...` branch on origin, which is
|
|
14
|
+
* the opposite of the safety property `isBranchAuthoredBy` is meant to
|
|
15
|
+
* provide. The frontend's `slugifyDraftName` can keep its UI-side `user`
|
|
16
|
+
* fallback at the call site because draft creation is not access-gated.
|
|
17
|
+
*/
|
|
18
|
+
export function branchAuthorLocalpart(
|
|
19
|
+
email: string | null | undefined,
|
|
20
|
+
): string | null {
|
|
21
|
+
if (!email) return null;
|
|
22
|
+
const before = email.split('@')[0];
|
|
23
|
+
if (!before) return null;
|
|
24
|
+
const sanitized = before.toLowerCase().replace(/[^a-z0-9]+/g, '-');
|
|
25
|
+
// Sanitized can be all dashes (`-`, `--`) when every char was non-alphanumeric;
|
|
26
|
+
// treat that as no usable identity.
|
|
27
|
+
if (!sanitized.replace(/-/g, '')) return null;
|
|
28
|
+
return sanitized;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* True when `branchName` starts with `<email-localpart>/` — i.e. when the
|
|
33
|
+
* branch matches the UI-created draft convention for this user.
|
|
34
|
+
*
|
|
35
|
+
* The trailing `/` is REQUIRED: without it, `alice-extra/foo` would look
|
|
36
|
+
* authored by `alice@…`, and any user could delete branches whose prefix
|
|
37
|
+
* happens to start with their own localpart. Substring is not authorship.
|
|
38
|
+
*/
|
|
39
|
+
export function isBranchAuthoredBy(
|
|
40
|
+
branchName: string,
|
|
41
|
+
email: string | null | undefined,
|
|
42
|
+
): boolean {
|
|
43
|
+
const localpart = branchAuthorLocalpart(email);
|
|
44
|
+
if (!localpart) return false;
|
|
45
|
+
return branchName.startsWith(`${localpart}/`);
|
|
46
|
+
}
|