@foldspace_npm/harness 0.1.1 → 0.1.3
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 +79 -31
- package/bin/attach.mjs +779 -107
- package/bin/cli.mjs +139 -11
- package/bin/deploy.mjs +37 -33
- package/bin/inject.mjs +64 -295
- package/package.json +6 -7
- package/src/action-observer.mjs +271 -0
- package/src/attach-helpers.mjs +162 -0
- package/src/attach-preflight.mjs +332 -0
- package/src/bootstrap-script.mjs +120 -0
- package/src/cdp-request-manager.mjs +61 -0
- package/src/cli-help.mjs +143 -0
- package/src/cli-registry.mjs +309 -0
- package/src/diagnostics.mjs +482 -0
- package/src/init.mjs +192 -18
- package/src/project-config.mjs +37 -0
- package/src/protocol.mjs +181 -0
- package/src/session-summary.mjs +133 -0
- package/templates/agent-starter/CLAUDE.md +31 -8
- package/templates/agent-starter/README.md +26 -3
- package/templates/agent-starter/foldspace.dev.json +1 -3
- package/templates/agent-starter/package.json +4 -4
- package/bin/buildExtension.mjs +0 -90
- package/bin/packageExtension.mjs +0 -29
|
@@ -26,22 +26,45 @@ agent/
|
|
|
26
26
|
api/ one file per HTTP helper
|
|
27
27
|
constants.ts product, agent, and domain identifiers
|
|
28
28
|
utils.ts Foldspace agent lookup
|
|
29
|
+
docs/ optional notes for coding-agent learnings (create when needed)
|
|
29
30
|
foldspace.dev.json
|
|
30
31
|
CLAUDE.md
|
|
31
32
|
```
|
|
32
33
|
|
|
34
|
+
## Agent learnings
|
|
35
|
+
|
|
36
|
+
Coding agents may keep durable, repository-specific lessons under `docs/` so
|
|
37
|
+
later sessions do not repeat the same mistakes. Create the folder when the first
|
|
38
|
+
note is useful; do not commit an empty `docs/` directory.
|
|
39
|
+
|
|
40
|
+
Good notes cover verified gotchas, failed approaches, design rationale, and
|
|
41
|
+
useful verification commands. Keep them concise and evidence-based. Before
|
|
42
|
+
similar work, read any relevant notes in `docs/`. Do not store secrets, cookies,
|
|
43
|
+
HAR files, browser storage, or other transient session data there.
|
|
44
|
+
|
|
33
45
|
## Commands
|
|
34
46
|
|
|
35
47
|
```bash
|
|
48
|
+
npx foldspace help # discover commands, risks, and next steps
|
|
36
49
|
npm run build # create dist/index.js
|
|
37
50
|
npm run dev # rebuild dist/index.js on changes
|
|
38
51
|
npm run inject # launch the dedicated Chrome profile
|
|
39
|
-
npm run attach # load
|
|
52
|
+
npm run attach # load local actions and observe the agent over CDP
|
|
40
53
|
```
|
|
41
54
|
|
|
42
55
|
Run `inject` before `attach`. Sign in to the product in the Chrome window that
|
|
43
|
-
`inject` opens.
|
|
44
|
-
`
|
|
56
|
+
`inject` opens. `inject` does not generate an application extension; `attach`
|
|
57
|
+
loads `dist/index.js` directly through CDP.
|
|
58
|
+
|
|
59
|
+
Choose the attach mode from the state of the target page:
|
|
60
|
+
|
|
61
|
+
- Default swap: the page already has the configured product and agent.
|
|
62
|
+
- `npm run attach -- --bootstrap`: the page has no Foldspace SDK.
|
|
63
|
+
- `npm run attach -- --replace`: the page has a different product or agent, or
|
|
64
|
+
an SDK without the configured agent.
|
|
65
|
+
|
|
66
|
+
Run `npx foldspace help attach` for full requirements and safety options. Coding
|
|
67
|
+
agents can read the versioned contract with `npx foldspace help --json`.
|
|
45
68
|
|
|
46
69
|
## Add an action
|
|
47
70
|
|
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
"$comment": "Generated by foldspace init. Use the bare product ID, not the EU-… SDK key.",
|
|
3
3
|
"defaultTarget": "app",
|
|
4
4
|
"sdkUrl": "https://script.eucerahive.io/web/sdk/foldspace.js",
|
|
5
|
-
"localActionsUrl": "http://localhost:3007/dist/index.js",
|
|
6
5
|
"targets": {
|
|
7
6
|
"app": {
|
|
8
7
|
"name": "App",
|
|
@@ -10,8 +9,7 @@
|
|
|
10
9
|
"productId": {{PRODUCT_ID_JSON}},
|
|
11
10
|
"agentApiName": {{AGENT_API_NAME_JSON}},
|
|
12
11
|
"hosts": {{HOSTS_JSON}},
|
|
13
|
-
"mode": "OVERLAY"
|
|
14
|
-
"loadLocally": true
|
|
12
|
+
"mode": "OVERLAY"
|
|
15
13
|
}
|
|
16
14
|
}
|
|
17
15
|
}
|
|
@@ -5,10 +5,10 @@
|
|
|
5
5
|
"private": true,
|
|
6
6
|
"type": "module",
|
|
7
7
|
"scripts": {
|
|
8
|
-
"dev": "foldspace
|
|
9
|
-
"build": "foldspace
|
|
10
|
-
"inject": "foldspace
|
|
11
|
-
"attach": "foldspace
|
|
8
|
+
"dev": "foldspace build --watch",
|
|
9
|
+
"build": "foldspace build",
|
|
10
|
+
"inject": "foldspace inject",
|
|
11
|
+
"attach": "foldspace attach"
|
|
12
12
|
},
|
|
13
13
|
"devDependencies": {
|
|
14
14
|
"@foldspace_npm/harness": "{{HARNESS_VERSION}}",
|
package/bin/buildExtension.mjs
DELETED
|
@@ -1,90 +0,0 @@
|
|
|
1
|
-
import { execFileSync } from "child_process";
|
|
2
|
-
import fs from "fs";
|
|
3
|
-
import path from "path";
|
|
4
|
-
import { fileURLToPath } from "url";
|
|
5
|
-
|
|
6
|
-
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
7
|
-
const projectDir = process.env.FOLDSPACE_PROJECT_DIR || process.cwd();
|
|
8
|
-
const indexPath = path.join(projectDir, "extension", "index.js");
|
|
9
|
-
|
|
10
|
-
const LOAD_LOCALLY_TRUE = "const LOAD_LOCALLY = true;";
|
|
11
|
-
const LOAD_LOCALLY_FALSE = "const LOAD_LOCALLY = false;";
|
|
12
|
-
const REMOTE_ENV_DEV = 'const REMOTE_ACTIONS_ENV = "DEV";';
|
|
13
|
-
const REMOTE_ENV_PROD = 'const REMOTE_ACTIONS_ENV = "PROD";';
|
|
14
|
-
|
|
15
|
-
function parseArgs(argv) {
|
|
16
|
-
for (let i = 0; i < argv.length; i++) {
|
|
17
|
-
if (argv[i] === "--env" && argv[i + 1]) return argv[++i];
|
|
18
|
-
}
|
|
19
|
-
return null;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
const env = parseArgs(process.argv.slice(2));
|
|
23
|
-
if (!env || (env !== "dev" && env !== "prod")) {
|
|
24
|
-
console.error('buildExtension: --env <dev|prod> is required');
|
|
25
|
-
process.exit(1);
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
function replaceInIndex(from, to, label) {
|
|
29
|
-
const source = fs.readFileSync(indexPath, "utf8");
|
|
30
|
-
|
|
31
|
-
if (!source.includes(from)) {
|
|
32
|
-
if (source.includes(to)) {
|
|
33
|
-
console.log(`buildExtension: ${label} already set`);
|
|
34
|
-
return;
|
|
35
|
-
}
|
|
36
|
-
console.error(
|
|
37
|
-
`buildExtension: expected ${label} pattern not found in index.js`,
|
|
38
|
-
);
|
|
39
|
-
process.exit(1);
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
fs.writeFileSync(indexPath, source.replace(from, to), "utf8");
|
|
43
|
-
console.log(`buildExtension: ${label} → ${to}`);
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
function setLoadLocally(value) {
|
|
47
|
-
if (!fs.existsSync(indexPath)) {
|
|
48
|
-
console.error("buildExtension: extension/index.js not found");
|
|
49
|
-
process.exit(1);
|
|
50
|
-
}
|
|
51
|
-
const from = value ? LOAD_LOCALLY_FALSE : LOAD_LOCALLY_TRUE;
|
|
52
|
-
const to = value ? LOAD_LOCALLY_TRUE : LOAD_LOCALLY_FALSE;
|
|
53
|
-
replaceInIndex(from, to, "LOAD_LOCALLY");
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
function setRemoteActionsEnv(targetEnv) {
|
|
57
|
-
const from = targetEnv === "dev" ? REMOTE_ENV_PROD : REMOTE_ENV_DEV;
|
|
58
|
-
const to = targetEnv === "dev" ? REMOTE_ENV_DEV : REMOTE_ENV_PROD;
|
|
59
|
-
replaceInIndex(from, to, "REMOTE_ACTIONS_ENV");
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
let failed = false;
|
|
63
|
-
|
|
64
|
-
try {
|
|
65
|
-
execFileSync("tsx", ["scripts/build.ts"], {
|
|
66
|
-
cwd: projectDir,
|
|
67
|
-
stdio: "inherit",
|
|
68
|
-
});
|
|
69
|
-
|
|
70
|
-
setLoadLocally(false);
|
|
71
|
-
setRemoteActionsEnv(env);
|
|
72
|
-
|
|
73
|
-
execFileSync("node", ["scripts/packageExtension.mjs"], {
|
|
74
|
-
cwd: projectDir,
|
|
75
|
-
stdio: "inherit",
|
|
76
|
-
});
|
|
77
|
-
} catch {
|
|
78
|
-
failed = true;
|
|
79
|
-
} finally {
|
|
80
|
-
try {
|
|
81
|
-
setLoadLocally(true);
|
|
82
|
-
setRemoteActionsEnv("prod");
|
|
83
|
-
} catch {
|
|
84
|
-
failed = true;
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
if (failed) {
|
|
89
|
-
process.exit(1);
|
|
90
|
-
}
|
package/bin/packageExtension.mjs
DELETED
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import { execFileSync } from "child_process";
|
|
2
|
-
import fs from "fs";
|
|
3
|
-
import path from "path";
|
|
4
|
-
import { fileURLToPath } from "url";
|
|
5
|
-
|
|
6
|
-
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
7
|
-
const projectDir = process.env.FOLDSPACE_PROJECT_DIR || process.cwd();
|
|
8
|
-
const projectName = path.basename(projectDir);
|
|
9
|
-
const extensionDir = path.join(projectDir, "extension");
|
|
10
|
-
const zipPath = path.join(projectDir, `${projectName}-extension.zip`);
|
|
11
|
-
|
|
12
|
-
if (!fs.existsSync(extensionDir)) {
|
|
13
|
-
console.error("packageExtension: extension/ directory not found");
|
|
14
|
-
process.exit(1);
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
try {
|
|
18
|
-
if (fs.existsSync(zipPath)) {
|
|
19
|
-
fs.rmSync(zipPath);
|
|
20
|
-
}
|
|
21
|
-
execFileSync("zip", ["-r", zipPath, "."], {
|
|
22
|
-
cwd: extensionDir,
|
|
23
|
-
stdio: "inherit",
|
|
24
|
-
});
|
|
25
|
-
console.log(`packageExtension: created ${zipPath}`);
|
|
26
|
-
} catch {
|
|
27
|
-
console.error("packageExtension: failed to create extension.zip");
|
|
28
|
-
process.exit(1);
|
|
29
|
-
}
|