@corenel/tools-node 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/dist/auth.d.ts +9 -0
- package/dist/auth.d.ts.map +1 -0
- package/dist/auth.js +41 -0
- package/dist/auth.js.map +1 -0
- package/dist/fileService.d.ts +33 -0
- package/dist/fileService.d.ts.map +1 -0
- package/dist/fileService.js +181 -0
- package/dist/fileService.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -0
- package/dist/promptHost.d.ts +6 -0
- package/dist/promptHost.d.ts.map +1 -0
- package/dist/promptHost.js +72 -0
- package/dist/promptHost.js.map +1 -0
- package/dist/verify.d.ts +2 -0
- package/dist/verify.d.ts.map +1 -0
- package/dist/verify.js +61 -0
- package/dist/verify.js.map +1 -0
- package/package.json +42 -0
package/dist/auth.d.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { IAuthTokenProvider } from '@corenel/protocol';
|
|
2
|
+
export declare function corenelDir(): string;
|
|
3
|
+
export declare function authTokenPath(): string;
|
|
4
|
+
export declare function writeAuthToken(token: string): Promise<void>;
|
|
5
|
+
export declare function readAuthToken(): Promise<string | null>;
|
|
6
|
+
export declare function clearAuthToken(): Promise<void>;
|
|
7
|
+
/** The IAuthTokenProvider for node: the stored login token, else CORENEL_TOKEN env. */
|
|
8
|
+
export declare function nodeAuthToken(): IAuthTokenProvider;
|
|
9
|
+
//# sourceMappingURL=auth.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../auth.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAE5D,wBAAgB,UAAU,IAAI,MAAM,CAEnC;AACD,wBAAgB,aAAa,IAAI,MAAM,CAEtC;AAED,wBAAsB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAIjE;AAED,wBAAsB,aAAa,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAO5D;AAED,wBAAsB,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC,CAEpD;AAED,uFAAuF;AACvF,wBAAgB,aAAa,IAAI,kBAAkB,CAElD"}
|
package/dist/auth.js
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/* Node auth token store — ~/.corenel/token (owner-only). `corenel login` writes it
|
|
2
|
+
* via the device flow; the CLI's token guard + gateway client read it through the
|
|
3
|
+
* IAuthTokenProvider port (falling back to the CORENEL_TOKEN env). Separate from
|
|
4
|
+
* the sidecar's ~/.corenel/daemon.token (that's the local pairing token). */
|
|
5
|
+
import { promises as fs } from 'node:fs';
|
|
6
|
+
import { homedir } from 'node:os';
|
|
7
|
+
import { join } from 'node:path';
|
|
8
|
+
export function corenelDir() {
|
|
9
|
+
return join(homedir(), '.corenel');
|
|
10
|
+
}
|
|
11
|
+
export function authTokenPath() {
|
|
12
|
+
return join(corenelDir(), 'token');
|
|
13
|
+
}
|
|
14
|
+
export async function writeAuthToken(token) {
|
|
15
|
+
await fs.mkdir(corenelDir(), { recursive: true });
|
|
16
|
+
await fs.writeFile(authTokenPath(), token.trim() + '\n', { mode: 0o600 });
|
|
17
|
+
try {
|
|
18
|
+
await fs.chmod(authTokenPath(), 0o600);
|
|
19
|
+
}
|
|
20
|
+
catch { /* non-POSIX */ }
|
|
21
|
+
}
|
|
22
|
+
export async function readAuthToken() {
|
|
23
|
+
try {
|
|
24
|
+
const t = (await fs.readFile(authTokenPath(), 'utf8')).trim();
|
|
25
|
+
return t || null;
|
|
26
|
+
}
|
|
27
|
+
catch {
|
|
28
|
+
return null;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
export async function clearAuthToken() {
|
|
32
|
+
try {
|
|
33
|
+
await fs.rm(authTokenPath(), { force: true });
|
|
34
|
+
}
|
|
35
|
+
catch { /* already gone */ }
|
|
36
|
+
}
|
|
37
|
+
/** The IAuthTokenProvider for node: the stored login token, else CORENEL_TOKEN env. */
|
|
38
|
+
export function nodeAuthToken() {
|
|
39
|
+
return { getToken: async () => (await readAuthToken()) ?? process.env.CORENEL_TOKEN ?? null };
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=auth.js.map
|
package/dist/auth.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../auth.ts"],"names":[],"mappings":"AAAA;;;6EAG6E;AAC7E,OAAO,EAAE,QAAQ,IAAI,EAAE,EAAE,MAAM,SAAS,CAAC;AACzC,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAGjC,MAAM,UAAU,UAAU;IACxB,OAAO,IAAI,CAAC,OAAO,EAAE,EAAE,UAAU,CAAC,CAAC;AACrC,CAAC;AACD,MAAM,UAAU,aAAa;IAC3B,OAAO,IAAI,CAAC,UAAU,EAAE,EAAE,OAAO,CAAC,CAAC;AACrC,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,KAAa;IAChD,MAAM,EAAE,CAAC,KAAK,CAAC,UAAU,EAAE,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAClD,MAAM,EAAE,CAAC,SAAS,CAAC,aAAa,EAAE,EAAE,KAAK,CAAC,IAAI,EAAE,GAAG,IAAI,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IAC1E,IAAI,CAAC;QAAC,MAAM,EAAE,CAAC,KAAK,CAAC,aAAa,EAAE,EAAE,KAAK,CAAC,CAAC;IAAC,CAAC;IAAC,MAAM,CAAC,CAAC,eAAe,CAAC,CAAC;AAC3E,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,aAAa;IACjC,IAAI,CAAC;QACH,MAAM,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,aAAa,EAAE,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAC9D,OAAO,CAAC,IAAI,IAAI,CAAC;IACnB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,cAAc;IAClC,IAAI,CAAC;QAAC,MAAM,EAAE,CAAC,EAAE,CAAC,aAAa,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IAAC,CAAC;IAAC,MAAM,CAAC,CAAC,kBAAkB,CAAC,CAAC;AACrF,CAAC;AAED,uFAAuF;AACvF,MAAM,UAAU,aAAa;IAC3B,OAAO,EAAE,QAAQ,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC,MAAM,aAAa,EAAE,CAAC,IAAI,OAAO,CAAC,GAAG,CAAC,aAAa,IAAI,IAAI,EAAE,CAAC;AAChG,CAAC"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { FileService, FileNode, FileStat, FileServiceKind } from '@corenel/protocol';
|
|
2
|
+
export declare class NodeFileService implements FileService {
|
|
3
|
+
readonly kind: FileServiceKind;
|
|
4
|
+
readonly label: string;
|
|
5
|
+
readonly isLocalDisk = true;
|
|
6
|
+
readonly writable: boolean;
|
|
7
|
+
private readonly root;
|
|
8
|
+
constructor(root: string, opts?: {
|
|
9
|
+
writable?: boolean;
|
|
10
|
+
});
|
|
11
|
+
/** True if `a` is lexically within the root (the root itself counts). */
|
|
12
|
+
private within;
|
|
13
|
+
/** Absolute path for a folder-relative one, rejecting anything that escapes root
|
|
14
|
+
* LEXICALLY (../, absolute). Symlink escapes are caught by assertReal/realAbs. */
|
|
15
|
+
private abs;
|
|
16
|
+
/** Defense against SYMLINK escapes the lexical abs() can't see: a link inside the
|
|
17
|
+
* root pointing outside it. Resolve the real path (or nearest existing ancestor,
|
|
18
|
+
* for a not-yet-created write target) and assert it stays within the real root. */
|
|
19
|
+
private assertReal;
|
|
20
|
+
/** abs() + symlink-escape check — for any op that reads or writes file content. */
|
|
21
|
+
private realAbs;
|
|
22
|
+
list(dir?: string): Promise<FileNode[]>;
|
|
23
|
+
read(path: string): Promise<string>;
|
|
24
|
+
stat(path: string): Promise<FileStat | null>;
|
|
25
|
+
write(path: string, content: string): Promise<void>;
|
|
26
|
+
create(path: string, content?: string): Promise<void>;
|
|
27
|
+
remove(path: string): Promise<void>;
|
|
28
|
+
rename(from: string, to: string): Promise<void>;
|
|
29
|
+
mkdir(path: string): Promise<void>;
|
|
30
|
+
search(query: string): Promise<string[]>;
|
|
31
|
+
onChange(): () => void;
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=fileService.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fileService.d.ts","sourceRoot":"","sources":["../fileService.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,WAAW,EAAE,QAAQ,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAM1F,qBAAa,eAAgB,YAAW,WAAW;IACjD,QAAQ,CAAC,IAAI,EAAE,eAAe,CAAe;IAC7C,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,WAAW,QAAQ;IAC5B,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC3B,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAS;gBAElB,IAAI,EAAE,MAAM,EAAE,IAAI,GAAE;QAAE,QAAQ,CAAC,EAAE,OAAO,CAAA;KAAO;IAM3D,yEAAyE;IACzE,OAAO,CAAC,MAAM;IAKd;sFACkF;IAClF,OAAO,CAAC,GAAG;IAMX;;uFAEmF;YACrE,UAAU;IAoBxB,mFAAmF;YACrE,OAAO;IAMf,IAAI,CAAC,GAAG,SAAK,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC;IAqBnC,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAInC,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC;IAS5C,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAOnD,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,SAAK,GAAG,OAAO,CAAC,IAAI,CAAC;IAYjD,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAInC,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAO/C,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIlC,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAU9C,QAAQ,IAAI,MAAM,IAAI;CAGvB"}
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
/* A disk-backed FileService (the node twin of the browser's MemoryFileService /
|
|
2
|
+
* DirectoryHandleFileService). Implements the @corenel/protocol FileService port
|
|
3
|
+
* over node:fs, confined to a root — so the harness file tools and the node
|
|
4
|
+
* PromptHost workspace work in node, with no path escaping the root. Paths are
|
|
5
|
+
* POSIX, folder-relative (no leading slash). */
|
|
6
|
+
import { promises as fs } from 'node:fs';
|
|
7
|
+
import { join, resolve, relative, dirname, sep, basename } from 'node:path';
|
|
8
|
+
import { normalizeFilePath, extOf, flattenFiles } from '@corenel/protocol';
|
|
9
|
+
/** Dirs skipped from listing/search (caches, VCS, build output). */
|
|
10
|
+
const SKIP = new Set(['node_modules', '.git', 'dist', 'build', '.next', '.cache', '.turbo']);
|
|
11
|
+
export class NodeFileService {
|
|
12
|
+
constructor(root, opts = {}) {
|
|
13
|
+
Object.defineProperty(this, "kind", {
|
|
14
|
+
enumerable: true,
|
|
15
|
+
configurable: true,
|
|
16
|
+
writable: true,
|
|
17
|
+
value: 'directory'
|
|
18
|
+
});
|
|
19
|
+
Object.defineProperty(this, "label", {
|
|
20
|
+
enumerable: true,
|
|
21
|
+
configurable: true,
|
|
22
|
+
writable: true,
|
|
23
|
+
value: void 0
|
|
24
|
+
});
|
|
25
|
+
Object.defineProperty(this, "isLocalDisk", {
|
|
26
|
+
enumerable: true,
|
|
27
|
+
configurable: true,
|
|
28
|
+
writable: true,
|
|
29
|
+
value: true
|
|
30
|
+
});
|
|
31
|
+
Object.defineProperty(this, "writable", {
|
|
32
|
+
enumerable: true,
|
|
33
|
+
configurable: true,
|
|
34
|
+
writable: true,
|
|
35
|
+
value: void 0
|
|
36
|
+
});
|
|
37
|
+
Object.defineProperty(this, "root", {
|
|
38
|
+
enumerable: true,
|
|
39
|
+
configurable: true,
|
|
40
|
+
writable: true,
|
|
41
|
+
value: void 0
|
|
42
|
+
});
|
|
43
|
+
this.root = resolve(root);
|
|
44
|
+
this.label = basename(this.root) || this.root;
|
|
45
|
+
this.writable = opts.writable ?? true;
|
|
46
|
+
}
|
|
47
|
+
/** True if `a` is lexically within the root (the root itself counts). */
|
|
48
|
+
within(a) {
|
|
49
|
+
const rel = relative(this.root, a);
|
|
50
|
+
return rel === '' || (rel !== '..' && !rel.startsWith('..' + sep) && rel.split(sep)[0] !== '..');
|
|
51
|
+
}
|
|
52
|
+
/** Absolute path for a folder-relative one, rejecting anything that escapes root
|
|
53
|
+
* LEXICALLY (../, absolute). Symlink escapes are caught by assertReal/realAbs. */
|
|
54
|
+
abs(p) {
|
|
55
|
+
const a = resolve(this.root, normalizeFilePath(p));
|
|
56
|
+
if (!this.within(a))
|
|
57
|
+
throw new Error(`path escapes the workspace root: ${p}`);
|
|
58
|
+
return a;
|
|
59
|
+
}
|
|
60
|
+
/** Defense against SYMLINK escapes the lexical abs() can't see: a link inside the
|
|
61
|
+
* root pointing outside it. Resolve the real path (or nearest existing ancestor,
|
|
62
|
+
* for a not-yet-created write target) and assert it stays within the real root. */
|
|
63
|
+
async assertReal(a) {
|
|
64
|
+
const realRoot = await fs.realpath(this.root);
|
|
65
|
+
let probe = a;
|
|
66
|
+
for (;;) {
|
|
67
|
+
try {
|
|
68
|
+
const real = await fs.realpath(probe);
|
|
69
|
+
const rel = relative(realRoot, real);
|
|
70
|
+
if (rel !== '' && (rel === '..' || rel.startsWith('..' + sep) || rel.split(sep)[0] === '..')) {
|
|
71
|
+
throw new Error(`path escapes the workspace root via symlink: ${a}`);
|
|
72
|
+
}
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
catch (e) {
|
|
76
|
+
if (e instanceof Error && e.message.includes('via symlink'))
|
|
77
|
+
throw e;
|
|
78
|
+
const parent = dirname(probe);
|
|
79
|
+
if (parent === probe)
|
|
80
|
+
throw new Error(`cannot resolve path under the workspace root: ${a}`);
|
|
81
|
+
probe = parent;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
/** abs() + symlink-escape check — for any op that reads or writes file content. */
|
|
86
|
+
async realAbs(p) {
|
|
87
|
+
const a = this.abs(p);
|
|
88
|
+
await this.assertReal(a);
|
|
89
|
+
return a;
|
|
90
|
+
}
|
|
91
|
+
async list(dir = '') {
|
|
92
|
+
const walk = async (absDir) => {
|
|
93
|
+
let entries;
|
|
94
|
+
try {
|
|
95
|
+
entries = await fs.readdir(absDir, { withFileTypes: true });
|
|
96
|
+
}
|
|
97
|
+
catch {
|
|
98
|
+
return [];
|
|
99
|
+
}
|
|
100
|
+
const out = [];
|
|
101
|
+
for (const e of entries.sort((a, b) => a.name.localeCompare(b.name))) {
|
|
102
|
+
if (SKIP.has(e.name))
|
|
103
|
+
continue;
|
|
104
|
+
const absChild = join(absDir, e.name);
|
|
105
|
+
const path = normalizeFilePath(relative(this.root, absChild));
|
|
106
|
+
if (e.isDirectory()) {
|
|
107
|
+
out.push({ name: e.name, path, kind: 'directory', children: await walk(absChild) });
|
|
108
|
+
}
|
|
109
|
+
else {
|
|
110
|
+
const st = await fs.stat(absChild).catch(() => null);
|
|
111
|
+
out.push({ name: e.name, path, kind: 'file', size: st?.size, ext: extOf(e.name) });
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
return out;
|
|
115
|
+
};
|
|
116
|
+
return walk(this.abs(dir));
|
|
117
|
+
}
|
|
118
|
+
async read(path) {
|
|
119
|
+
return fs.readFile(await this.realAbs(path), 'utf8');
|
|
120
|
+
}
|
|
121
|
+
async stat(path) {
|
|
122
|
+
try {
|
|
123
|
+
const st = await fs.stat(this.abs(path));
|
|
124
|
+
return { path: normalizeFilePath(path), kind: st.isDirectory() ? 'directory' : 'file', size: st.size, ext: extOf(path) };
|
|
125
|
+
}
|
|
126
|
+
catch {
|
|
127
|
+
return null;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
async write(path, content) {
|
|
131
|
+
const a = this.abs(path);
|
|
132
|
+
await fs.mkdir(dirname(a), { recursive: true });
|
|
133
|
+
await this.assertReal(a);
|
|
134
|
+
await fs.writeFile(a, content, 'utf8');
|
|
135
|
+
}
|
|
136
|
+
async create(path, content = '') {
|
|
137
|
+
const a = this.abs(path);
|
|
138
|
+
await fs.mkdir(dirname(a), { recursive: true });
|
|
139
|
+
await this.assertReal(a);
|
|
140
|
+
try {
|
|
141
|
+
await fs.writeFile(a, content, { flag: 'wx' }); // wx => fail if it exists
|
|
142
|
+
}
|
|
143
|
+
catch (e) {
|
|
144
|
+
if (e.code === 'EEXIST')
|
|
145
|
+
throw new Error(`already exists: ${path}`);
|
|
146
|
+
throw e;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
async remove(path) {
|
|
150
|
+
await fs.rm(await this.realAbs(path), { recursive: true, force: true });
|
|
151
|
+
}
|
|
152
|
+
async rename(from, to) {
|
|
153
|
+
const t = this.abs(to);
|
|
154
|
+
await fs.mkdir(dirname(t), { recursive: true });
|
|
155
|
+
await this.assertReal(t);
|
|
156
|
+
await fs.rename(await this.realAbs(from), t);
|
|
157
|
+
}
|
|
158
|
+
async mkdir(path) {
|
|
159
|
+
await fs.mkdir(this.abs(path), { recursive: true });
|
|
160
|
+
}
|
|
161
|
+
async search(query) {
|
|
162
|
+
const q = query.toLowerCase();
|
|
163
|
+
const out = [];
|
|
164
|
+
for (const f of flattenFiles(await this.list())) {
|
|
165
|
+
if (f.name.toLowerCase().includes(q)) {
|
|
166
|
+
out.push(f.path);
|
|
167
|
+
continue;
|
|
168
|
+
}
|
|
169
|
+
try {
|
|
170
|
+
if ((await this.read(f.path)).toLowerCase().includes(q))
|
|
171
|
+
out.push(f.path);
|
|
172
|
+
}
|
|
173
|
+
catch { /* binary/unreadable */ }
|
|
174
|
+
}
|
|
175
|
+
return out;
|
|
176
|
+
}
|
|
177
|
+
onChange() {
|
|
178
|
+
return () => { }; // a real impl could fs.watch; the CLI doesn't need live refresh
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
//# sourceMappingURL=fileService.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fileService.js","sourceRoot":"","sources":["../fileService.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EACL,UAAU,EAAE,aAAa,EAAE,cAAc,EAAE,aAAa,EAAE,cAAc,EAAE,aAAa,GACxF,MAAM,QAAQ,CAAC;AAChB,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
/* @corenel/tools-node — node capabilities (the tools-web twin). */
|
|
2
|
+
export { NodeFileService } from './fileService';
|
|
3
|
+
export { corenelDir, authTokenPath, writeAuthToken, readAuthToken, clearAuthToken, nodeAuthToken, } from './auth';
|
|
4
|
+
export { nodePromptHost } from './promptHost';
|
|
5
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA,mEAAmE;AACnE,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EACL,UAAU,EAAE,aAAa,EAAE,cAAc,EAAE,aAAa,EAAE,cAAc,EAAE,aAAa,GACxF,MAAM,QAAQ,CAAC;AAChB,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { FileService } from '@corenel/protocol';
|
|
2
|
+
import type { PromptHost } from '@corenel/harness/prompts/host';
|
|
3
|
+
/** A node PromptHost over a FileService workspace. setPromptHost(nodePromptHost(ws))
|
|
4
|
+
* then makes the harness prompt subsystem (composeAgentSystem) run in node. */
|
|
5
|
+
export declare function nodePromptHost(workspace: FileService): PromptHost;
|
|
6
|
+
//# sourceMappingURL=promptHost.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"promptHost.d.ts","sourceRoot":"","sources":["../promptHost.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAErD,OAAO,KAAK,EAAE,UAAU,EAAiB,MAAM,+BAA+B,CAAC;AAuC/E;+EAC+E;AAC/E,wBAAgB,cAAc,CAAC,SAAS,EAAE,WAAW,GAAG,UAAU,CAkBjE"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/* A node PromptHost — the node impl of @corenel/harness's prompt-subsystem port,
|
|
2
|
+
* so composeAgentSystem (the @prompd/core system-prompt INHERITANCE) RUNS in node.
|
|
3
|
+
* The browser host (src/prompd/promptHost) uses the app's lib/compile + a browser
|
|
4
|
+
* FileService; this uses @prompd/core directly over a node FileService (disk via
|
|
5
|
+
* NodeFileService, or ~/.corenel/config). corenel/prompts owns the composition
|
|
6
|
+
* logic; this provides where the files live and how they compile. */
|
|
7
|
+
import { PrompdParser, PrompdCompiler, MemoryFileSystem, HybridFileSystem } from '@prompd/core';
|
|
8
|
+
import { normalizeFilePath, flattenFiles } from '@corenel/protocol';
|
|
9
|
+
const parser = new PrompdParser();
|
|
10
|
+
const compiler = new PrompdCompiler();
|
|
11
|
+
/** Stream non-source files (context assets) to the compiler from a FileService. */
|
|
12
|
+
function backend(svc) {
|
|
13
|
+
return {
|
|
14
|
+
async readFile(p) {
|
|
15
|
+
try {
|
|
16
|
+
return await svc.read(normalizeFilePath(p));
|
|
17
|
+
}
|
|
18
|
+
catch {
|
|
19
|
+
return null;
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
async isDirectory(p) {
|
|
23
|
+
return (await svc.stat(normalizeFilePath(p)))?.kind === 'directory';
|
|
24
|
+
},
|
|
25
|
+
async readdir(p) {
|
|
26
|
+
return (await svc.list(normalizeFilePath(p))).map((n) => n.name);
|
|
27
|
+
},
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
/** Pre-load every .prmd/.md source so the synchronous Nunjucks {% include %}
|
|
31
|
+
* loader can resolve inherits against siblings. */
|
|
32
|
+
async function preload(svc) {
|
|
33
|
+
const out = {};
|
|
34
|
+
for (const f of flattenFiles(await svc.list())) {
|
|
35
|
+
try {
|
|
36
|
+
out[f.path] = await svc.read(f.path);
|
|
37
|
+
}
|
|
38
|
+
catch { /* skip unreadable */ }
|
|
39
|
+
}
|
|
40
|
+
return out;
|
|
41
|
+
}
|
|
42
|
+
async function compile(src, values, fileSystem, mainPath) {
|
|
43
|
+
const mp = mainPath || '/main.prmd';
|
|
44
|
+
const fs = fileSystem || new MemoryFileSystem({ [mp]: src });
|
|
45
|
+
const ctx = await compiler.compileWithContext(mp, { parameters: values || {}, fileSystem: fs, outputFormat: 'markdown' });
|
|
46
|
+
const compiled = ctx.compiledResult;
|
|
47
|
+
const output = typeof compiled === 'string' ? compiled : compiled ? new TextDecoder().decode(compiled) : '';
|
|
48
|
+
return { output };
|
|
49
|
+
}
|
|
50
|
+
/** A node PromptHost over a FileService workspace. setPromptHost(nodePromptHost(ws))
|
|
51
|
+
* then makes the harness prompt subsystem (composeAgentSystem) run in node. */
|
|
52
|
+
export function nodePromptHost(workspace) {
|
|
53
|
+
return {
|
|
54
|
+
workspace,
|
|
55
|
+
seed: async (defaults) => {
|
|
56
|
+
for (const [p, content] of Object.entries(defaults)) {
|
|
57
|
+
if (!(await workspace.stat(p)))
|
|
58
|
+
await workspace.write(p, content);
|
|
59
|
+
}
|
|
60
|
+
},
|
|
61
|
+
parse: (source) => ({ meta: (parser.parseContent(source).metadata ?? {}) }),
|
|
62
|
+
compileBody: (source, values) => compile(source, values),
|
|
63
|
+
compileTemplate: async (path, liveSrc, values) => {
|
|
64
|
+
const sources = await preload(workspace);
|
|
65
|
+
const p = normalizeFilePath(path);
|
|
66
|
+
sources[p] = liveSrc; // the (possibly default-fallback) template content
|
|
67
|
+
return compile('', values, new HybridFileSystem(sources, backend(workspace)), '/' + p);
|
|
68
|
+
},
|
|
69
|
+
siteIndex: () => '', // no site index in node (the help chat is browser-only)
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
//# sourceMappingURL=promptHost.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"promptHost.js","sourceRoot":"","sources":["../promptHost.ts"],"names":[],"mappings":"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"}
|
package/dist/verify.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verify.d.ts","sourceRoot":"","sources":["../verify.ts"],"names":[],"mappings":""}
|
package/dist/verify.js
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/* Headless proof of the node FileService: real fs ops on a temp dir + path
|
|
2
|
+
* confinement. Run: pnpm verify. */
|
|
3
|
+
import { promises as fs } from 'node:fs';
|
|
4
|
+
import { tmpdir } from 'node:os';
|
|
5
|
+
import { join } from 'node:path';
|
|
6
|
+
import { NodeFileService } from './fileService';
|
|
7
|
+
import { nodePromptHost } from './promptHost';
|
|
8
|
+
import { setPromptHost } from '@corenel/harness/prompts/host';
|
|
9
|
+
import { composeAgentSystem } from '@corenel/harness/prompts';
|
|
10
|
+
function assert(cond, msg) {
|
|
11
|
+
if (!cond)
|
|
12
|
+
throw new Error(`FAIL: ${msg}`);
|
|
13
|
+
process.stdout.write(` ok: ${msg}\n`);
|
|
14
|
+
}
|
|
15
|
+
async function main() {
|
|
16
|
+
const root = await fs.mkdtemp(join(tmpdir(), 'corenel-tn-'));
|
|
17
|
+
const svc = new NodeFileService(root);
|
|
18
|
+
await svc.write('a/b/note.md', '# hello');
|
|
19
|
+
assert((await svc.read('a/b/note.md')) === '# hello', 'write + read a nested file');
|
|
20
|
+
const st = await svc.stat('a/b/note.md');
|
|
21
|
+
assert(st?.kind === 'file' && st.ext === 'md' && st.size === 7, 'stat reports kind/ext/size');
|
|
22
|
+
assert((await svc.stat('nope.txt')) === null, 'stat of a missing path is null');
|
|
23
|
+
const tree = await svc.list();
|
|
24
|
+
assert(tree.some((n) => n.name === 'a' && n.kind === 'directory'), 'list returns the dir tree');
|
|
25
|
+
await svc.create('fresh.txt', 'x');
|
|
26
|
+
let dup = false;
|
|
27
|
+
try {
|
|
28
|
+
await svc.create('fresh.txt', 'y');
|
|
29
|
+
}
|
|
30
|
+
catch {
|
|
31
|
+
dup = true;
|
|
32
|
+
}
|
|
33
|
+
assert(dup, 'create rejects an existing file');
|
|
34
|
+
await svc.rename('fresh.txt', 'renamed.txt');
|
|
35
|
+
assert((await svc.read('renamed.txt')) === 'x', 'rename moves the file');
|
|
36
|
+
await svc.write('haystack.txt', 'find the needle here');
|
|
37
|
+
assert((await svc.search('needle')).includes('haystack.txt'), 'search matches file contents');
|
|
38
|
+
await svc.remove('a');
|
|
39
|
+
assert((await svc.stat('a/b/note.md')) === null, 'remove deletes recursively');
|
|
40
|
+
let escaped = false;
|
|
41
|
+
try {
|
|
42
|
+
await svc.read('../../../../etc/passwd');
|
|
43
|
+
}
|
|
44
|
+
catch {
|
|
45
|
+
escaped = true;
|
|
46
|
+
}
|
|
47
|
+
assert(escaped, 'path traversal outside the root is refused');
|
|
48
|
+
await fs.rm(root, { recursive: true, force: true });
|
|
49
|
+
// Node PromptHost: compose the agent system prompt IN NODE (@prompd/core
|
|
50
|
+
// system-prompt inheritance), over a disk-backed config workspace.
|
|
51
|
+
const cfgDir = await fs.mkdtemp(join(tmpdir(), 'corenel-cfg-'));
|
|
52
|
+
const ws = new NodeFileService(cfgDir);
|
|
53
|
+
setPromptHost(nodePromptHost(ws));
|
|
54
|
+
const system = await composeAgentSystem({ mode: 'auto' });
|
|
55
|
+
assert(typeof system === 'string' && system.trim().length > 50, 'composeAgentSystem produced a system prompt in node');
|
|
56
|
+
assert((await ws.stat('systems/system-base.md')) !== null, 'the prompt subsystem seeded the config defaults to the node workspace');
|
|
57
|
+
await fs.rm(cfgDir, { recursive: true, force: true });
|
|
58
|
+
process.stdout.write('\nNODE FILESERVICE + PROMPT HOST OK\n');
|
|
59
|
+
}
|
|
60
|
+
main().catch((e) => { process.stderr.write(`\n${e instanceof Error ? e.message : String(e)}\n`); process.exit(1); });
|
|
61
|
+
//# sourceMappingURL=verify.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verify.js","sourceRoot":"","sources":["../verify.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@corenel/tools-node",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"description": "Corenel node capabilities — the tools-web twin. A disk-backed FileService (the harness file tools + node PromptHost workspace) over node:fs, confined to a root. Shell/secrets/~/.corenel to follow.",
|
|
6
|
+
"exports": {
|
|
7
|
+
".": "./index.ts",
|
|
8
|
+
"./*": "./*.ts"
|
|
9
|
+
},
|
|
10
|
+
"scripts": {
|
|
11
|
+
"typecheck": "tsc --noEmit",
|
|
12
|
+
"verify": "tsx verify.ts",
|
|
13
|
+
"build": "tsc -p tsconfig.build.json",
|
|
14
|
+
"prepublishOnly": "tsc -p tsconfig.build.json"
|
|
15
|
+
},
|
|
16
|
+
"dependencies": {
|
|
17
|
+
"@corenel/protocol": "workspace:*",
|
|
18
|
+
"@corenel/harness": "workspace:*",
|
|
19
|
+
"@prompd/core": "0.5.0-beta.10"
|
|
20
|
+
},
|
|
21
|
+
"devDependencies": {
|
|
22
|
+
"@types/node": "^24.13.1",
|
|
23
|
+
"tsx": "^4.19.2",
|
|
24
|
+
"typescript": "^5.9.3"
|
|
25
|
+
},
|
|
26
|
+
"publishConfig": {
|
|
27
|
+
"access": "public",
|
|
28
|
+
"exports": {
|
|
29
|
+
".": {
|
|
30
|
+
"types": "./dist/index.d.ts",
|
|
31
|
+
"default": "./dist/index.js"
|
|
32
|
+
},
|
|
33
|
+
"./*": {
|
|
34
|
+
"types": "./dist/*.d.ts",
|
|
35
|
+
"default": "./dist/*.js"
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
},
|
|
39
|
+
"files": [
|
|
40
|
+
"dist"
|
|
41
|
+
]
|
|
42
|
+
}
|