@owlmeans/viable-sdk 0.1.18-rc.1
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/README.md +128 -0
- package/build/api/index.d.ts +2 -0
- package/build/api/index.d.ts.map +1 -0
- package/build/api/index.js +2 -0
- package/build/api/index.js.map +1 -0
- package/build/api/remote.d.ts +14 -0
- package/build/api/remote.d.ts.map +1 -0
- package/build/api/remote.js +123 -0
- package/build/api/remote.js.map +1 -0
- package/build/consts.d.ts +47 -0
- package/build/consts.d.ts.map +1 -0
- package/build/consts.js +47 -0
- package/build/consts.js.map +1 -0
- package/build/context/index.d.ts +22 -0
- package/build/context/index.d.ts.map +1 -0
- package/build/context/index.js +92 -0
- package/build/context/index.js.map +1 -0
- package/build/errors.d.ts +21 -0
- package/build/errors.d.ts.map +1 -0
- package/build/errors.js +36 -0
- package/build/errors.js.map +1 -0
- package/build/executor/boot-check.d.ts +73 -0
- package/build/executor/boot-check.d.ts.map +1 -0
- package/build/executor/boot-check.js +155 -0
- package/build/executor/boot-check.js.map +1 -0
- package/build/executor/env.d.ts +25 -0
- package/build/executor/env.d.ts.map +1 -0
- package/build/executor/env.js +77 -0
- package/build/executor/env.js.map +1 -0
- package/build/executor/errors.d.ts +69 -0
- package/build/executor/errors.d.ts.map +1 -0
- package/build/executor/errors.js +80 -0
- package/build/executor/errors.js.map +1 -0
- package/build/executor/files.d.ts +124 -0
- package/build/executor/files.d.ts.map +1 -0
- package/build/executor/files.js +529 -0
- package/build/executor/files.js.map +1 -0
- package/build/executor/git.d.ts +52 -0
- package/build/executor/git.d.ts.map +1 -0
- package/build/executor/git.js +353 -0
- package/build/executor/git.js.map +1 -0
- package/build/executor/health.d.ts +92 -0
- package/build/executor/health.d.ts.map +1 -0
- package/build/executor/health.js +98 -0
- package/build/executor/health.js.map +1 -0
- package/build/executor/index.d.ts +39 -0
- package/build/executor/index.d.ts.map +1 -0
- package/build/executor/index.js +173 -0
- package/build/executor/index.js.map +1 -0
- package/build/executor/integrity.d.ts +17 -0
- package/build/executor/integrity.d.ts.map +1 -0
- package/build/executor/integrity.js +59 -0
- package/build/executor/integrity.js.map +1 -0
- package/build/executor/layout.d.ts +61 -0
- package/build/executor/layout.d.ts.map +1 -0
- package/build/executor/layout.js +98 -0
- package/build/executor/layout.js.map +1 -0
- package/build/executor/shell.d.ts +89 -0
- package/build/executor/shell.d.ts.map +1 -0
- package/build/executor/shell.js +280 -0
- package/build/executor/shell.js.map +1 -0
- package/build/executor/spawn.d.ts +111 -0
- package/build/executor/spawn.d.ts.map +1 -0
- package/build/executor/spawn.js +314 -0
- package/build/executor/spawn.js.map +1 -0
- package/build/harness/index.d.ts +28 -0
- package/build/harness/index.d.ts.map +1 -0
- package/build/harness/index.js +83 -0
- package/build/harness/index.js.map +1 -0
- package/build/harness/templates.d.ts +30 -0
- package/build/harness/templates.d.ts.map +1 -0
- package/build/harness/templates.js +162 -0
- package/build/harness/templates.js.map +1 -0
- package/build/index.d.ts +13 -0
- package/build/index.d.ts.map +1 -0
- package/build/index.js +12 -0
- package/build/index.js.map +1 -0
- package/build/project/env.d.ts +108 -0
- package/build/project/env.d.ts.map +1 -0
- package/build/project/env.js +233 -0
- package/build/project/env.js.map +1 -0
- package/build/project/marker.d.ts +34 -0
- package/build/project/marker.d.ts.map +1 -0
- package/build/project/marker.js +54 -0
- package/build/project/marker.js.map +1 -0
- package/build/project/setup.d.ts +62 -0
- package/build/project/setup.d.ts.map +1 -0
- package/build/project/setup.js +190 -0
- package/build/project/setup.js.map +1 -0
- package/build/run/index.d.ts +75 -0
- package/build/run/index.d.ts.map +1 -0
- package/build/run/index.js +150 -0
- package/build/run/index.js.map +1 -0
- package/build/run/serve.d.ts +18 -0
- package/build/run/serve.d.ts.map +1 -0
- package/build/run/serve.js +148 -0
- package/build/run/serve.js.map +1 -0
- package/build/run/state.d.ts +75 -0
- package/build/run/state.d.ts.map +1 -0
- package/build/run/state.js +136 -0
- package/build/run/state.js.map +1 -0
- package/build/session/index.d.ts +17 -0
- package/build/session/index.d.ts.map +1 -0
- package/build/session/index.js +226 -0
- package/build/session/index.js.map +1 -0
- package/build/session/questions.d.ts +16 -0
- package/build/session/questions.d.ts.map +1 -0
- package/build/session/questions.js +17 -0
- package/build/session/questions.js.map +1 -0
- package/build/session/queue.d.ts +54 -0
- package/build/session/queue.d.ts.map +1 -0
- package/build/session/queue.js +102 -0
- package/build/session/queue.js.map +1 -0
- package/build/session/tasks.d.ts +15 -0
- package/build/session/tasks.d.ts.map +1 -0
- package/build/session/tasks.js +16 -0
- package/build/session/tasks.js.map +1 -0
- package/build/task/driver.d.ts +30 -0
- package/build/task/driver.d.ts.map +1 -0
- package/build/task/driver.js +120 -0
- package/build/task/driver.js.map +1 -0
- package/build/task/envelope.d.ts +35 -0
- package/build/task/envelope.d.ts.map +1 -0
- package/build/task/envelope.js +230 -0
- package/build/task/envelope.js.map +1 -0
- package/build/task/index.d.ts +4 -0
- package/build/task/index.d.ts.map +1 -0
- package/build/task/index.js +4 -0
- package/build/task/index.js.map +1 -0
- package/build/task/inquiry.d.ts +53 -0
- package/build/task/inquiry.d.ts.map +1 -0
- package/build/task/inquiry.js +232 -0
- package/build/task/inquiry.js.map +1 -0
- package/build/tools/catalogue.d.ts +17 -0
- package/build/tools/catalogue.d.ts.map +1 -0
- package/build/tools/catalogue.js +1169 -0
- package/build/tools/catalogue.js.map +1 -0
- package/build/tools/index.d.ts +7 -0
- package/build/tools/index.d.ts.map +1 -0
- package/build/tools/index.js +7 -0
- package/build/tools/index.js.map +1 -0
- package/build/tools/jobs.d.ts +12 -0
- package/build/tools/jobs.d.ts.map +1 -0
- package/build/tools/jobs.js +60 -0
- package/build/tools/jobs.js.map +1 -0
- package/build/tools/mcp.d.ts +43 -0
- package/build/tools/mcp.d.ts.map +1 -0
- package/build/tools/mcp.js +131 -0
- package/build/tools/mcp.js.map +1 -0
- package/build/tools/platform.d.ts +77 -0
- package/build/tools/platform.d.ts.map +1 -0
- package/build/tools/platform.js +316 -0
- package/build/tools/platform.js.map +1 -0
- package/build/tools/refusal.d.ts +66 -0
- package/build/tools/refusal.d.ts.map +1 -0
- package/build/tools/refusal.js +377 -0
- package/build/tools/refusal.js.map +1 -0
- package/build/tools/types.d.ts +83 -0
- package/build/tools/types.d.ts.map +1 -0
- package/build/tools/types.js +38 -0
- package/build/tools/types.js.map +1 -0
- package/build/types.d.ts +174 -0
- package/build/types.d.ts.map +1 -0
- package/build/types.js +2 -0
- package/build/types.js.map +1 -0
- package/package.json +105 -0
|
@@ -0,0 +1,529 @@
|
|
|
1
|
+
import fs from 'fs-extra';
|
|
2
|
+
import { globby } from 'globby';
|
|
3
|
+
import fsp from 'node:fs/promises';
|
|
4
|
+
import p from 'node:path';
|
|
5
|
+
import { binaryByExtension, BINARY_PROBE_BYTES, CENSUS_MAX_ENTRIES, CENSUS_MAX_HEAD_BYTES, CENSUS_SKIP_DIRS, CONNECT_MARKER_DIR, METADATA_SUFFIXES, SOURCE_LIST_EXCLUSIONS, SubProject } from '@owlmeans/viable-common';
|
|
6
|
+
import { FileCommandRefused, SandboxPathError } from './errors.js';
|
|
7
|
+
import { subprojectDir, targetPaths } from './layout.js';
|
|
8
|
+
/**
|
|
9
|
+
* What a tree walk never descends into.
|
|
10
|
+
*
|
|
11
|
+
* {@link CENSUS_SKIP_DIRS} is the shared half — the two directories that are never the repository
|
|
12
|
+
* in any tree, spread from `@owlmeans/viable-common` rather than restated, because the publisher
|
|
13
|
+
* and the library-local helper walk the SAME question and a caller cannot tell which executor
|
|
14
|
+
* produced the listing it is holding. This one used to add `dist`, `build` and `.next` on top,
|
|
15
|
+
* which are ordinary directory names an origin may keep sources in: the same repository then had
|
|
16
|
+
* one `total` here and another one in the slot.
|
|
17
|
+
*
|
|
18
|
+
* {@link CONNECT_MARKER_DIR} is added for a reason that belongs to this executor alone: it is THIS
|
|
19
|
+
* CONNECTOR's directory, not the origin's. It holds the local key pair and the run record and
|
|
20
|
+
* never a line of the application, while a census exists to be followed by a `readHead` of what it
|
|
21
|
+
* listed — and nothing downstream knows which of the two wrote a path.
|
|
22
|
+
*/
|
|
23
|
+
const WALK_SKIP = new Set([...CENSUS_SKIP_DIRS, CONNECT_MARKER_DIR]);
|
|
24
|
+
/**
|
|
25
|
+
* Whether a file is binary, by git's own heuristic: a NUL byte near the beginning.
|
|
26
|
+
*
|
|
27
|
+
* Asked only where {@link binaryByExtension} says nothing, and that ordering is the contract
|
|
28
|
+
* rather than an optimization: a probe alone answers `false` for a small `.ico` with no NUL in its
|
|
29
|
+
* first bytes, so a census run here and the same census run in the slot disagreed about one file
|
|
30
|
+
* of one repository — with the tail table consulted first, all three executors agree.
|
|
31
|
+
*/
|
|
32
|
+
const isBinary = async (path, size) => {
|
|
33
|
+
if (size < 1)
|
|
34
|
+
return false;
|
|
35
|
+
const handle = await fsp.open(path, 'r').catch(() => null);
|
|
36
|
+
if (handle == null)
|
|
37
|
+
return false;
|
|
38
|
+
try {
|
|
39
|
+
const length = Math.min(size, BINARY_PROBE_BYTES);
|
|
40
|
+
const buffer = Buffer.alloc(length);
|
|
41
|
+
const { bytesRead } = await handle.read(buffer, 0, length, 0);
|
|
42
|
+
return buffer.subarray(0, bytesRead).includes(0);
|
|
43
|
+
}
|
|
44
|
+
catch {
|
|
45
|
+
return false;
|
|
46
|
+
}
|
|
47
|
+
finally {
|
|
48
|
+
await handle.close();
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
/**
|
|
52
|
+
* The target's files, as the platform asks for them.
|
|
53
|
+
*
|
|
54
|
+
* Shaped exactly like the publisher's `createFileHelper`, because the caller is the same code:
|
|
55
|
+
* the agent's remote helper sends a `SlotFileCommand` and parses one of these answers, and it has
|
|
56
|
+
* no way to know whether a pod or a laptop produced it.
|
|
57
|
+
*/
|
|
58
|
+
export const createLocalFileHelper = (projectPath) => {
|
|
59
|
+
const rootPath = wrapWithSlashes(p.resolve(projectPath));
|
|
60
|
+
// Every path below asks the tree which layout it holds, per call, rather than closing over one
|
|
61
|
+
// answer: a project is re-initialized in place, and this helper outlives that. `packages/` for
|
|
62
|
+
// a target generated before the move, `sources/` for one generated after it.
|
|
63
|
+
const layout = () => targetPaths(rootPath);
|
|
64
|
+
const dirOf = (role) => subprojectDir(rootPath, role);
|
|
65
|
+
/**
|
|
66
|
+
* What a wipe must never take, whatever the caller asked to keep.
|
|
67
|
+
*
|
|
68
|
+
* The publisher empties a volume the platform owns; this empties a directory the DEVELOPER
|
|
69
|
+
* owns, and four things in it were never the platform's to delete. `.viable/` is how a later
|
|
70
|
+
* session recognizes the project at all (and holds the local keypair and the run record);
|
|
71
|
+
* `.env` and the web's `.env` carry the database URL and the identity the user typed, which
|
|
72
|
+
* the platform cannot re-derive because it provisions nothing on a developer's machine; and
|
|
73
|
+
* `.git` is their history. Losing any of them is a data loss no re-initialization is worth,
|
|
74
|
+
* so the list is added to the caller's rather than offered to it.
|
|
75
|
+
*
|
|
76
|
+
* DELIBERATE DIFFERENCE from the publisher: because this set is never empty, the
|
|
77
|
+
* `fs.emptyDir` fast path an absent `ignore` used to take can never be taken here. Every wipe
|
|
78
|
+
* walks and prunes.
|
|
79
|
+
*/
|
|
80
|
+
const alwaysKeep = () => [
|
|
81
|
+
CONNECT_MARKER_DIR,
|
|
82
|
+
'.env',
|
|
83
|
+
`${layout().dir}/${dirOf(SubProject.Web)}/.env`,
|
|
84
|
+
'.git',
|
|
85
|
+
];
|
|
86
|
+
/**
|
|
87
|
+
* The two questions a wipe and a relocation both ask of every entry they walk.
|
|
88
|
+
*
|
|
89
|
+
* Shared because they are the same walk with a different verb: one removes what it passes and
|
|
90
|
+
* the other moves it, and both must leave a nested keep — `.agents/memory/history.md`,
|
|
91
|
+
* `sources/web/.env` — where it is. Matching kept paths against top-level names alone is what
|
|
92
|
+
* once deleted a whole harness tree along with the one file the caller had asked to preserve.
|
|
93
|
+
*/
|
|
94
|
+
const keepGuards = (entries) => {
|
|
95
|
+
const keep = new Set(entries.map(entry => entry.replace(/^\.?\//, '').replace(/\/+$/, '')));
|
|
96
|
+
const holdsKept = (rel) => {
|
|
97
|
+
const prefix = `${rel}/`;
|
|
98
|
+
for (const entry of keep) {
|
|
99
|
+
if (entry.startsWith(prefix))
|
|
100
|
+
return true;
|
|
101
|
+
}
|
|
102
|
+
return false;
|
|
103
|
+
};
|
|
104
|
+
return { keep, isKept: (rel) => keep.has(rel), holdsKept };
|
|
105
|
+
};
|
|
106
|
+
const helper = {
|
|
107
|
+
/**
|
|
108
|
+
* Wipe the project, keeping what the caller names and what is never ours to delete.
|
|
109
|
+
*
|
|
110
|
+
* The kept paths are project-relative and may be NESTED — `.agents/memory/history.md` is one
|
|
111
|
+
* the reinit pipeline passes, and `sources/web/.env` is one this helper adds itself. Matching
|
|
112
|
+
* them against top-level `readdir` names alone is what deleted the first: `.agents` matched
|
|
113
|
+
* nothing in the ignore set, so the whole harness tree went along with the one file the
|
|
114
|
+
* caller had explicitly asked to preserve — and nothing failed.
|
|
115
|
+
*
|
|
116
|
+
* So a directory is removed whole only when nothing kept lives under it; otherwise it is
|
|
117
|
+
* walked and pruned entry by entry.
|
|
118
|
+
*/
|
|
119
|
+
emptyProject: async (ignore) => {
|
|
120
|
+
// `holdsKept` says something kept lives below here, so this directory has to be walked
|
|
121
|
+
// rather than removed.
|
|
122
|
+
const { isKept, holdsKept } = keepGuards([...(ignore ?? []), ...alwaysKeep()]);
|
|
123
|
+
const prune = async (rel) => {
|
|
124
|
+
const dir = rel === '' ? rootPath : p.join(rootPath, rel);
|
|
125
|
+
const entries = await fs.readdir(dir);
|
|
126
|
+
await Promise.all(entries.map(async (name) => {
|
|
127
|
+
const child = rel === '' ? name : `${rel}/${name}`;
|
|
128
|
+
if (isKept(child)) {
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
if (holdsKept(child)) {
|
|
132
|
+
await prune(child);
|
|
133
|
+
// The keep list names paths that need not exist — the web package's `.env` is one
|
|
134
|
+
// every project without local branding lacks. A directory walked only for a keep that
|
|
135
|
+
// was not there must not survive as an empty shell, or a wipe leaves a skeleton of
|
|
136
|
+
// the tree it removed and the install that follows lands in a half-populated one.
|
|
137
|
+
const remaining = await fs.readdir(p.join(rootPath, child));
|
|
138
|
+
if (remaining.length === 0) {
|
|
139
|
+
await fs.remove(p.join(rootPath, child));
|
|
140
|
+
}
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
await fs.remove(p.join(rootPath, child));
|
|
144
|
+
}));
|
|
145
|
+
};
|
|
146
|
+
await fs.ensureDir(rootPath);
|
|
147
|
+
await prune('');
|
|
148
|
+
},
|
|
149
|
+
deleteProject: async () => {
|
|
150
|
+
await helper.emptyProject();
|
|
151
|
+
},
|
|
152
|
+
/**
|
|
153
|
+
* Finish an installed template: make sure the root manifest declares its workspaces.
|
|
154
|
+
*
|
|
155
|
+
* The agent pushes every template file itself, so this is only the finalizer. The workspace
|
|
156
|
+
* list is written only when the manifest does not already declare one — the template ships
|
|
157
|
+
* `["sources/*"]`, and injecting the explicit list beside it produced a manifest carrying the
|
|
158
|
+
* key TWICE, valid only because JSON keeps the last one.
|
|
159
|
+
*/
|
|
160
|
+
initializeProject: async () => {
|
|
161
|
+
const manifestPath = `${rootPath}package.json`;
|
|
162
|
+
if (await fs.pathExists(manifestPath) === false) {
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
const file = await fs.readFile(manifestPath, 'utf-8');
|
|
166
|
+
if (/"workspaces"\s*:/.test(file)) {
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
const { dir, build } = layout();
|
|
170
|
+
const present = [];
|
|
171
|
+
for (const pkg of build) {
|
|
172
|
+
if (await fs.pathExists(`${rootPath}${p.join(dir, pkg, 'package.json')}`)) {
|
|
173
|
+
present.push(p.join(dir, pkg));
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
await fs.writeFile(manifestPath, file.replace(`"type": "module",`, `
|
|
177
|
+
"type": "module",
|
|
178
|
+
"workspaces": [
|
|
179
|
+
${present.map(path => ` "${path}"`).join(',\n')}
|
|
180
|
+
],
|
|
181
|
+
`));
|
|
182
|
+
},
|
|
183
|
+
getSourceList: async (pattern = `${rootPath}**/*`, options = {}) => {
|
|
184
|
+
const { skipUIElements = false, excludes = [] } = options;
|
|
185
|
+
pattern = pattern.startsWith(rootPath) ? pattern : p.join(rootPath, pattern);
|
|
186
|
+
const files = await globby([
|
|
187
|
+
pattern,
|
|
188
|
+
`!${rootPath}**/rollup.config.js`,
|
|
189
|
+
`!${rootPath}**/rollup.build.mjs`,
|
|
190
|
+
// bunfig.toml is pure infra (identical to the template); excluded so an LLM fixer cannot
|
|
191
|
+
// corrupt it with an invalid `[run] shell`, which breaks every `bun install`.
|
|
192
|
+
`!${rootPath}**/bunfig.toml`,
|
|
193
|
+
// Legacy drizzle-kit output. The target no longer emits it — tables come from the
|
|
194
|
+
// resources' AJV schemas — but a tree generated before that switch may still carry some,
|
|
195
|
+
// and it is not source an LLM should read or edit.
|
|
196
|
+
`!${rootPath}**/db/migrations/**`,
|
|
197
|
+
// Dependency lockfiles — generated, never hand-fixable, and huge: a target's `bun.lock`
|
|
198
|
+
// alone overflows a model's context window, and every retry then fails identically. The
|
|
199
|
+
// target installs with bun, but every manager's lockfile is listed — an LLM-authored
|
|
200
|
+
// `package.json` edit can switch the target's toolchain.
|
|
201
|
+
`!${rootPath}**/bun.lock`,
|
|
202
|
+
`!${rootPath}**/bun.lockb`,
|
|
203
|
+
`!${rootPath}**/yarn.lock`,
|
|
204
|
+
`!${rootPath}**/package-lock.json`,
|
|
205
|
+
`!${rootPath}**/pnpm-lock.yaml`,
|
|
206
|
+
`!${rootPath}**/dist/**/*`,
|
|
207
|
+
`!${rootPath}**/build/**/*`,
|
|
208
|
+
`!${rootPath}**/node_modules/**/*`,
|
|
209
|
+
`!${rootPath}spectator-log/**/*`,
|
|
210
|
+
// The target's own documentation and agent harness, and the origin tree a conversion
|
|
211
|
+
// keeps beside the generated application — ONE constant, shared with the publisher and
|
|
212
|
+
// the library, because three copies of this list is three chances for one of them to
|
|
213
|
+
// keep listing the origin, and the symptom is a coder helper reading a foreign
|
|
214
|
+
// framework's files as if they were the target's. Plus the co-located metadata files
|
|
215
|
+
// (*.spec.md, *.ux.md, *.ui.md).
|
|
216
|
+
...SOURCE_LIST_EXCLUSIONS.map(dir => `!${rootPath}${dir}/**/*`),
|
|
217
|
+
...METADATA_SUFFIXES.map(suffix => `!${rootPath}**/*${suffix}`),
|
|
218
|
+
...excludes.map(exclude => `!${rootPath}${exclude}`),
|
|
219
|
+
...(skipUIElements
|
|
220
|
+
? [`!${rootPath}${layout().dir}/${dirOf(SubProject.Frontend)}/src/components/ui/**/*`]
|
|
221
|
+
: [])
|
|
222
|
+
]);
|
|
223
|
+
return files.map(file => cleanUpPath(file, { rootPath }));
|
|
224
|
+
},
|
|
225
|
+
getStructuredList: async (patterns) => {
|
|
226
|
+
const resolved = patterns.map(pattern => pattern.startsWith(rootPath) ? pattern : p.join(rootPath, pattern));
|
|
227
|
+
const files = await globby(resolved);
|
|
228
|
+
return files.map(file => cleanUpPath(file, { rootPath }));
|
|
229
|
+
},
|
|
230
|
+
readFile: async (path, notThrow = false) => {
|
|
231
|
+
try {
|
|
232
|
+
return await fs.readFile(resolveInProject(path, { rootPath }), 'utf-8');
|
|
233
|
+
}
|
|
234
|
+
catch (e) {
|
|
235
|
+
if (notThrow) {
|
|
236
|
+
return '';
|
|
237
|
+
}
|
|
238
|
+
throw e;
|
|
239
|
+
}
|
|
240
|
+
},
|
|
241
|
+
readSource: async (filePath) => {
|
|
242
|
+
const path = cleanUpPath(filePath, { rootPath });
|
|
243
|
+
const code = await fs.readFile(resolveInProject(path, { rootPath }), 'utf-8').catch(() => '');
|
|
244
|
+
return { path, code };
|
|
245
|
+
},
|
|
246
|
+
readPossibleSource: async (filePath) => {
|
|
247
|
+
const source = await fs.readFile(resolveInProject(filePath, { rootPath }), 'utf-8')
|
|
248
|
+
.catch(() => '');
|
|
249
|
+
const path = cleanUpPath(filePath, { rootPath });
|
|
250
|
+
return source === '' ? { path } : { path, code: source };
|
|
251
|
+
},
|
|
252
|
+
readSources: async (files) => {
|
|
253
|
+
const paths = normalizePaths(files, { rootPath });
|
|
254
|
+
const results = [];
|
|
255
|
+
for (const path of paths) {
|
|
256
|
+
const code = await fs.readFile(resolveInProject(path, { rootPath }), 'utf-8')
|
|
257
|
+
.catch(() => '');
|
|
258
|
+
results.push({ path, code });
|
|
259
|
+
}
|
|
260
|
+
return results;
|
|
261
|
+
},
|
|
262
|
+
writeFile: async (filePath, content) => {
|
|
263
|
+
const path = resolveInProject(filePath, { rootPath });
|
|
264
|
+
await fs.ensureDir(p.dirname(path));
|
|
265
|
+
await fs.writeFile(path, content);
|
|
266
|
+
},
|
|
267
|
+
writeSource: async (file) => {
|
|
268
|
+
const path = resolveInProject(file.path, { rootPath });
|
|
269
|
+
await fs.ensureDir(p.dirname(path));
|
|
270
|
+
await fs.writeFile(path, file.code);
|
|
271
|
+
},
|
|
272
|
+
deleteFile: async (filePath, noThrow = true) => {
|
|
273
|
+
const path = resolveInProject(filePath, { rootPath });
|
|
274
|
+
try {
|
|
275
|
+
await fs.rm(path, { force: true, recursive: true });
|
|
276
|
+
}
|
|
277
|
+
catch (e) {
|
|
278
|
+
if (!noThrow) {
|
|
279
|
+
throw e;
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
},
|
|
283
|
+
/**
|
|
284
|
+
* The tree, one line per file, bounded.
|
|
285
|
+
*
|
|
286
|
+
* One command rather than a listing plus a read per entry: the caller is a census over a
|
|
287
|
+
* repository somebody else wrote, which may hold a hundred thousand files, and one round trip
|
|
288
|
+
* each — over a connector, on somebody's laptop — is not a slower walk but a walk that never
|
|
289
|
+
* finishes.
|
|
290
|
+
*
|
|
291
|
+
* `total` counts what the walk SAW and `entries` what it returned. They differ once the limit
|
|
292
|
+
* is reached, and that difference is the only thing that tells a caller its picture of the
|
|
293
|
+
* tree is partial: a listing that reported only its own length would be indistinguishable
|
|
294
|
+
* from a small repository.
|
|
295
|
+
*
|
|
296
|
+
* Every entry's `path` is relative to the directory ASKED FOR, not to the project root. That
|
|
297
|
+
* is the contract the in-process helper and the publisher answer, and one executor answering
|
|
298
|
+
* a different relativity is worse than either choice: the caller is a census that follows a
|
|
299
|
+
* listing with a `readHead` of what it listed, and nothing downstream knows which of the
|
|
300
|
+
* three produced the path it is holding.
|
|
301
|
+
*/
|
|
302
|
+
statTree: async (dir, limit) => {
|
|
303
|
+
const start = dir != null && dir !== ''
|
|
304
|
+
? resolveInProject(dir, { rootPath })
|
|
305
|
+
: p.resolve(rootPath);
|
|
306
|
+
const cap = limit != null && limit > 0 ? limit : CENSUS_MAX_ENTRIES;
|
|
307
|
+
const entries = [];
|
|
308
|
+
let total = 0;
|
|
309
|
+
const walk = async (absolute) => {
|
|
310
|
+
const listed = await fs.readdir(absolute, { withFileTypes: true }).catch(() => []);
|
|
311
|
+
for (const entry of listed) {
|
|
312
|
+
if (WALK_SKIP.has(entry.name))
|
|
313
|
+
continue;
|
|
314
|
+
const child = p.join(absolute, entry.name);
|
|
315
|
+
if (entry.isDirectory()) {
|
|
316
|
+
await walk(child);
|
|
317
|
+
continue;
|
|
318
|
+
}
|
|
319
|
+
// Symlinks and devices are counted by nobody: a census describes files a model could
|
|
320
|
+
// read, and following a link would leave the tree it was asked about.
|
|
321
|
+
if (!entry.isFile())
|
|
322
|
+
continue;
|
|
323
|
+
total += 1;
|
|
324
|
+
if (entries.length >= cap)
|
|
325
|
+
continue;
|
|
326
|
+
const stat = await fs.stat(child).catch(() => null);
|
|
327
|
+
if (stat == null)
|
|
328
|
+
continue;
|
|
329
|
+
const rel = p.relative(start, child);
|
|
330
|
+
const known = binaryByExtension(rel);
|
|
331
|
+
entries.push({
|
|
332
|
+
path: rel,
|
|
333
|
+
bytes: stat.size,
|
|
334
|
+
binary: known ?? await isBinary(child, stat.size),
|
|
335
|
+
modifiedAt: stat.mtime.toISOString(),
|
|
336
|
+
});
|
|
337
|
+
}
|
|
338
|
+
};
|
|
339
|
+
await walk(start);
|
|
340
|
+
return { entries, truncated: total > entries.length, total };
|
|
341
|
+
},
|
|
342
|
+
/**
|
|
343
|
+
* The first bytes of one file, decoded as text.
|
|
344
|
+
*
|
|
345
|
+
* A classification reads a head; reading whole files to do it would hold a megabyte export in
|
|
346
|
+
* memory to look at its first line. Whatever the decoding produces for a binary head is the
|
|
347
|
+
* answer — that IS the signal an entropy classification wants, and cleaning it up would hide
|
|
348
|
+
* the one thing the caller is asking about.
|
|
349
|
+
*/
|
|
350
|
+
readHead: async (filePath, bytes) => {
|
|
351
|
+
// Confinement first, and it is the ONE thing here that still raises: a path resolving
|
|
352
|
+
// outside the project is a caller's bug, never an entry of a tree.
|
|
353
|
+
const path = resolveInProject(filePath, { rootPath });
|
|
354
|
+
// Everything else answers `''`. A census hands this whatever a walk over somebody else's
|
|
355
|
+
// tree produced — a directory, a symlink, a file deleted between the listing and the read —
|
|
356
|
+
// and one unreadable entry must not fail the pass that is classifying the rest. A directory
|
|
357
|
+
// is the case that made this necessary: `open` succeeds on one and the read then throws
|
|
358
|
+
// EISDIR, so the tolerant answer has to cover the read as well as the open.
|
|
359
|
+
const stat = await fs.stat(path).catch(() => null);
|
|
360
|
+
if (stat == null || !stat.isFile())
|
|
361
|
+
return '';
|
|
362
|
+
const length = Math.min(Math.max(bytes, 0), stat.size, CENSUS_MAX_HEAD_BYTES);
|
|
363
|
+
if (length < 1)
|
|
364
|
+
return '';
|
|
365
|
+
const handle = await fsp.open(path, 'r').catch(() => null);
|
|
366
|
+
if (handle == null)
|
|
367
|
+
return '';
|
|
368
|
+
try {
|
|
369
|
+
const buffer = Buffer.alloc(length);
|
|
370
|
+
const { bytesRead } = await handle.read(buffer, 0, length, 0);
|
|
371
|
+
return buffer.subarray(0, bytesRead).toString('utf-8');
|
|
372
|
+
}
|
|
373
|
+
catch {
|
|
374
|
+
return '';
|
|
375
|
+
}
|
|
376
|
+
finally {
|
|
377
|
+
await handle.close();
|
|
378
|
+
}
|
|
379
|
+
},
|
|
380
|
+
/**
|
|
381
|
+
* Move everything in the project root under one directory, leaving a named few where they are.
|
|
382
|
+
*
|
|
383
|
+
* What makes a converted project possible: the origin's own tree goes below, a Viable target
|
|
384
|
+
* is grown above it, and the two never share a path. It is the same walk `emptyProject` does —
|
|
385
|
+
* kept paths may be nested, a directory holding one is walked rather than moved, and a
|
|
386
|
+
* directory left empty by that walk does not survive as a shell.
|
|
387
|
+
*
|
|
388
|
+
* The always-keep set applies here too and for the same reason: `.git` is the developer's
|
|
389
|
+
* history and moving it under the origin would take the project's whole history with it,
|
|
390
|
+
* `.viable` is how a later session recognizes the project, and the two `.env` files hold what
|
|
391
|
+
* the platform cannot re-derive.
|
|
392
|
+
*
|
|
393
|
+
* Refuses a destination that already holds something. A relocation into an occupied directory
|
|
394
|
+
* interleaves two trees, and nothing afterwards can tell which files came from where.
|
|
395
|
+
*/
|
|
396
|
+
relocate: async (dir, keep) => {
|
|
397
|
+
// Resolved FIRST, and the project-relative name derived back from the resolved path. A
|
|
398
|
+
// destination arrives in both shapes like every other path a caller sends, and normalizing
|
|
399
|
+
// the string ahead of the confinement is what builds the shadow tree `resolveInProject`
|
|
400
|
+
// exists to prevent: an absolute destination lost its leading slash, resolved under the root
|
|
401
|
+
// a second time, and the keep set then no longer matched the top-level name it had created.
|
|
402
|
+
// It also subsumes `.`, `''` and a trailing slash, which all resolve to the root itself.
|
|
403
|
+
const destinationPath = resolveInProject(dir ?? '', { rootPath });
|
|
404
|
+
const destination = p.relative(p.resolve(rootPath), destinationPath);
|
|
405
|
+
if (destination === '') {
|
|
406
|
+
throw new FileCommandRefused('relocate needs a directory to move the project into');
|
|
407
|
+
}
|
|
408
|
+
if (await fs.pathExists(destinationPath)) {
|
|
409
|
+
const existing = await fs.readdir(destinationPath);
|
|
410
|
+
if (existing.length > 0) {
|
|
411
|
+
throw new FileCommandRefused(`relocation target is not empty: ${destination}`);
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
// The destination is kept like anything else, which is what stops the walk moving it into
|
|
415
|
+
// itself — a keep is checked before a move, and this one always matches first.
|
|
416
|
+
const { keep: kept, isKept, holdsKept } = keepGuards([destination, ...(keep ?? []), ...alwaysKeep()]);
|
|
417
|
+
const move = async (rel) => {
|
|
418
|
+
const from = rel === '' ? rootPath : p.join(rootPath, rel);
|
|
419
|
+
const entries = await fs.readdir(from);
|
|
420
|
+
let moved = 0;
|
|
421
|
+
// Serial: a relocation is one operation from the caller's point of view, and a half-moved
|
|
422
|
+
// tree is neither the origin nor a target.
|
|
423
|
+
for (const name of entries) {
|
|
424
|
+
const child = rel === '' ? name : `${rel}/${name}`;
|
|
425
|
+
if (isKept(child))
|
|
426
|
+
continue;
|
|
427
|
+
if (holdsKept(child)) {
|
|
428
|
+
moved += await move(child);
|
|
429
|
+
const remaining = await fs.readdir(p.join(rootPath, child));
|
|
430
|
+
if (remaining.length === 0)
|
|
431
|
+
await fs.remove(p.join(rootPath, child));
|
|
432
|
+
continue;
|
|
433
|
+
}
|
|
434
|
+
const to = p.join(destinationPath, child);
|
|
435
|
+
await fs.ensureDir(p.dirname(to));
|
|
436
|
+
await fs.move(p.join(rootPath, child), to);
|
|
437
|
+
moved += 1;
|
|
438
|
+
}
|
|
439
|
+
return moved;
|
|
440
|
+
};
|
|
441
|
+
await fs.ensureDir(destinationPath);
|
|
442
|
+
const moved = await move('');
|
|
443
|
+
// The whole keep set, exactly as the publisher and the library helper answer it — this is a
|
|
444
|
+
// report of what the relocation was told to leave alone, not a listing of what happens to be
|
|
445
|
+
// on disk afterwards. Filtering it by existence made the same relocation answer differently
|
|
446
|
+
// here than in a slot, over paths (a project without local branding has no web `.env`) whose
|
|
447
|
+
// absence says nothing about the move.
|
|
448
|
+
return { moved, kept: [...kept] };
|
|
449
|
+
},
|
|
450
|
+
/**
|
|
451
|
+
* Delete a directory and everything under it — the purge of a relocated origin.
|
|
452
|
+
*
|
|
453
|
+
* Refuses the project root: emptying the project is `emptyProject`, which has a keep list this
|
|
454
|
+
* does not, and a purge that resolved to `.` would take the developer's `.git` and `.env` with
|
|
455
|
+
* the origin it was asked to remove.
|
|
456
|
+
*/
|
|
457
|
+
removeTree: async (dir) => {
|
|
458
|
+
const path = resolveInProject(dir, { rootPath });
|
|
459
|
+
if (path === p.resolve(rootPath)) {
|
|
460
|
+
throw new FileCommandRefused('removeTree cannot delete the project root');
|
|
461
|
+
}
|
|
462
|
+
await fs.remove(path);
|
|
463
|
+
},
|
|
464
|
+
getRootPath: (subproject) => subproject == null
|
|
465
|
+
? rootPath
|
|
466
|
+
: p.join(rootPath, layout().dir, dirOf(subproject)),
|
|
467
|
+
findFilesWithEnvVars: async (frontend) => {
|
|
468
|
+
const searchPattern = frontend === true
|
|
469
|
+
? `${rootPath}${layout().dir}/${dirOf(SubProject.Frontend)}/src/**/*.ts`
|
|
470
|
+
: frontend === false
|
|
471
|
+
? `${rootPath}${layout().dir}/${dirOf(SubProject.Backend)}/src/**/*.ts`
|
|
472
|
+
: `${rootPath}**/*.ts`;
|
|
473
|
+
const files = await globby([
|
|
474
|
+
searchPattern,
|
|
475
|
+
`!${rootPath}**/node_modules/**/*`,
|
|
476
|
+
`!${rootPath}**/owlmeans.ts`,
|
|
477
|
+
`!${rootPath}**/config.ts`,
|
|
478
|
+
`!${rootPath}**/routes.ts`,
|
|
479
|
+
`!${rootPath}**/router.ts`,
|
|
480
|
+
`!${rootPath}**/index.ts`,
|
|
481
|
+
`!${rootPath}spectator-log/**/*`,
|
|
482
|
+
]);
|
|
483
|
+
const result = [];
|
|
484
|
+
for (const fullPath of files) {
|
|
485
|
+
const content = await fs.readFile(fullPath, 'utf-8').catch(() => '');
|
|
486
|
+
if (content.match(/process\.env\??\./g)) {
|
|
487
|
+
result.push(cleanUpPath(fullPath, { rootPath }));
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
return result;
|
|
491
|
+
}
|
|
492
|
+
};
|
|
493
|
+
return helper;
|
|
494
|
+
};
|
|
495
|
+
const wrapWithSlashes = (path) => path.endsWith('/') ? path : `${path}/`;
|
|
496
|
+
const cleanUpPath = (file, { rootPath }) => file.replace(rootPath, '').replace(/^\/+/, '');
|
|
497
|
+
/**
|
|
498
|
+
* Resolve a caller-supplied project path to the absolute path it names inside the project.
|
|
499
|
+
*
|
|
500
|
+
* Paths arrive from the platform in both shapes — root-relative (`sources/web/src/app.tsx`) and
|
|
501
|
+
* already absolute — so **every** fs call has to apply the same normalization, not just the read
|
|
502
|
+
* side. Concatenating an absolute path onto the root instead builds a shadow tree: the write
|
|
503
|
+
* reports success, a later read of the same name resolves to the untouched original, and the
|
|
504
|
+
* change looks like it was silently ignored.
|
|
505
|
+
*
|
|
506
|
+
* The refusal is confinement, not sanitization: only a fully resolved path can be compared to the
|
|
507
|
+
* root, and a `..`-to-`.` replace at one caller is a guard on that caller rather than on the tree.
|
|
508
|
+
*/
|
|
509
|
+
const resolveInProject = (file, { rootPath }) => {
|
|
510
|
+
const resolved = p.resolve(rootPath, cleanUpPath(file, { rootPath }));
|
|
511
|
+
const root = p.resolve(rootPath);
|
|
512
|
+
if (resolved !== root && !resolved.startsWith(wrapWithSlashes(root))) {
|
|
513
|
+
throw new SandboxPathError(file);
|
|
514
|
+
}
|
|
515
|
+
return resolved;
|
|
516
|
+
};
|
|
517
|
+
const normalizePaths = (files, { rootPath }) => {
|
|
518
|
+
const fileList = Array.isArray(files) ? files : [files];
|
|
519
|
+
return fileList.map(file => file.startsWith('/') ? cleanUpPath(file, { rootPath }) : file);
|
|
520
|
+
};
|
|
521
|
+
/**
|
|
522
|
+
* The same confinement, for callers outside this helper.
|
|
523
|
+
*
|
|
524
|
+
* Exported because the configure push writes `.env` files by name and a path is a path: a guard
|
|
525
|
+
* that only the file commands apply is a guard on the file commands, and the connector holds the
|
|
526
|
+
* developer's home directory rather than a pod's volume.
|
|
527
|
+
*/
|
|
528
|
+
export const confineToProject = (dir, file) => resolveInProject(file, { rootPath: wrapWithSlashes(p.resolve(dir)) });
|
|
529
|
+
//# sourceMappingURL=files.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"files.js","sourceRoot":"","sources":["../../src/executor/files.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { SlotGitCommand } from '@owlmeans/viable-common';
|
|
2
|
+
/**
|
|
3
|
+
* The runtime safety net `ensure` appends, so a first commit never captures dependencies, build
|
|
4
|
+
* output, secrets or the connector's own scratch files.
|
|
5
|
+
*
|
|
6
|
+
* `.viable/connect.json` is deliberately NOT here: it is the project's identity, it holds no
|
|
7
|
+
* secret, and a developer who clones their own repository elsewhere should find it. The two files
|
|
8
|
+
* beside it are — a run record names pids on one machine, and the local keypair is a credential.
|
|
9
|
+
*/
|
|
10
|
+
declare const IGNORE_BASELINE: string[];
|
|
11
|
+
/**
|
|
12
|
+
* Why a local repository is never pushed, pulled or given a remote.
|
|
13
|
+
*
|
|
14
|
+
* DELIBERATE DIFFERENCE from the publisher, which does all three against a token the platform
|
|
15
|
+
* holds. A slot's volume is the platform's and its remote is a repository the platform created;
|
|
16
|
+
* a developer's checkout is THEIRS, its remote is whatever they configured, and pushing to it
|
|
17
|
+
* would mean the platform writing to a repository nobody here was asked about — with the
|
|
18
|
+
* developer's own credential helper supplying the authentication. So the platform touches none
|
|
19
|
+
* of it: whoever owns the directory owns its remotes.
|
|
20
|
+
*/
|
|
21
|
+
declare const REMOTE_REFUSAL: string;
|
|
22
|
+
/**
|
|
23
|
+
* Why a local target is never cloned into.
|
|
24
|
+
*
|
|
25
|
+
* A clone exists for one case — the platform fetching an origin repository onto a slot's volume it
|
|
26
|
+
* owns — and a local target has already answered that question: the directory the connector was
|
|
27
|
+
* started in IS the origin, and there is nothing to fetch. Overwriting it with a remote tree would
|
|
28
|
+
* replace a developer's working copy, including whatever they had not committed.
|
|
29
|
+
*
|
|
30
|
+
* Answered as TEXT beside {@link REMOTE_REFUSAL} and never thrown, for the same reason: a caller
|
|
31
|
+
* that received an exception would retry something that can never succeed, while a `cloned: false`
|
|
32
|
+
* in the shape it already parses is a fact its next step can read.
|
|
33
|
+
*/
|
|
34
|
+
declare const CLONE_REFUSAL: string;
|
|
35
|
+
/**
|
|
36
|
+
* Make the directory a repository the platform can work in, and change nothing else.
|
|
37
|
+
*
|
|
38
|
+
* DELIBERATE DIFFERENCE from the publisher on two points, both because this history belongs to a
|
|
39
|
+
* person rather than to a slot:
|
|
40
|
+
*
|
|
41
|
+
* - **No baseline commit.** The publisher snapshots a pre-git slot into a first commit so its
|
|
42
|
+
* history starts clean. Here the first commit is the developer's to make (or not) — a tool that
|
|
43
|
+
* committed a working tree it found is a tool that decided what their project's history says.
|
|
44
|
+
* - **An identity only when there is none.** `git config user.name` consults local, global and
|
|
45
|
+
* system, so a developer with a global identity keeps authoring as themselves. Writing the
|
|
46
|
+
* platform's name unconditionally would rewrite the author of every commit made in that
|
|
47
|
+
* directory afterwards, including ones the platform had nothing to do with.
|
|
48
|
+
*/
|
|
49
|
+
declare const ensure: (dir: string) => Promise<void>;
|
|
50
|
+
export declare const dispatchGitCommand: (dir: string, command: SlotGitCommand, args?: Record<string, any>) => Promise<Record<string, unknown>>;
|
|
51
|
+
export { CLONE_REFUSAL, ensure as ensureGitRepo, IGNORE_BASELINE, REMOTE_REFUSAL };
|
|
52
|
+
//# sourceMappingURL=git.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"git.d.ts","sourceRoot":"","sources":["../../src/executor/git.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAA;AAuBxD;;;;;;;GAOG;AACH,QAAA,MAAM,eAAe,UAQpB,CAAA;AAED;;;;;;;;;GASG;AACH,QAAA,MAAM,cAAc,QACoD,CAAA;AAExE;;;;;;;;;;;GAWG;AACH,QAAA,MAAM,aAAa,QAC0C,CAAA;AA2J7D;;;;;;;;;;;;;GAaG;AACH,QAAA,MAAM,MAAM,QAAe,MAAM,KAAG,OAAO,CAAC,IAAI,CA+B/C,CAAA;AA0BD,eAAO,MAAM,kBAAkB,QACxB,MAAM,WAAW,cAAc,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,KAC/D,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CACqC,CAAA;AA8HvE,OAAO,EAAE,aAAa,EAAE,MAAM,IAAI,aAAa,EAAE,eAAe,EAAE,cAAc,EAAE,CAAA"}
|