@guuey/fs 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 +21 -0
- package/README.md +132 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +9 -0
- package/dist/roots.d.ts +18 -0
- package/dist/roots.d.ts.map +1 -0
- package/dist/roots.js +30 -0
- package/package.json +51 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Loqu, Inc.
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
# `@guuey/fs`
|
|
2
|
+
|
|
3
|
+
> Dev-guidance helper for GuueyFS — the per-(app, user, session) filesystem
|
|
4
|
+
> every agent hosted on [guuey.com](https://guuey.com) runs inside. There is
|
|
5
|
+
> no wrapper API: **plain `node:fs` on the three paths below IS the
|
|
6
|
+
> contract.** This package just tells you where they are.
|
|
7
|
+
|
|
8
|
+
## Install
|
|
9
|
+
|
|
10
|
+
```sh
|
|
11
|
+
npm install @guuey/fs
|
|
12
|
+
# or
|
|
13
|
+
pnpm add @guuey/fs
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## The three paths
|
|
17
|
+
|
|
18
|
+
Every hosted agent invoke runs with three directories bound in, one per
|
|
19
|
+
layer:
|
|
20
|
+
|
|
21
|
+
| Helper | Layer | Read/write | Lifetime |
|
|
22
|
+
| -------------- | --------- | ------------------ | ---------------------------------------------------------------------------- |
|
|
23
|
+
| `homeDir()` | `home` | read-write | Durable, per (app, user) — survives restarts and new sessions. |
|
|
24
|
+
| `appDir()` | `app` | read-only | Shared across every user of the app; ships with the app, not per-user. |
|
|
25
|
+
| `sessionDir()` | `session` | read-write (= cwd) | Scratch for THIS turn's session. Pod-local — does not survive a pod restart. |
|
|
26
|
+
|
|
27
|
+
```ts
|
|
28
|
+
import { homeDir, appDir, sessionDir } from "@guuey/fs";
|
|
29
|
+
import { readFile, writeFile, mkdir } from "node:fs/promises";
|
|
30
|
+
import { join } from "node:path";
|
|
31
|
+
|
|
32
|
+
// Durable per-user memory — plain node:fs, nothing else.
|
|
33
|
+
const memoryPath = join(homeDir(), "memories", "MEMORY.md");
|
|
34
|
+
await mkdir(join(homeDir(), "memories"), { recursive: true });
|
|
35
|
+
await writeFile(memoryPath, "User prefers dark mode.\n", { flag: "a" });
|
|
36
|
+
const memory = await readFile(memoryPath, "utf8").catch(() => undefined);
|
|
37
|
+
|
|
38
|
+
// Shared, read-only per-app assets your build ships with the agent.
|
|
39
|
+
const template = await readFile(join(appDir(), "templates", "welcome.md"), "utf8");
|
|
40
|
+
|
|
41
|
+
// Scratch space for this session — sessionDir() IS process.cwd(), so plain
|
|
42
|
+
// relative paths already resolve here.
|
|
43
|
+
await writeFile("draft.txt", "working notes for this turn\n");
|
|
44
|
+
// equivalent: join(sessionDir(), "draft.txt")
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Each helper throws a clear error if its env var isn't set — that's the
|
|
48
|
+
signal you're not running inside the guuey Router (`guuey dev` or the
|
|
49
|
+
hosted runtime). There's nothing to configure and nothing to catch
|
|
50
|
+
silently: either you're on a guuey pod and the paths are there, or you
|
|
51
|
+
aren't and the helper tells you so immediately.
|
|
52
|
+
|
|
53
|
+
## Memory behavior — the part that matters
|
|
54
|
+
|
|
55
|
+
Once the durable filesystem is enabled for an environment (the GuueyFS
|
|
56
|
+
rollout — operator-gated per env, see Status below), this is the target
|
|
57
|
+
contract:
|
|
58
|
+
|
|
59
|
+
- **Signed-in users**: `homeDir()` is durable cross-session memory. Files an
|
|
60
|
+
agent writes today are there next week, from a different pod, after a
|
|
61
|
+
restart.
|
|
62
|
+
- **Guests (anonymous sessions)**: `homeDir()` is still a real, writable
|
|
63
|
+
directory — but it's backed by pod-local ephemeral scratch, not durable
|
|
64
|
+
storage. Nothing a guest writes survives past the pod's lifetime. This is
|
|
65
|
+
a deliberate platform boundary (guests never accumulate durable storage),
|
|
66
|
+
not a bug — don't build a feature that assumes guest `homeDir()` writes
|
|
67
|
+
persist.
|
|
68
|
+
- **`sessionDir()`** is pod-local scratch for every caller, guest or
|
|
69
|
+
signed-in — by contract, not a deferred feature. Don't put anything there
|
|
70
|
+
you need past the current session.
|
|
71
|
+
|
|
72
|
+
**Automatic recall is `claude-agent-sdk`-only today.** The three paths above
|
|
73
|
+
— including `homeDir()`'s durable-for-signed-in-users behavior — are the
|
|
74
|
+
same on every framework Guuey hosts. What's framework-scoped is the
|
|
75
|
+
Router's automatic recall: on `claude-agent-sdk`, the platform reads
|
|
76
|
+
`<home>/memories/MEMORY.md` before each turn and injects it into the
|
|
77
|
+
model's context for you, for free. On openai-agents-sdk and google-adk,
|
|
78
|
+
that automatic injection doesn't happen yet — an agent on those frameworks
|
|
79
|
+
can still read/write the same file with plain `node:fs` (as above), it just
|
|
80
|
+
has to do the reading itself. All-framework automatic recall arrives with
|
|
81
|
+
guuey's own memory MCP (a platform tool every framework calls over its
|
|
82
|
+
existing MCP channel). Separately: framework-native memory backends (e.g.
|
|
83
|
+
Google ADK's Vertex MemoryBank) are unsupported on Guuey — they store user
|
|
84
|
+
data outside guuey's deletion boundary, and there's no data-governance
|
|
85
|
+
policy for that yet.
|
|
86
|
+
|
|
87
|
+
Until the rollout reaches an environment, hosted agents there DO still get
|
|
88
|
+
`GUUEY_HOME_DIR`/`GUUEY_APP_DIR` — pointing at pod-local ephemeral storage.
|
|
89
|
+
Writes to `homeDir()` work, but nothing survives the pod: treat every layer
|
|
90
|
+
as session-lifetime until the durable filesystem is enabled for your
|
|
91
|
+
environment. The helpers' throw only signals you're outside the guuey
|
|
92
|
+
runtime entirely (no `guuey dev`, no hosted pod) — it is not a durability
|
|
93
|
+
signal.
|
|
94
|
+
|
|
95
|
+
## What this package is NOT
|
|
96
|
+
|
|
97
|
+
- **Not a storage adapter.** There's no `FsSource`, no versioning/CoW
|
|
98
|
+
overlay, no read/write resolution logic to import. Base-path injection —
|
|
99
|
+
the Router hands you three real directories — won that design; a client
|
|
100
|
+
library on top of it would just be indirection.
|
|
101
|
+
- **Not a durability guarantee by itself.** The env vars are the contract;
|
|
102
|
+
whether `homeDir()` is backed by durable storage depends on whether the
|
|
103
|
+
durable filesystem is enabled for the environment AND whether the caller
|
|
104
|
+
is signed in (see Memory behavior above) — this package can't change
|
|
105
|
+
that, only report where the paths are.
|
|
106
|
+
|
|
107
|
+
## Status
|
|
108
|
+
|
|
109
|
+
🧪 **Developer preview (`0.x`).** The three-path shape (`home`/`app`/
|
|
110
|
+
`session`) and the env-var names (`GUUEY_HOME_DIR`, `GUUEY_APP_DIR`,
|
|
111
|
+
`process.cwd()`) are the actual production contract, not a preview of one —
|
|
112
|
+
code written against this package today keeps working unchanged when the
|
|
113
|
+
durable-filesystem rollout reaches your environment. What exists vs.
|
|
114
|
+
what's coming:
|
|
115
|
+
|
|
116
|
+
| Piece | Status |
|
|
117
|
+
| --------------------------------------------------- | ---------------------------------------------------------- |
|
|
118
|
+
| `homeDir()`/`appDir()`/`sessionDir()` helpers | ✅ shipped |
|
|
119
|
+
| Env-var contract (`GUUEY_HOME_DIR`/`GUUEY_APP_DIR`) | ✅ shipped |
|
|
120
|
+
| Durable per-user `home` (signed-in users) | 🔜 lands with the GuueyFS rollout (operator-gated per env) |
|
|
121
|
+
| Guest `home` = pod-local ephemeral | 🔜 lands with the GuueyFS rollout (operator-gated per env) |
|
|
122
|
+
| Per-user/per-app storage quotas | 🔜 enforced at the filesystem layer, not visible here |
|
|
123
|
+
|
|
124
|
+
Until the rollout reaches an environment, the durable backing is off there
|
|
125
|
+
(`GUUEY_FS_BASE` unset) — but hosted agents still get the env vars, pointing
|
|
126
|
+
at pod-local ephemeral storage: writes work, nothing survives the pod (see
|
|
127
|
+
Memory behavior above).
|
|
128
|
+
|
|
129
|
+
This package is optional sugar — three one-line env-var reads. You can
|
|
130
|
+
skip it entirely and read `process.env.GUUEY_HOME_DIR` /
|
|
131
|
+
`process.env.GUUEY_APP_DIR` / `process.cwd()` yourself; nothing here is
|
|
132
|
+
magic.
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @guuey/fs — a tiny dev-guidance helper for the GuueyFS 3-layer contract every
|
|
3
|
+
* hosted guuey agent runs inside. `homeDir()`/`appDir()`/`sessionDir()` just read
|
|
4
|
+
* the env vars the Router already injects (`GUUEY_HOME_DIR`/`GUUEY_APP_DIR`) plus
|
|
5
|
+
* `process.cwd()` — there is no wrapper API, no adapter, no storage abstraction.
|
|
6
|
+
* Plain `node:fs` on the three paths IS the contract. See README.md and
|
|
7
|
+
* docs/superpowers/specs/2026-07-20-guueyfs-slice4-design.md §6.
|
|
8
|
+
*/
|
|
9
|
+
export { ENV_HOME_DIR, ENV_APP_DIR, homeDir, appDir, sessionDir } from "./roots.js";
|
|
10
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @guuey/fs — a tiny dev-guidance helper for the GuueyFS 3-layer contract every
|
|
3
|
+
* hosted guuey agent runs inside. `homeDir()`/`appDir()`/`sessionDir()` just read
|
|
4
|
+
* the env vars the Router already injects (`GUUEY_HOME_DIR`/`GUUEY_APP_DIR`) plus
|
|
5
|
+
* `process.cwd()` — there is no wrapper API, no adapter, no storage abstraction.
|
|
6
|
+
* Plain `node:fs` on the three paths IS the contract. See README.md and
|
|
7
|
+
* docs/superpowers/specs/2026-07-20-guueyfs-slice4-design.md §6.
|
|
8
|
+
*/
|
|
9
|
+
export { ENV_HOME_DIR, ENV_APP_DIR, homeDir, appDir, sessionDir } from "./roots.js";
|
package/dist/roots.d.ts
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Env-var names the Router injects so agent code reaches the home/app layers
|
|
3
|
+
* portably. This package's OWN copy (trivial string literals — not imported,
|
|
4
|
+
* so the published `@guuey/fs` package has zero non-devDependency deps and
|
|
5
|
+
* cannot depend on the platform-private contract package). Sync sites if
|
|
6
|
+
* these ever change: `backend/libs/fs-contract/src/contract.ts` (the
|
|
7
|
+
* platform-internal source of truth) and `oss/packages/host/src/frameworks/
|
|
8
|
+
* claude-options.ts:41-45` (same OSS-legality constraint, same literals).
|
|
9
|
+
*/
|
|
10
|
+
export declare const ENV_HOME_DIR = "GUUEY_HOME_DIR";
|
|
11
|
+
export declare const ENV_APP_DIR = "GUUEY_APP_DIR";
|
|
12
|
+
/** The user's durable memory layer root (reads GUUEY_HOME_DIR, Router-injected). */
|
|
13
|
+
export declare function homeDir(env?: NodeJS.ProcessEnv): string;
|
|
14
|
+
/** The app's shared read-only layer root (reads GUUEY_APP_DIR, Router-injected). */
|
|
15
|
+
export declare function appDir(env?: NodeJS.ProcessEnv): string;
|
|
16
|
+
/** The per-session working dir = the process cwd (the Router sets cwd = sessionDir). */
|
|
17
|
+
export declare function sessionDir(cwd?: () => string): string;
|
|
18
|
+
//# sourceMappingURL=roots.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"roots.d.ts","sourceRoot":"","sources":["../src/roots.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,eAAO,MAAM,YAAY,mBAAmB,CAAC;AAC7C,eAAO,MAAM,WAAW,kBAAkB,CAAC;AAE3C,oFAAoF;AACpF,wBAAgB,OAAO,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,MAAM,CAEpE;AAED,oFAAoF;AACpF,wBAAgB,MAAM,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,MAAM,CAEnE;AAED,wFAAwF;AACxF,wBAAgB,UAAU,CAAC,GAAG,GAAE,MAAM,MAAoB,GAAG,MAAM,CAElE"}
|
package/dist/roots.js
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Env-var names the Router injects so agent code reaches the home/app layers
|
|
3
|
+
* portably. This package's OWN copy (trivial string literals — not imported,
|
|
4
|
+
* so the published `@guuey/fs` package has zero non-devDependency deps and
|
|
5
|
+
* cannot depend on the platform-private contract package). Sync sites if
|
|
6
|
+
* these ever change: `backend/libs/fs-contract/src/contract.ts` (the
|
|
7
|
+
* platform-internal source of truth) and `oss/packages/host/src/frameworks/
|
|
8
|
+
* claude-options.ts:41-45` (same OSS-legality constraint, same literals).
|
|
9
|
+
*/
|
|
10
|
+
export const ENV_HOME_DIR = "GUUEY_HOME_DIR";
|
|
11
|
+
export const ENV_APP_DIR = "GUUEY_APP_DIR";
|
|
12
|
+
/** The user's durable memory layer root (reads GUUEY_HOME_DIR, Router-injected). */
|
|
13
|
+
export function homeDir(env = process.env) {
|
|
14
|
+
return requireRoot(env, ENV_HOME_DIR);
|
|
15
|
+
}
|
|
16
|
+
/** The app's shared read-only layer root (reads GUUEY_APP_DIR, Router-injected). */
|
|
17
|
+
export function appDir(env = process.env) {
|
|
18
|
+
return requireRoot(env, ENV_APP_DIR);
|
|
19
|
+
}
|
|
20
|
+
/** The per-session working dir = the process cwd (the Router sets cwd = sessionDir). */
|
|
21
|
+
export function sessionDir(cwd = process.cwd) {
|
|
22
|
+
return cwd();
|
|
23
|
+
}
|
|
24
|
+
function requireRoot(env, name) {
|
|
25
|
+
const value = env[name];
|
|
26
|
+
if (!value) {
|
|
27
|
+
throw new Error(`${name} is not set — the guuey agent runtime injects it. Run via \`guuey dev\` or the hosted runtime.`);
|
|
28
|
+
}
|
|
29
|
+
return value;
|
|
30
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@guuey/fs",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "GuueyFS dev-guidance helper — homeDir()/appDir()/sessionDir() read the three env-var/cwd paths the guuey Router injects into every hosted agent. No wrapper API: plain node:fs on the returned paths IS the contract.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"main": "dist/index.js",
|
|
8
|
+
"types": "dist/index.d.ts",
|
|
9
|
+
"files": [
|
|
10
|
+
"dist",
|
|
11
|
+
"README.md"
|
|
12
|
+
],
|
|
13
|
+
"exports": {
|
|
14
|
+
".": {
|
|
15
|
+
"types": "./dist/index.d.ts",
|
|
16
|
+
"import": "./dist/index.js",
|
|
17
|
+
"default": "./dist/index.js"
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
"devDependencies": {
|
|
21
|
+
"@types/node": "^24.0.0",
|
|
22
|
+
"typescript": "^5.0.0",
|
|
23
|
+
"vitest": "^3.0.0"
|
|
24
|
+
},
|
|
25
|
+
"publishConfig": {
|
|
26
|
+
"access": "public"
|
|
27
|
+
},
|
|
28
|
+
"keywords": [
|
|
29
|
+
"guuey",
|
|
30
|
+
"filesystem",
|
|
31
|
+
"vfs",
|
|
32
|
+
"layers",
|
|
33
|
+
"agent"
|
|
34
|
+
],
|
|
35
|
+
"repository": {
|
|
36
|
+
"type": "git",
|
|
37
|
+
"url": "git+https://github.com/withguuey/guuey-sdks.git",
|
|
38
|
+
"directory": "packages/fs"
|
|
39
|
+
},
|
|
40
|
+
"homepage": "https://guuey.com",
|
|
41
|
+
"bugs": {
|
|
42
|
+
"url": "https://github.com/loqu-co/guuey/issues"
|
|
43
|
+
},
|
|
44
|
+
"scripts": {
|
|
45
|
+
"build": "tsc -p tsconfig.build.json",
|
|
46
|
+
"dev": "tsc --watch",
|
|
47
|
+
"typecheck": "tsc --noEmit",
|
|
48
|
+
"test": "vitest run",
|
|
49
|
+
"test:watch": "vitest"
|
|
50
|
+
}
|
|
51
|
+
}
|