@ibgib/space-gib 0.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.
- package/CHANGELOG.md +31 -0
- package/Dockerfile +14 -0
- package/IMPLEMENTATION.md +484 -0
- package/README.md +46 -0
- package/dist/client/bootstrap.mjs +58 -0
- package/dist/client/bootstrap.mjs.map +7 -0
- package/dist/client/chunk-CT47Z5WU.mjs +21 -0
- package/dist/client/chunk-CT47Z5WU.mjs.map +7 -0
- package/dist/client/chunk-RHEDTRKF.mjs +235 -0
- package/dist/client/chunk-RHEDTRKF.mjs.map +7 -0
- package/dist/client/index.html +147 -0
- package/dist/client/index.mjs +2 -0
- package/dist/client/index.mjs.map +7 -0
- package/dist/client/script.mjs +2 -0
- package/dist/client/script.mjs.map +7 -0
- package/dist/client/style.css +605 -0
- package/dist/respec-gib.node.mjs +5 -0
- package/dist/server/server.mjs +20157 -0
- package/dist/server/server.mjs.map +7 -0
- package/generate-version-file.js +35 -0
- package/package.json +27 -0
- package/src/client/AUTO-GENERATED-version.mts +11 -0
- package/src/client/README.md +19 -0
- package/src/client/api/function-infos.web.mts +38 -0
- package/src/client/api/space-gib-api-bridge.mts +85 -0
- package/src/client/bootstrap.mts +49 -0
- package/src/client/components/keystone-creator/keystone-creator.css +139 -0
- package/src/client/components/keystone-creator/keystone-creator.html +26 -0
- package/src/client/components/keystone-creator/keystone-creator.mts +229 -0
- package/src/client/constants.mts +76 -0
- package/src/client/custom.d.ts +11 -0
- package/src/client/dev-tools.mts +540 -0
- package/src/client/helpers.web.mts +178 -0
- package/src/client/index.html +147 -0
- package/src/client/index.mts +59 -0
- package/src/client/script.mts +13 -0
- package/src/client/style.css +605 -0
- package/src/client/types.mts +85 -0
- package/src/client/ui/shell/space-gib-shell-constants.mts +24 -0
- package/src/client/ui/shell/space-gib-shell-service.mts +233 -0
- package/src/client/ui/shell/space-gib-shell-types.mts +5 -0
- package/src/client/witness/app/space-gib/space-gib-app-v1.mts +160 -0
- package/src/client/witness/app/space-gib/space-gib-constants.mts +38 -0
- package/src/client/witness/app/space-gib/space-gib-helper.mts +72 -0
- package/src/client/witness/app/space-gib/space-gib-types.mts +47 -0
- package/src/common/keystone-policies.mts +159 -0
- package/src/respec-gib.node.mts +6 -0
- package/src/server/README.md +18 -0
- package/src/server/bootstrap-helper.mts +141 -0
- package/src/server/bootstrap-helper.respec.mts +100 -0
- package/src/server/metaspace-nodeindexedspace/metaspace-nodeindexedspace.mts +85 -0
- package/src/server/path-constants.mts +89 -0
- package/src/server/path-helper.mts +101 -0
- package/src/server/path-helper.respec.mts +94 -0
- package/src/server/serve-gib/CHANGELOG.md +29 -0
- package/src/server/serve-gib/README.md +34 -0
- package/src/server/serve-gib/constants.mts +1 -0
- package/src/server/serve-gib/handlers/api/debug/ws-echo.handler.mts +104 -0
- package/src/server/serve-gib/handlers/api/health.handler.mts +23 -0
- package/src/server/serve-gib/handlers/api/health.respec.mts +51 -0
- package/src/server/serve-gib/handlers/api/ibgib/ibgib-handler-types.mts +49 -0
- package/src/server/serve-gib/handlers/api/ibgib/ibgib.handler.mts +176 -0
- package/src/server/serve-gib/handlers/api/keystone/keystone-evolve.handler.mts +261 -0
- package/src/server/serve-gib/handlers/api/keystone/keystone-genesis.handler.mts +146 -0
- package/src/server/serve-gib/handlers/api/keystone/keystone-get.handler.mts +198 -0
- package/src/server/serve-gib/handlers/api/keystone/keystone-get.respec.mts +107 -0
- package/src/server/serve-gib/handlers/api/keystone/keystone-handler-types.mts +29 -0
- package/src/server/serve-gib/handlers/api/keystone/keystone-post.handler.mts +70 -0
- package/src/server/serve-gib/handlers/api/keystone/keystone-post.respec.mts +130 -0
- package/src/server/serve-gib/handlers/error-handler.mts +36 -0
- package/src/server/serve-gib/handlers/handler-base.mts +383 -0
- package/src/server/serve-gib/handlers/static-handler.mts +82 -0
- package/src/server/serve-gib/handlers/ws/sync-upgrade.handler.mts +498 -0
- package/src/server/serve-gib/handlers/ws/ws-helper.mts +111 -0
- package/src/server/serve-gib/handlers/ws/ws-types.mts +53 -0
- package/src/server/serve-gib/serve-gib-helpers.mts +32 -0
- package/src/server/serve-gib/serve-gib-v1.mts +172 -0
- package/src/server/serve-gib/serve-gib.respec.mts +90 -0
- package/src/server/serve-gib/types.mts +102 -0
- package/src/server/server-constants.mts +2 -0
- package/src/server/server.mts +96 -0
- package/tsconfig.json +29 -0
- package/tsconfig.server.json +29 -0
- package/tsconfig.test.json +27 -0
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* generate-version-file.js
|
|
3
|
+
*
|
|
4
|
+
* Writes `src/client/AUTO-GENERATED-version.mts` from the current
|
|
5
|
+
* package.json version. Called by the build orchestrator (build-space-gib.mts)
|
|
6
|
+
* during `createDynamicFiles()`.
|
|
7
|
+
*
|
|
8
|
+
* Run: node generate-version-file.js
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import * as pathUtils from 'path';
|
|
12
|
+
import { writeFile } from 'node:fs/promises';
|
|
13
|
+
|
|
14
|
+
import packageJson from './package.json' with { type: 'json' };
|
|
15
|
+
|
|
16
|
+
const lc = `[${import.meta.url}]`;
|
|
17
|
+
console.log(`${lc} starting...`);
|
|
18
|
+
|
|
19
|
+
const filePath = pathUtils.resolve('./src/client/AUTO-GENERATED-version.mts');
|
|
20
|
+
|
|
21
|
+
const contents = `/**
|
|
22
|
+
* @module auto-generated-version
|
|
23
|
+
*
|
|
24
|
+
* CHANGES TO THIS FILE WILL NOT BE SAVED.
|
|
25
|
+
* This is automatically updated during the build process.
|
|
26
|
+
*/
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Version of space-gib, auto-updated by the build process.
|
|
30
|
+
*/
|
|
31
|
+
export const AUTO_GENERATED_VERSION = '${packageJson.version}';
|
|
32
|
+
`;
|
|
33
|
+
|
|
34
|
+
await writeFile(filePath, contents, { encoding: 'utf8' });
|
|
35
|
+
console.log(`${lc} complete. wrote version: ${packageJson.version}`);
|
package/package.json
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@ibgib/space-gib",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"description": "ibgib storage and provider service — SaaS at ibgib.space",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"clean": "node ../../node_modules/@ibgib/helper-gib/tools/clean.js ./dist",
|
|
8
|
+
"prepare:publish": "npm version patch && node ../../build/dist/concrete-build/build-space-gib.mjs --prod && npm run pack",
|
|
9
|
+
"pack": "npm pack --pack-destination=\"./published\"",
|
|
10
|
+
"pack:dryrun": "npm pack --dry-run",
|
|
11
|
+
"test:node:nobuild": "node dist/respec-gib.node.mjs --inspect",
|
|
12
|
+
"build:test": "tsc -p tsconfig.test.json"
|
|
13
|
+
},
|
|
14
|
+
"dependencies": {
|
|
15
|
+
"@ibgib/core-gib": "*",
|
|
16
|
+
"@ibgib/helper-gib": "*",
|
|
17
|
+
"@ibgib/ts-gib": "*",
|
|
18
|
+
"@ibgib/web-gib": "*",
|
|
19
|
+
"@ibgib/node-gib": "*"
|
|
20
|
+
},
|
|
21
|
+
"engines": {
|
|
22
|
+
"node": ">=20.0.0"
|
|
23
|
+
},
|
|
24
|
+
"publishConfig": {
|
|
25
|
+
"access": "public"
|
|
26
|
+
}
|
|
27
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module auto-generated-version
|
|
3
|
+
*
|
|
4
|
+
* CHANGES TO THIS FILE WILL NOT BE SAVED.
|
|
5
|
+
* This is automatically updated during the build process.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Version of space-gib, auto-updated by the build process.
|
|
10
|
+
*/
|
|
11
|
+
export const AUTO_GENERATED_VERSION = '0.0.1';
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# Space-Gib Client
|
|
2
|
+
|
|
3
|
+
This directory contains the browser single-page application (SPA) frontend for `space-gib`.
|
|
4
|
+
|
|
5
|
+
## Architecture
|
|
6
|
+
|
|
7
|
+
* **Framework**: Built on top of `web-gib`, utilizing IbGib's vanilla web component architecture (no React/Vue/Angular).
|
|
8
|
+
* **Styling**: Vanilla CSS utilizing dark glassmorphism and modern variables.
|
|
9
|
+
* **State**: Interacts with the backend via a REST API bridge (`SpaceGibApiBridge`) and directly connects to the Node.js WebSocket endpoint for live peer synchronization.
|
|
10
|
+
* **Build**: Bundled by `esbuild` using the monorepo's shared `build-space-gib.mts` script.
|
|
11
|
+
|
|
12
|
+
## Core Structure
|
|
13
|
+
* `index.html` & `style.css`: The static entry points.
|
|
14
|
+
* `index.mts`: The JS entry point that initializes the global context and bootstraps the SPA.
|
|
15
|
+
* `components/`: Contains dynamic UI components (`keystone-creator`, etc.).
|
|
16
|
+
* `api/`: REST and WebSocket API communication layers.
|
|
17
|
+
* `dev-tools.mts`: Utilities for rendering the local development test panel.
|
|
18
|
+
|
|
19
|
+
For local development commands, please refer to the [Root space-gib README](../../README.md).
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module function-infos.web.mts
|
|
3
|
+
*
|
|
4
|
+
* Web app-specific API function infos for space-gib.
|
|
5
|
+
* Initially minimal — grows as the app adds agent capabilities.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { extractErrorMsg } from "@ibgib/helper-gib/dist/helpers/utils-helper.mjs";
|
|
9
|
+
import { registerFunctionInfos } from "@ibgib/web-gib/dist/api/api-index.mjs";
|
|
10
|
+
import { IbGibAPIFunctionInfos } from "@ibgib/web-gib/dist/api/commands/ibgib/ibgib-index.mjs";
|
|
11
|
+
import { ChatAPIFunctionInfos } from "@ibgib/web-gib/dist/api/commands/chat/chat-index.mjs";
|
|
12
|
+
import { TextAPIFunctionInfos } from "@ibgib/web-gib/dist/api/commands/text/text-index.mjs";
|
|
13
|
+
|
|
14
|
+
import { GLOBAL_LOG_A_LOT } from "../constants.mjs";
|
|
15
|
+
|
|
16
|
+
const logalot = GLOBAL_LOG_A_LOT;
|
|
17
|
+
|
|
18
|
+
const AllFunctionInfos_Web = new Map([
|
|
19
|
+
...ChatAPIFunctionInfos,
|
|
20
|
+
...TextAPIFunctionInfos,
|
|
21
|
+
...IbGibAPIFunctionInfos,
|
|
22
|
+
].map(x => [x.nameOrId, x]));
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Call once during bootstrap to register all available agent API functions.
|
|
26
|
+
*/
|
|
27
|
+
export function registerDeprecatedFunctionNamesAndFunctionInfos_Web(): void {
|
|
28
|
+
const lc = `[${registerDeprecatedFunctionNamesAndFunctionInfos_Web.name}]`;
|
|
29
|
+
try {
|
|
30
|
+
if (logalot) { console.log(`${lc} starting... (I: e6bad47eedd044beadadbd63361128ea)`); }
|
|
31
|
+
registerFunctionInfos({ functionInfos: AllFunctionInfos_Web });
|
|
32
|
+
} catch (error) {
|
|
33
|
+
console.error(`${lc} ${extractErrorMsg(error)}`);
|
|
34
|
+
throw error;
|
|
35
|
+
} finally {
|
|
36
|
+
if (logalot) { console.log(`${lc} complete.`); }
|
|
37
|
+
}
|
|
38
|
+
}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { extractErrorMsg } from "@ibgib/helper-gib/dist/helpers/utils-helper.mjs";
|
|
2
|
+
import { IbGib_V1 } from "@ibgib/ts-gib/dist/V1/types.mjs";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Handles communication with the SpaceGib REST API.
|
|
6
|
+
*/
|
|
7
|
+
export class SpaceGibApiBridge {
|
|
8
|
+
private lc: string = `[SpaceGibApiBridge]`;
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Posts a single genesis keystone ibgib to the server to create a new domain.
|
|
12
|
+
*
|
|
13
|
+
* @param keystoneIbGib The genesis keystone ibgib.
|
|
14
|
+
* @returns Promise resolving to the server response containing the addr.
|
|
15
|
+
*/
|
|
16
|
+
public async postGenesisKeystone(keystoneIbGib: IbGib_V1): Promise<{ success: boolean; message?: string; addr?: string }> {
|
|
17
|
+
const lc = `${this.lc}[${this.postGenesisKeystone.name}]`;
|
|
18
|
+
try {
|
|
19
|
+
console.log(`${lc} [NAG][ibgib-paradigm] posting genesis keystone...`);
|
|
20
|
+
|
|
21
|
+
const response = await fetch('/api/keystone/genesis', {
|
|
22
|
+
method: 'POST',
|
|
23
|
+
headers: {
|
|
24
|
+
'Content-Type': 'application/json',
|
|
25
|
+
},
|
|
26
|
+
body: JSON.stringify({ keystoneIbGib }),
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
const data = await response.json();
|
|
30
|
+
|
|
31
|
+
if (!response.ok) {
|
|
32
|
+
const errorMsg = data.message || data.error || 'Unknown error';
|
|
33
|
+
console.error(`${lc} [NAG][ibgib-paradigm] server rejected genesis keystone: ${errorMsg}`);
|
|
34
|
+
return { success: false, message: errorMsg, addr: data.addr };
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
console.log(`${lc} [NAG][ibgib-paradigm] genesis keystone posted successfully.`);
|
|
38
|
+
return { success: true, addr: data.addr };
|
|
39
|
+
|
|
40
|
+
} catch (error) {
|
|
41
|
+
const errorMsg = extractErrorMsg(error);
|
|
42
|
+
console.error(`${lc} [NAG][ibgib-paradigm] fetch error: ${errorMsg}`);
|
|
43
|
+
return { success: false, message: errorMsg };
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* PUTs an evolved domain keystone and any related ibgibs (e.g. S^Stjp) to the server.
|
|
49
|
+
*/
|
|
50
|
+
public async putEvolveKeystone(domainAddr: string, keystoneIbGib: IbGib_V1, relatedIbGibs: IbGib_V1[] = []): Promise<{ success: boolean; message?: string }> {
|
|
51
|
+
const lc = `${this.lc}[${this.putEvolveKeystone.name}]`;
|
|
52
|
+
try {
|
|
53
|
+
console.log(`${lc} posting evolved keystone...`);
|
|
54
|
+
|
|
55
|
+
// Note: encodeURIComponent safely encodes the `^` if needed, though our regex handles both
|
|
56
|
+
const url = `/api/keystone/evolve/${encodeURIComponent(domainAddr)}`;
|
|
57
|
+
const response = await fetch(url, {
|
|
58
|
+
method: 'PUT',
|
|
59
|
+
headers: {
|
|
60
|
+
'Content-Type': 'application/json',
|
|
61
|
+
},
|
|
62
|
+
body: JSON.stringify({ keystoneIbGib, relatedIbGibs }),
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
const data = await response.json();
|
|
66
|
+
|
|
67
|
+
if (!response.ok) {
|
|
68
|
+
const errorMsg = data.message || data.error || 'Unknown error';
|
|
69
|
+
console.error(`${lc} server rejected keystone evolution: ${errorMsg}`);
|
|
70
|
+
return { success: false, message: errorMsg };
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
console.log(`${lc} keystone evolution accepted by server.`);
|
|
74
|
+
return { success: true };
|
|
75
|
+
|
|
76
|
+
} catch (error) {
|
|
77
|
+
const errorMsg = extractErrorMsg(error);
|
|
78
|
+
console.error(`${lc} fetch error: ${errorMsg}`);
|
|
79
|
+
return { success: false, message: errorMsg };
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/** Singleton instance for the bridge. */
|
|
85
|
+
export const spaceGibApiBridge = new SpaceGibApiBridge();
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module bootstrap
|
|
3
|
+
*
|
|
4
|
+
* Startup code for ibgib-specific things: initializing the metaspace and
|
|
5
|
+
* starting the space-gib app.
|
|
6
|
+
*
|
|
7
|
+
* Called dynamically by index.mts AFTER initial page render, so the heavy
|
|
8
|
+
* ibgib import graph doesn't block first paint.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import { bootstrapIbGibApp } from "@ibgib/web-gib/dist/app-bootstrap/bootstrap.mjs";
|
|
12
|
+
|
|
13
|
+
import { APP_CONFIG, GLOBAL_LOG_A_LOT } from "./constants.mjs";
|
|
14
|
+
import { getIbGibGlobalThis_SpaceGib } from "./helpers.web.mjs";
|
|
15
|
+
import { SpaceGibApp_V1 } from "./witness/app/space-gib/space-gib-app-v1.mjs";
|
|
16
|
+
import { PARAM_INFOS } from "./witness/app/space-gib/space-gib-constants.mjs";
|
|
17
|
+
import {
|
|
18
|
+
DEFAULT_SPACE_GIB_APP_DATA_V1,
|
|
19
|
+
DEFAULT_SPACE_GIB_APP_REL8NS_V1,
|
|
20
|
+
} from "./witness/app/space-gib/space-gib-types.mjs";
|
|
21
|
+
import { AUTO_GENERATED_VERSION } from "./AUTO-GENERATED-version.mjs";
|
|
22
|
+
import { registerDeprecatedFunctionNamesAndFunctionInfos_Web } from "./api/function-infos.web.mjs";
|
|
23
|
+
|
|
24
|
+
import { getSpaceGibShellSvc } from "./ui/shell/space-gib-shell-service.mjs";
|
|
25
|
+
|
|
26
|
+
console.log(`[space-gib bootstrap] version: ${AUTO_GENERATED_VERSION}`);
|
|
27
|
+
|
|
28
|
+
// ---------------------------------------------------------------------------
|
|
29
|
+
// Main entry point
|
|
30
|
+
// ---------------------------------------------------------------------------
|
|
31
|
+
|
|
32
|
+
export async function bootstrapSpaceGibApp() {
|
|
33
|
+
await bootstrapIbGibApp({
|
|
34
|
+
config: APP_CONFIG,
|
|
35
|
+
getGlobalThis: getIbGibGlobalThis_SpaceGib,
|
|
36
|
+
AppClass: SpaceGibApp_V1,
|
|
37
|
+
defaultAppData: DEFAULT_SPACE_GIB_APP_DATA_V1,
|
|
38
|
+
paramInfos: PARAM_INFOS,
|
|
39
|
+
registerAgentFunctionInfos: registerDeprecatedFunctionNamesAndFunctionInfos_Web,
|
|
40
|
+
localSpaceNamePrefix: 'space_gib_',
|
|
41
|
+
|
|
42
|
+
onReady: async (app) => {
|
|
43
|
+
if (GLOBAL_LOG_A_LOT) { console.log(`[bootstrapSpaceGibApp] Engine ready. app: ${app?.ib}`); }
|
|
44
|
+
|
|
45
|
+
// Hand over control to the shell
|
|
46
|
+
await getSpaceGibShellSvc().onEngineReady();
|
|
47
|
+
},
|
|
48
|
+
});
|
|
49
|
+
}
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
:host {
|
|
2
|
+
display: block;
|
|
3
|
+
width: 100%;
|
|
4
|
+
max-width: 600px;
|
|
5
|
+
margin: 2rem auto;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
.component-container {
|
|
9
|
+
padding: 2rem;
|
|
10
|
+
background: var(--clr-bg-glass);
|
|
11
|
+
backdrop-filter: blur(16px);
|
|
12
|
+
border-radius: var(--radius-lg);
|
|
13
|
+
border: 1px solid var(--clr-border);
|
|
14
|
+
color: var(--clr-text-primary);
|
|
15
|
+
box-shadow: var(--shadow-card);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
h2 {
|
|
19
|
+
margin-top: 0;
|
|
20
|
+
font-size: 1.5rem;
|
|
21
|
+
color: var(--clr-accent);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
.content {
|
|
25
|
+
margin-top: 1.5rem;
|
|
26
|
+
display: flex;
|
|
27
|
+
flex-direction: column;
|
|
28
|
+
gap: 1.5rem;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
.action-row {
|
|
32
|
+
display: flex;
|
|
33
|
+
justify-content: center;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
.action-btn {
|
|
37
|
+
padding: 0.75rem 1.5rem;
|
|
38
|
+
background: var(--clr-accent);
|
|
39
|
+
color: var(--clr-bg-deep);
|
|
40
|
+
border: none;
|
|
41
|
+
border-radius: var(--radius-md);
|
|
42
|
+
font-weight: 600;
|
|
43
|
+
cursor: pointer;
|
|
44
|
+
transition: all var(--t-fast);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
.action-btn:hover {
|
|
48
|
+
background: #9fffa5;
|
|
49
|
+
transform: translateY(-1px);
|
|
50
|
+
box-shadow: 0 0 16px var(--clr-accent-glow);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
.input-group {
|
|
54
|
+
display: flex;
|
|
55
|
+
flex-direction: column;
|
|
56
|
+
gap: 0.5rem;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
.input-group label {
|
|
60
|
+
font-size: 0.85rem;
|
|
61
|
+
color: var(--clr-text-secondary);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
.secret-input {
|
|
65
|
+
padding: 0.75rem;
|
|
66
|
+
background: rgba(0, 0, 0, 0.2);
|
|
67
|
+
border: 1px solid var(--clr-border);
|
|
68
|
+
border-radius: var(--radius-sm);
|
|
69
|
+
color: var(--clr-text-primary);
|
|
70
|
+
font-family: var(--font-mono);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
.secret-input:focus {
|
|
74
|
+
outline: none;
|
|
75
|
+
border-color: var(--clr-accent);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
.status-area {
|
|
79
|
+
padding: 1rem;
|
|
80
|
+
border-radius: var(--radius-md);
|
|
81
|
+
background: rgba(255, 255, 255, 0.03);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
.status-area.hidden {
|
|
85
|
+
display: none;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
.status-msg {
|
|
89
|
+
margin: 0;
|
|
90
|
+
font-size: 0.9rem;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
.status-msg.info { color: var(--clr-text-secondary); }
|
|
94
|
+
.status-msg.success { color: var(--clr-accent); }
|
|
95
|
+
.status-msg.error { color: var(--clr-warn); }
|
|
96
|
+
|
|
97
|
+
.action-btn:disabled {
|
|
98
|
+
opacity: 0.5;
|
|
99
|
+
cursor: not-allowed;
|
|
100
|
+
background: var(--clr-border);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
.result-area {
|
|
104
|
+
padding: 1.5rem;
|
|
105
|
+
background: rgba(255, 255, 255, 0.03);
|
|
106
|
+
border: 1px solid var(--clr-border);
|
|
107
|
+
border-radius: var(--radius-md);
|
|
108
|
+
display: flex;
|
|
109
|
+
flex-direction: column;
|
|
110
|
+
gap: 0.75rem;
|
|
111
|
+
transition: opacity var(--t-med);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
.result-area.collapsed {
|
|
115
|
+
display: none;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
.address-label {
|
|
119
|
+
font-size: 0.8rem;
|
|
120
|
+
color: var(--clr-text-secondary);
|
|
121
|
+
margin: 0;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
.keystone-addr {
|
|
125
|
+
display: block;
|
|
126
|
+
padding: 0.75rem;
|
|
127
|
+
background: rgba(0, 0, 0, 0.3);
|
|
128
|
+
border-radius: var(--radius-sm);
|
|
129
|
+
font-family: var(--font-mono);
|
|
130
|
+
font-size: 0.85rem;
|
|
131
|
+
word-break: break-all;
|
|
132
|
+
color: var(--clr-accent);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
.warning {
|
|
136
|
+
font-size: 0.8rem;
|
|
137
|
+
color: var(--clr-warn);
|
|
138
|
+
margin: 0.5rem 0 0;
|
|
139
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
<div id="container" class="component-container">
|
|
2
|
+
<h2 id="title">Keystone Creator</h2>
|
|
3
|
+
<div class="content">
|
|
4
|
+
<p>This will generate a new root keystone (identity) for your space.</p>
|
|
5
|
+
|
|
6
|
+
<div class="input-group">
|
|
7
|
+
<label for="input-secret">Master Secret (Keep this private!)</label>
|
|
8
|
+
<input type="password" id="input-secret" placeholder="Enter your master secret..." class="secret-input">
|
|
9
|
+
</div>
|
|
10
|
+
|
|
11
|
+
<div class="action-row">
|
|
12
|
+
<button id="btn-generate" class="action-btn">Generate Identity Keystone</button>
|
|
13
|
+
</div>
|
|
14
|
+
|
|
15
|
+
<div id="status-area" class="status-area hidden">
|
|
16
|
+
<p id="status-text" class="status-msg"></p>
|
|
17
|
+
</div>
|
|
18
|
+
|
|
19
|
+
<div id="result-area" class="result-area collapsed">
|
|
20
|
+
<h3>New Keystone Generated!</h3>
|
|
21
|
+
<p class="address-label">Address:</p>
|
|
22
|
+
<code id="keystone-addr" class="keystone-addr"></code>
|
|
23
|
+
<p class="warning">⚠️ Store this address safely. It is your root identity for this space.</p>
|
|
24
|
+
</div>
|
|
25
|
+
</div>
|
|
26
|
+
</div>
|
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
import thisCss from "./keystone-creator.css";
|
|
2
|
+
import thisHtml from "./keystone-creator.html";
|
|
3
|
+
|
|
4
|
+
import { extractErrorMsg } from "@ibgib/helper-gib/dist/helpers/utils-helper.mjs";
|
|
5
|
+
import { HashAlgorithm } from "@ibgib/helper-gib/dist/helpers/utils-helper.mjs";
|
|
6
|
+
import { IbGibAddr } from "@ibgib/ts-gib/dist/types.mjs";
|
|
7
|
+
import { IbGib_V1 } from "@ibgib/ts-gib/dist/V1/types.mjs";
|
|
8
|
+
import { getIbGibAddr } from "@ibgib/ts-gib/dist/helper.mjs";
|
|
9
|
+
import { KeystoneService_V1 } from "@ibgib/core-gib/dist/keystone/keystone-service-v1.mjs";
|
|
10
|
+
import {
|
|
11
|
+
KeystonePoolConfig, KeystoneChallengeType, KeystoneReplenishStrategy
|
|
12
|
+
} from "@ibgib/core-gib/dist/keystone/keystone-types.mjs";
|
|
13
|
+
import { getGlobalMetaspace_waitIfNeeded } from "@ibgib/web-gib/dist/helpers.mjs";
|
|
14
|
+
import {
|
|
15
|
+
IbGibDynamicComponentMetaBase, IbGibDynamicComponentInstanceBase,
|
|
16
|
+
} from "@ibgib/web-gib/dist/ui/component/ibgib-dynamic-component-bases.mjs";
|
|
17
|
+
import {
|
|
18
|
+
ElementsBase, IbGibDynamicComponentInstance,
|
|
19
|
+
IbGibDynamicComponentInstanceInitOpts,
|
|
20
|
+
} from "@ibgib/web-gib/dist/ui/component/component-types.mjs";
|
|
21
|
+
|
|
22
|
+
import { getComponentCtorArg } from "../../helpers.web.mjs";
|
|
23
|
+
import { spaceGibApiBridge } from "../../api/space-gib-api-bridge.mjs";
|
|
24
|
+
import { devLog } from "../../dev-tools.mjs";
|
|
25
|
+
|
|
26
|
+
export const KEYSTONE_CREATOR_COMPONENT_NAME = 'space-gib-keystone-creator';
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Metadata for the Keystone Creator component.
|
|
30
|
+
*/
|
|
31
|
+
export class KeystoneCreatorComponentMeta extends IbGibDynamicComponentMetaBase {
|
|
32
|
+
protected lc: string = `[KeystoneCreatorComponentMeta]`;
|
|
33
|
+
|
|
34
|
+
routeRegExp?: RegExp = new RegExp(`^${KEYSTONE_CREATOR_COMPONENT_NAME}$`);
|
|
35
|
+
componentName = KEYSTONE_CREATOR_COMPONENT_NAME;
|
|
36
|
+
|
|
37
|
+
constructor() {
|
|
38
|
+
super(getComponentCtorArg());
|
|
39
|
+
if (!customElements.get(this.componentName)) {
|
|
40
|
+
customElements.define(this.componentName, KeystoneCreatorComponentInstance);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
async createInstance({
|
|
45
|
+
path,
|
|
46
|
+
ibGibAddr
|
|
47
|
+
}: {
|
|
48
|
+
path: string;
|
|
49
|
+
ibGibAddr: IbGibAddr;
|
|
50
|
+
}): Promise<IbGibDynamicComponentInstance> {
|
|
51
|
+
const lc = `${this.lc}[${this.createInstance.name}]`;
|
|
52
|
+
const component = document.createElement(this.componentName) as KeystoneCreatorComponentInstance;
|
|
53
|
+
await component.initialize({
|
|
54
|
+
ibGibAddr,
|
|
55
|
+
meta: this,
|
|
56
|
+
html: thisHtml,
|
|
57
|
+
css: [thisCss],
|
|
58
|
+
});
|
|
59
|
+
return component;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* References to DOM elements within the component's shadow root.
|
|
65
|
+
*/
|
|
66
|
+
interface KeystoneCreatorElements extends ElementsBase {
|
|
67
|
+
containerEl: HTMLDivElement;
|
|
68
|
+
titleEl: HTMLHeadingElement;
|
|
69
|
+
btnGenerateEl: HTMLButtonElement;
|
|
70
|
+
resultAreaEl: HTMLDivElement;
|
|
71
|
+
keystoneAddrEl: HTMLElement;
|
|
72
|
+
inputSecret: HTMLInputElement;
|
|
73
|
+
statusArea: HTMLDivElement;
|
|
74
|
+
statusText: HTMLParagraphElement;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Concrete implementation of the Keystone Creator component.
|
|
79
|
+
*/
|
|
80
|
+
export class KeystoneCreatorComponentInstance
|
|
81
|
+
extends IbGibDynamicComponentInstanceBase<IbGib_V1, KeystoneCreatorElements>
|
|
82
|
+
implements IbGibDynamicComponentInstance<IbGib_V1, KeystoneCreatorElements> {
|
|
83
|
+
|
|
84
|
+
protected lc: string = `[KeystoneCreatorComponentInstance]`;
|
|
85
|
+
|
|
86
|
+
constructor() {
|
|
87
|
+
super();
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
override async initialize(opts: IbGibDynamicComponentInstanceInitOpts): Promise<void> {
|
|
91
|
+
await super.initialize(opts);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
override async created(): Promise<void> {
|
|
95
|
+
this.elements = {} as KeystoneCreatorElements;
|
|
96
|
+
|
|
97
|
+
this.elements.containerEl = this.shadowRoot!.getElementById('container') as HTMLDivElement;
|
|
98
|
+
this.elements.titleEl = this.shadowRoot!.getElementById('title') as HTMLHeadingElement;
|
|
99
|
+
this.elements.btnGenerateEl = this.shadowRoot!.getElementById('btn-generate') as HTMLButtonElement;
|
|
100
|
+
this.elements.resultAreaEl = this.shadowRoot!.getElementById('result-area') as HTMLDivElement;
|
|
101
|
+
this.elements.keystoneAddrEl = this.shadowRoot!.getElementById('keystone-addr') as HTMLElement;
|
|
102
|
+
this.elements.inputSecret = this.shadowRoot!.getElementById('input-secret') as HTMLInputElement;
|
|
103
|
+
this.elements.statusArea = this.shadowRoot!.getElementById('status-area') as HTMLDivElement;
|
|
104
|
+
this.elements.statusText = this.shadowRoot!.getElementById('status-text') as HTMLParagraphElement;
|
|
105
|
+
|
|
106
|
+
// ElementBase requires contentEl
|
|
107
|
+
this.elements.contentEl = this.elements.containerEl;
|
|
108
|
+
|
|
109
|
+
this.initHandlers();
|
|
110
|
+
|
|
111
|
+
if (this.ibGibAddr && !this.ibGib) {
|
|
112
|
+
await this.loadIbGib();
|
|
113
|
+
}
|
|
114
|
+
await this.renderUI();
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
override async disconnected(): Promise<void> {
|
|
118
|
+
// cleanup if needed
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
private initHandlers() {
|
|
122
|
+
this.elements!.btnGenerateEl.addEventListener('click', () => this.handleGenerate());
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Triggered by the "Generate" button.
|
|
127
|
+
* Orchestrates: Secret -> Local Genesis -> Graph Collection -> Server Sync.
|
|
128
|
+
*/
|
|
129
|
+
protected async handleGenerate() {
|
|
130
|
+
const lc = `${this.lc}[${this.handleGenerate.name}]`;
|
|
131
|
+
try {
|
|
132
|
+
console.log(`${lc} [NAG][ibgib-paradigm] starting genesis orchestration...`);
|
|
133
|
+
this.setLoading(true);
|
|
134
|
+
this.setStatus("Initializing genesis...", "info");
|
|
135
|
+
|
|
136
|
+
devLog('Starting local genesis orchestration...');
|
|
137
|
+
const masterSecret = this.elements!.inputSecret.value;
|
|
138
|
+
if (!masterSecret) {
|
|
139
|
+
this.setStatus("Please enter a master secret.", "error");
|
|
140
|
+
devLog('✗ Please enter a master secret.');
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
// 1. Prepare Keystone Configs (Standard Phase 1 config)
|
|
145
|
+
const configs: KeystonePoolConfig[] = [
|
|
146
|
+
{
|
|
147
|
+
id: 'primary',
|
|
148
|
+
type: KeystoneChallengeType.hash_reveal_v1,
|
|
149
|
+
salt: 'primary_pool_salt',
|
|
150
|
+
algo: HashAlgorithm.sha_256,
|
|
151
|
+
rounds: 1,
|
|
152
|
+
behavior: {
|
|
153
|
+
size: 3,
|
|
154
|
+
replenish: KeystoneReplenishStrategy.topUp,
|
|
155
|
+
selectSequentially: 1,
|
|
156
|
+
selectRandomly: 0,
|
|
157
|
+
targetBindingChars: 0,
|
|
158
|
+
},
|
|
159
|
+
allowedVerbs: [], // General purpose
|
|
160
|
+
}
|
|
161
|
+
];
|
|
162
|
+
|
|
163
|
+
// 2. Get local services
|
|
164
|
+
const metaspace = await getGlobalMetaspace_waitIfNeeded();
|
|
165
|
+
const space = await metaspace.getLocalUserSpace({});
|
|
166
|
+
if (!space) { throw new Error("No default space found in metaspace."); }
|
|
167
|
+
|
|
168
|
+
// 3. Perform Genesis (Local)
|
|
169
|
+
const keystoneService = new KeystoneService_V1();
|
|
170
|
+
const keystoneIbGib = await keystoneService.genesis({
|
|
171
|
+
masterSecret,
|
|
172
|
+
configs,
|
|
173
|
+
metaspace,
|
|
174
|
+
space,
|
|
175
|
+
frameDetails: { client: 'space-gib-web', timestamp: Date.now() }
|
|
176
|
+
});
|
|
177
|
+
|
|
178
|
+
const addr = getIbGibAddr({ ibGib: keystoneIbGib });
|
|
179
|
+
console.log(`${lc} [NAG][ibgib-paradigm] local genesis complete: ${addr}`);
|
|
180
|
+
this.setStatus("Local genesis complete. Syncing to server...", "info");
|
|
181
|
+
devLog(`✓ Local genesis complete: ${addr}`);
|
|
182
|
+
|
|
183
|
+
// Expose for dev tools
|
|
184
|
+
(window as any).dev_domainI = keystoneIbGib;
|
|
185
|
+
(window as any).dev_domainIMasterSecret = masterSecret;
|
|
186
|
+
|
|
187
|
+
// 4. Post to Server
|
|
188
|
+
devLog(`Posting genesis keystone to server...`);
|
|
189
|
+
const resSync = await spaceGibApiBridge.postGenesisKeystone(keystoneIbGib);
|
|
190
|
+
if (!resSync.success) {
|
|
191
|
+
this.setStatus(`Sync failed: ${resSync.message}`, "error");
|
|
192
|
+
devLog(`✗ Server rejected genesis keystone: ${resSync.message}`);
|
|
193
|
+
return;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
// 5. Success
|
|
197
|
+
this.elements!.keystoneAddrEl.textContent = addr;
|
|
198
|
+
this.elements!.statusArea.classList.remove('hidden');
|
|
199
|
+
this.setStatus("Keystone successfully created and synced!", "success");
|
|
200
|
+
devLog(`✓ Keystone successfully created and synced!`);
|
|
201
|
+
|
|
202
|
+
} catch (error) {
|
|
203
|
+
const emsg = extractErrorMsg(error);
|
|
204
|
+
console.error(`${lc} ${emsg}`);
|
|
205
|
+
this.setStatus(`Error: ${emsg}`, "error");
|
|
206
|
+
devLog(`✗ Error: ${emsg}`);
|
|
207
|
+
} finally {
|
|
208
|
+
this.setLoading(false);
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
private setLoading(loading: boolean) {
|
|
213
|
+
this.elements!.btnGenerateEl.disabled = loading;
|
|
214
|
+
this.elements!.btnGenerateEl.textContent = loading ? "Generating..." : "Generate Identity Keystone";
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
private setStatus(msg: string, type: 'info' | 'success' | 'error') {
|
|
218
|
+
this.elements!.statusText.textContent = msg;
|
|
219
|
+
this.elements!.statusText.className = `status-msg ${type}`;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
protected override async renderUI(): Promise<void> {
|
|
223
|
+
// No complex rendering needed for this simple creator component yet
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
override async handleContextUpdated(): Promise<void> {
|
|
227
|
+
await this.renderUI();
|
|
228
|
+
}
|
|
229
|
+
}
|