@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.
@@ -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 the SDK and local actions over CDP
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. For a product that does not already embed the Foldspace SDK, run
44
- `npm run attach -- --bootstrap`.
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-build --watch",
9
- "build": "foldspace-build",
10
- "inject": "foldspace-inject",
11
- "attach": "foldspace-attach"
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}}",
@@ -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
- }
@@ -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
- }