@the-40-thieves/obsidian-tc-shared 0.0.1 → 1.0.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.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"result.js","sourceRoot":"","sources":["../src/result.ts"],"names":[],"mappings":""}
@@ -0,0 +1,37 @@
1
+ import { z } from "zod";
2
+ /** Vault registry id: lowercase slug. */
3
+ export declare const VaultId: z.ZodString;
4
+ /**
5
+ * Vault-relative path. Rejects absolute paths (POSIX and Windows drive paths)
6
+ * and any ".." segment. Backslashes are tolerated on input and normalized by
7
+ * the resolver; the byte-level guard stays conservative per G2.1.
8
+ */
9
+ export declare const VaultPath: z.ZodEffects<z.ZodEffects<z.ZodString, string, string>, string, string>;
10
+ /** 32-char hex HITL elicit token (matches issueElicitToken: randomBytes(16).hex). */
11
+ export declare const ElicitToken: z.ZodString;
12
+ /** Cursor pagination inputs (G2.1 convention). */
13
+ export declare const Pagination: z.ZodObject<{
14
+ limit: z.ZodOptional<z.ZodNumber>;
15
+ cursor: z.ZodOptional<z.ZodString>;
16
+ }, "strip", z.ZodTypeAny, {
17
+ limit?: number | undefined;
18
+ cursor?: string | undefined;
19
+ }, {
20
+ limit?: number | undefined;
21
+ cursor?: string | undefined;
22
+ }>;
23
+ export type PaginationInput = z.infer<typeof Pagination>;
24
+ /** Shared write options. `idempotency_key` is accepted as a forward-compat
25
+ * surface in M1 (replay lands with the Policy layer in a later milestone). */
26
+ export declare const WriteOptions: z.ZodObject<{
27
+ idempotency_key: z.ZodOptional<z.ZodString>;
28
+ create_dirs: z.ZodDefault<z.ZodBoolean>;
29
+ }, "strip", z.ZodTypeAny, {
30
+ create_dirs: boolean;
31
+ idempotency_key?: string | undefined;
32
+ }, {
33
+ idempotency_key?: string | undefined;
34
+ create_dirs?: boolean | undefined;
35
+ }>;
36
+ export type WriteOptionsInput = z.infer<typeof WriteOptions>;
37
+ //# sourceMappingURL=primitives.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"primitives.d.ts","sourceRoot":"","sources":["../../src/schemas/primitives.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,yCAAyC;AACzC,eAAO,MAAM,OAAO,aAI0C,CAAC;AAE/D;;;;GAIG;AACH,eAAO,MAAM,SAAS,yEAQnB,CAAC;AAEJ,qFAAqF;AACrF,eAAO,MAAM,WAAW,aAA+D,CAAC;AAExF,kDAAkD;AAClD,eAAO,MAAM,UAAU;;;;;;;;;EAGrB,CAAC;AACH,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,UAAU,CAAC,CAAC;AAEzD;+EAC+E;AAC/E,eAAO,MAAM,YAAY;;;;;;;;;EAGvB,CAAC;AACH,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,YAAY,CAAC,CAAC"}
@@ -0,0 +1,36 @@
1
+ // Shared Zod primitives for the tool surface (G2.1 "Standard primitives").
2
+ // Reused across every vault-touching tool so path-safety and pagination are
3
+ // uniform. The traversal guard here is defense-in-depth; the filesystem
4
+ // resolver (packages/server/src/vault/paths.ts) re-checks real-path containment.
5
+ import { z } from "zod";
6
+ /** Vault registry id: lowercase slug. */
7
+ export const VaultId = z
8
+ .string()
9
+ .min(1)
10
+ .max(64)
11
+ .regex(/^[a-z0-9_-]+$/, "vault id must be a lowercase slug");
12
+ /**
13
+ * Vault-relative path. Rejects absolute paths (POSIX and Windows drive paths)
14
+ * and any ".." segment. Backslashes are tolerated on input and normalized by
15
+ * the resolver; the byte-level guard stays conservative per G2.1.
16
+ */
17
+ export const VaultPath = z
18
+ .string()
19
+ .min(1)
20
+ .max(1024)
21
+ .refine((p) => !p.includes(".."), "path traversal rejected")
22
+ .refine((p) => !p.startsWith("/") && !p.startsWith("\\") && !/^[A-Za-z]:[\\/]/.test(p), "absolute paths rejected");
23
+ /** 32-char hex HITL elicit token (matches issueElicitToken: randomBytes(16).hex). */
24
+ export const ElicitToken = z.string().regex(/^[a-f0-9]{32}$/, "malformed elicit token");
25
+ /** Cursor pagination inputs (G2.1 convention). */
26
+ export const Pagination = z.object({
27
+ limit: z.number().int().positive().max(1000).optional(),
28
+ cursor: z.string().optional(),
29
+ });
30
+ /** Shared write options. `idempotency_key` is accepted as a forward-compat
31
+ * surface in M1 (replay lands with the Policy layer in a later milestone). */
32
+ export const WriteOptions = z.object({
33
+ idempotency_key: z.string().min(1).max(128).optional(),
34
+ create_dirs: z.boolean().default(true),
35
+ });
36
+ //# sourceMappingURL=primitives.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"primitives.js","sourceRoot":"","sources":["../../src/schemas/primitives.ts"],"names":[],"mappings":"AAAA,2EAA2E;AAC3E,4EAA4E;AAC5E,wEAAwE;AACxE,iFAAiF;AACjF,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,yCAAyC;AACzC,MAAM,CAAC,MAAM,OAAO,GAAG,CAAC;KACrB,MAAM,EAAE;KACR,GAAG,CAAC,CAAC,CAAC;KACN,GAAG,CAAC,EAAE,CAAC;KACP,KAAK,CAAC,eAAe,EAAE,mCAAmC,CAAC,CAAC;AAE/D;;;;GAIG;AACH,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC;KACvB,MAAM,EAAE;KACR,GAAG,CAAC,CAAC,CAAC;KACN,GAAG,CAAC,IAAI,CAAC;KACT,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,yBAAyB,CAAC;KAC3D,MAAM,CACL,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC,CAAC,EAC9E,yBAAyB,CAC1B,CAAC;AAEJ,qFAAqF;AACrF,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,gBAAgB,EAAE,wBAAwB,CAAC,CAAC;AAExF,kDAAkD;AAClD,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,CAAC,MAAM,CAAC;IACjC,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE;IACvD,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;CAC9B,CAAC,CAAC;AAGH;+EAC+E;AAC/E,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,CAAC,MAAM,CAAC;IACnC,eAAe,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE;IACtD,WAAW,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC;CACvC,CAAC,CAAC"}
@@ -0,0 +1,16 @@
1
+ export declare const SCOPE_FAMILIES: readonly ["read", "write", "delete", "execute", "admin", "bulk"];
2
+ export type ScopeFamily = (typeof SCOPE_FAMILIES)[number];
3
+ export type Scope = string;
4
+ export declare const HITL_FLOOR_SCOPES: ReadonlySet<Scope>;
5
+ export declare const HITL_FLOOR_FAMILIES: readonly string[];
6
+ export declare function parseScope(s: Scope): {
7
+ family: string;
8
+ resource: string;
9
+ };
10
+ export declare function grantsScope(granted: Iterable<Scope>, required: Scope): boolean;
11
+ export declare function grantsAll(granted: Iterable<Scope>, required: readonly Scope[]): boolean;
12
+ export declare function scopeRequiresHitl(scope: Scope): boolean;
13
+ export declare const MUTATING_FAMILIES: readonly string[];
14
+ export declare function isMutatingScope(scope: Scope): boolean;
15
+ export declare function scopeClassOf(requiredScopes: readonly Scope[]): string;
16
+ //# sourceMappingURL=scopes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scopes.d.ts","sourceRoot":"","sources":["../src/scopes.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,cAAc,kEAAmE,CAAC;AAC/F,MAAM,MAAM,WAAW,GAAG,CAAC,OAAO,cAAc,CAAC,CAAC,MAAM,CAAC,CAAC;AAC1D,MAAM,MAAM,KAAK,GAAG,MAAM,CAAC;AAG3B,eAAO,MAAM,iBAAiB,EAAE,WAAW,CAAC,KAAK,CAG/C,CAAC;AAGH,eAAO,MAAM,mBAAmB,EAAE,SAAS,MAAM,EAAwB,CAAC;AAE1E,wBAAgB,UAAU,CAAC,CAAC,EAAE,KAAK,GAAG;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAKzE;AAGD,wBAAgB,WAAW,CAAC,OAAO,EAAE,QAAQ,CAAC,KAAK,CAAC,EAAE,QAAQ,EAAE,KAAK,GAAG,OAAO,CAS9E;AAGD,wBAAgB,SAAS,CAAC,OAAO,EAAE,QAAQ,CAAC,KAAK,CAAC,EAAE,QAAQ,EAAE,SAAS,KAAK,EAAE,GAAG,OAAO,CAGvF;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,KAAK,GAAG,OAAO,CAGvD;AAGD,eAAO,MAAM,iBAAiB,EAAE,SAAS,MAAM,EAA2C,CAAC;AAE3F,wBAAgB,eAAe,CAAC,KAAK,EAAE,KAAK,GAAG,OAAO,CAErD;AAUD,wBAAgB,YAAY,CAAC,cAAc,EAAE,SAAS,KAAK,EAAE,GAAG,MAAM,CAIrE"}
package/dist/scopes.js ADDED
@@ -0,0 +1,60 @@
1
+ export const SCOPE_FAMILIES = ["read", "write", "delete", "execute", "admin", "bulk"];
2
+ // Scopes that always require a HITL elicit confirmation (G2.4 A.3 hardcoded floors).
3
+ export const HITL_FLOOR_SCOPES = new Set([
4
+ "admin:auth",
5
+ "write:templater",
6
+ ]);
7
+ // Families where every member is a HITL floor.
8
+ export const HITL_FLOOR_FAMILIES = ["execute", "bulk"];
9
+ export function parseScope(s) {
10
+ if (s === "*")
11
+ return { family: "*", resource: "*" };
12
+ const i = s.indexOf(":");
13
+ if (i < 0)
14
+ return { family: s, resource: "*" };
15
+ return { family: s.slice(0, i), resource: s.slice(i + 1) };
16
+ }
17
+ // Does the granted set satisfy one required scope, honoring family/global wildcards?
18
+ export function grantsScope(granted, required) {
19
+ const req = parseScope(required);
20
+ for (const g of granted) {
21
+ if (g === "*")
22
+ return true;
23
+ const gp = parseScope(g);
24
+ if (gp.family !== "*" && gp.family !== req.family)
25
+ continue;
26
+ if (gp.resource === "*" || gp.resource === req.resource)
27
+ return true;
28
+ }
29
+ return false;
30
+ }
31
+ // AND across all required scopes.
32
+ export function grantsAll(granted, required) {
33
+ const set = granted instanceof Set ? granted : new Set(granted);
34
+ return required.every((r) => grantsScope(set, r));
35
+ }
36
+ export function scopeRequiresHitl(scope) {
37
+ if (HITL_FLOOR_SCOPES.has(scope))
38
+ return true;
39
+ return HITL_FLOOR_FAMILIES.includes(parseScope(scope).family);
40
+ }
41
+ // Scope families that mutate the vault; denied when an ACL is read-only.
42
+ export const MUTATING_FAMILIES = ["write", "delete", "bulk", "execute"];
43
+ export function isMutatingScope(scope) {
44
+ return MUTATING_FAMILIES.includes(parseScope(scope).family);
45
+ }
46
+ // Scope-class precedence for the dispatch rate-limiter gate (THE-210) and the `scope_class`
47
+ // metric label (G2.4). A tool's governing class is the most operationally significant family
48
+ // among its required scopes: a bulk_* tool (write:notes + bulk:notes) is governed by `bulk`,
49
+ // an execute tool by `execute`, an admin tool by `admin`, and so on. Tools whose families
50
+ // carry no throttle tier (e.g. a delete-only tool) resolve to their first declared family and
51
+ // are treated as unlimited by the limiter (an unknown tier is never throttled).
52
+ const SCOPE_CLASS_PRECEDENCE = ["bulk", "execute", "admin", "write", "read"];
53
+ export function scopeClassOf(requiredScopes) {
54
+ const families = new Set(requiredScopes.map((s) => parseScope(s).family));
55
+ for (const cls of SCOPE_CLASS_PRECEDENCE)
56
+ if (families.has(cls))
57
+ return cls;
58
+ return requiredScopes[0] ? parseScope(requiredScopes[0]).family : "unknown";
59
+ }
60
+ //# sourceMappingURL=scopes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scopes.js","sourceRoot":"","sources":["../src/scopes.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,18 +1,34 @@
1
1
  {
2
2
  "name": "@the-40-thieves/obsidian-tc-shared",
3
- "version": "0.0.1",
4
- "description": "Reserved. Shared TypeScript types and Zod schemas for obsidian-tc. v1.0 ships Q3 2026.",
3
+ "version": "1.0.1",
4
+ "description": "Shared Zod schemas and types for obsidian-tc",
5
5
  "license": "Apache-2.0",
6
- "author": "Suavecito (Mohammed Islam)",
7
- "homepage": "https://github.com/suavecito585/obsidian-tc",
6
+ "type": "module",
7
+ "main": "./dist/index.js",
8
+ "types": "./dist/index.d.ts",
9
+ "files": ["dist", "README.md", "LICENSE"],
10
+ "scripts": {
11
+ "build": "tsc",
12
+ "typecheck": "tsc --noEmit",
13
+ "test": "vitest run --passWithNoTests"
14
+ },
15
+ "dependencies": {
16
+ "zod": "^3.23.0"
17
+ },
18
+ "devDependencies": {
19
+ "typescript": "^5.7.0",
20
+ "vitest": "^2.1.0"
21
+ },
8
22
  "repository": {
9
23
  "type": "git",
10
- "url": "git+https://github.com/suavecito585/obsidian-tc.git"
11
- },
12
- "bugs": {
13
- "url": "https://github.com/suavecito585/obsidian-tc/issues"
24
+ "url": "https://github.com/The-40-Thieves/obsidian-tc.git",
25
+ "directory": "packages/shared"
14
26
  },
15
- "keywords": ["obsidian", "mcp", "model-context-protocol", "ai", "knowledge-management", "second-brain"],
16
- "publishConfig": { "access": "public" },
17
- "private": false
27
+ "exports": {
28
+ ".": {
29
+ "types": "./dist/index.d.ts",
30
+ "import": "./dist/index.js"
31
+ },
32
+ "./package.json": "./package.json"
33
+ }
18
34
  }