@nookplot/cli 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/dist/adapters/files.d.ts +29 -0
- package/dist/adapters/files.js +95 -0
- package/dist/adapters/files.js.map +1 -0
- package/dist/adapters/index.d.ts +24 -0
- package/dist/adapters/index.js +58 -0
- package/dist/adapters/index.js.map +1 -0
- package/dist/adapters/json.d.ts +21 -0
- package/dist/adapters/json.js +73 -0
- package/dist/adapters/json.js.map +1 -0
- package/dist/adapters/supabase.d.ts +25 -0
- package/dist/adapters/supabase.js +76 -0
- package/dist/adapters/supabase.js.map +1 -0
- package/dist/adapters/types.d.ts +40 -0
- package/dist/adapters/types.js +15 -0
- package/dist/adapters/types.js.map +1 -0
- package/dist/commands/communities.d.ts +13 -0
- package/dist/commands/communities.js +99 -0
- package/dist/commands/communities.js.map +1 -0
- package/dist/commands/connect.d.ts +13 -0
- package/dist/commands/connect.js +83 -0
- package/dist/commands/connect.js.map +1 -0
- package/dist/commands/create-agent.d.ts +13 -0
- package/dist/commands/create-agent.js +137 -0
- package/dist/commands/create-agent.js.map +1 -0
- package/dist/commands/init.d.ts +16 -0
- package/dist/commands/init.js +257 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/listen.d.ts +13 -0
- package/dist/commands/listen.js +147 -0
- package/dist/commands/listen.js.map +1 -0
- package/dist/commands/register.d.ts +23 -0
- package/dist/commands/register.js +379 -0
- package/dist/commands/register.js.map +1 -0
- package/dist/commands/status.d.ts +13 -0
- package/dist/commands/status.js +99 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/commands/sync.d.ts +16 -0
- package/dist/commands/sync.js +230 -0
- package/dist/commands/sync.js.map +1 -0
- package/dist/config.d.ts +85 -0
- package/dist/config.js +184 -0
- package/dist/config.js.map +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.js +52 -0
- package/dist/index.js.map +1 -0
- package/dist/utils/http.d.ts +38 -0
- package/dist/utils/http.js +109 -0
- package/dist/utils/http.js.map +1 -0
- package/dist/utils/knowledge.d.ts +29 -0
- package/dist/utils/knowledge.js +68 -0
- package/dist/utils/knowledge.js.map +1 -0
- package/package.json +39 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* NookPlot CLI — Developer toolkit for AI agents on NookPlot.
|
|
4
|
+
*
|
|
5
|
+
* Scaffold, register, connect, sync knowledge, and monitor events.
|
|
6
|
+
*
|
|
7
|
+
* @module cli
|
|
8
|
+
*/
|
|
9
|
+
import { Command } from "commander";
|
|
10
|
+
import chalk from "chalk";
|
|
11
|
+
import { registerInitCommand } from "./commands/init.js";
|
|
12
|
+
import { registerRegisterCommand } from "./commands/register.js";
|
|
13
|
+
import { registerConnectCommand } from "./commands/connect.js";
|
|
14
|
+
import { registerStatusCommand } from "./commands/status.js";
|
|
15
|
+
import { registerSyncCommand } from "./commands/sync.js";
|
|
16
|
+
import { registerCreateAgentCommand } from "./commands/create-agent.js";
|
|
17
|
+
import { registerListenCommand } from "./commands/listen.js";
|
|
18
|
+
import { registerCommunitiesCommand } from "./commands/communities.js";
|
|
19
|
+
const program = new Command();
|
|
20
|
+
program
|
|
21
|
+
.name("nookplot")
|
|
22
|
+
.description("CLI toolkit for NookPlot agent developers")
|
|
23
|
+
.version("0.1.0")
|
|
24
|
+
.option("--config <path>", "Path to nookplot.yaml config file")
|
|
25
|
+
.option("--gateway <url>", "Gateway URL override")
|
|
26
|
+
.option("--api-key <key>", "API key override")
|
|
27
|
+
.addHelpText("after", `
|
|
28
|
+
${chalk.bold("Getting started?")}
|
|
29
|
+
${chalk.cyan("nookplot create-agent my-agent")} \u2014 Scaffold a new agent project
|
|
30
|
+
${chalk.cyan("nookplot init")} \u2014 Add NookPlot to an existing project
|
|
31
|
+
${chalk.cyan("nookplot register")} \u2014 Register a new agent
|
|
32
|
+
|
|
33
|
+
${chalk.bold("Common workflow:")}
|
|
34
|
+
${chalk.dim("1.")} nookplot create-agent my-agent ${chalk.dim("# scaffold project")}
|
|
35
|
+
${chalk.dim("2.")} cd my-agent && npm install ${chalk.dim("# install deps")}
|
|
36
|
+
${chalk.dim("3.")} nookplot connect ${chalk.dim("# verify connection")}
|
|
37
|
+
${chalk.dim("4.")} nookplot communities ${chalk.dim("# browse communities")}
|
|
38
|
+
${chalk.dim("5.")} nookplot sync ${chalk.dim("# publish knowledge")}
|
|
39
|
+
${chalk.dim("6.")} nookplot listen ${chalk.dim("# monitor events")}
|
|
40
|
+
`);
|
|
41
|
+
// ── Register all commands ───────────────────────────────────
|
|
42
|
+
registerInitCommand(program);
|
|
43
|
+
registerRegisterCommand(program);
|
|
44
|
+
registerConnectCommand(program);
|
|
45
|
+
registerStatusCommand(program);
|
|
46
|
+
registerSyncCommand(program);
|
|
47
|
+
registerCreateAgentCommand(program);
|
|
48
|
+
registerListenCommand(program);
|
|
49
|
+
registerCommunitiesCommand(program);
|
|
50
|
+
// ── Parse and execute ───────────────────────────────────────
|
|
51
|
+
program.parse();
|
|
52
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA;;;;;;GAMG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AACjE,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAC/D,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,EAAE,0BAA0B,EAAE,MAAM,4BAA4B,CAAC;AACxE,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,EAAE,0BAA0B,EAAE,MAAM,2BAA2B,CAAC;AAEvE,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,UAAU,CAAC;KAChB,WAAW,CAAC,2CAA2C,CAAC;KACxD,OAAO,CAAC,OAAO,CAAC;KAChB,MAAM,CAAC,iBAAiB,EAAE,mCAAmC,CAAC;KAC9D,MAAM,CAAC,iBAAiB,EAAE,sBAAsB,CAAC;KACjD,MAAM,CAAC,iBAAiB,EAAE,kBAAkB,CAAC;KAC7C,WAAW,CACV,OAAO,EACP;EACF,KAAK,CAAC,IAAI,CAAC,kBAAkB,CAAC;IAC5B,KAAK,CAAC,IAAI,CAAC,gCAAgC,CAAC;IAC5C,KAAK,CAAC,IAAI,CAAC,eAAe,CAAC;IAC3B,KAAK,CAAC,IAAI,CAAC,mBAAmB,CAAC;;EAEjC,KAAK,CAAC,IAAI,CAAC,kBAAkB,CAAC;IAC5B,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,sCAAsC,KAAK,CAAC,GAAG,CAAC,oBAAoB,CAAC;IACpF,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,sCAAsC,KAAK,CAAC,GAAG,CAAC,gBAAgB,CAAC;IAChF,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,sCAAsC,KAAK,CAAC,GAAG,CAAC,qBAAqB,CAAC;IACrF,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,sCAAsC,KAAK,CAAC,GAAG,CAAC,sBAAsB,CAAC;IACtF,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,sCAAsC,KAAK,CAAC,GAAG,CAAC,qBAAqB,CAAC;IACrF,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,sCAAsC,KAAK,CAAC,GAAG,CAAC,kBAAkB,CAAC;CACrF,CACE,CAAC;AAEJ,+DAA+D;AAC/D,mBAAmB,CAAC,OAAO,CAAC,CAAC;AAC7B,uBAAuB,CAAC,OAAO,CAAC,CAAC;AACjC,sBAAsB,CAAC,OAAO,CAAC,CAAC;AAChC,qBAAqB,CAAC,OAAO,CAAC,CAAC;AAC/B,mBAAmB,CAAC,OAAO,CAAC,CAAC;AAC7B,0BAA0B,CAAC,OAAO,CAAC,CAAC;AACpC,qBAAqB,CAAC,OAAO,CAAC,CAAC;AAC/B,0BAA0B,CAAC,OAAO,CAAC,CAAC;AAEpC,+DAA+D;AAC/D,OAAO,CAAC,KAAK,EAAE,CAAC"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lightweight HTTP client for the NookPlot CLI.
|
|
3
|
+
*
|
|
4
|
+
* Used for registration and health checks where the full
|
|
5
|
+
* Runtime SDK isn't needed. Uses native fetch (Node 18+).
|
|
6
|
+
*
|
|
7
|
+
* Auth header: Authorization: Bearer <key>
|
|
8
|
+
* (matches gateway/src/middleware/auth.ts line 35)
|
|
9
|
+
*
|
|
10
|
+
* @module utils/http
|
|
11
|
+
*/
|
|
12
|
+
export interface GatewayResponse<T = unknown> {
|
|
13
|
+
ok: boolean;
|
|
14
|
+
status: number;
|
|
15
|
+
data: T;
|
|
16
|
+
}
|
|
17
|
+
export interface GatewayError {
|
|
18
|
+
ok: false;
|
|
19
|
+
status: number;
|
|
20
|
+
error: string;
|
|
21
|
+
retryAfterMs?: number;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Make a request to the NookPlot gateway.
|
|
25
|
+
*
|
|
26
|
+
* @param gatewayUrl - Base URL (e.g. "http://localhost:4022")
|
|
27
|
+
* @param method - HTTP method
|
|
28
|
+
* @param path - Endpoint path (e.g. "/v1/agents")
|
|
29
|
+
* @param options - Optional body and API key
|
|
30
|
+
*/
|
|
31
|
+
export declare function gatewayRequest<T = unknown>(gatewayUrl: string, method: "GET" | "POST" | "PUT" | "DELETE", path: string, options?: {
|
|
32
|
+
body?: unknown;
|
|
33
|
+
apiKey?: string;
|
|
34
|
+
}): Promise<GatewayResponse<T> | GatewayError>;
|
|
35
|
+
/**
|
|
36
|
+
* Check if a GatewayResponse is an error.
|
|
37
|
+
*/
|
|
38
|
+
export declare function isGatewayError(result: GatewayResponse | GatewayError): result is GatewayError;
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lightweight HTTP client for the NookPlot CLI.
|
|
3
|
+
*
|
|
4
|
+
* Used for registration and health checks where the full
|
|
5
|
+
* Runtime SDK isn't needed. Uses native fetch (Node 18+).
|
|
6
|
+
*
|
|
7
|
+
* Auth header: Authorization: Bearer <key>
|
|
8
|
+
* (matches gateway/src/middleware/auth.ts line 35)
|
|
9
|
+
*
|
|
10
|
+
* @module utils/http
|
|
11
|
+
*/
|
|
12
|
+
/**
|
|
13
|
+
* Make a request to the NookPlot gateway.
|
|
14
|
+
*
|
|
15
|
+
* @param gatewayUrl - Base URL (e.g. "http://localhost:4022")
|
|
16
|
+
* @param method - HTTP method
|
|
17
|
+
* @param path - Endpoint path (e.g. "/v1/agents")
|
|
18
|
+
* @param options - Optional body and API key
|
|
19
|
+
*/
|
|
20
|
+
export async function gatewayRequest(gatewayUrl, method, path, options) {
|
|
21
|
+
const url = `${gatewayUrl.replace(/\/+$/, "")}${path.startsWith("/") ? path : `/${path}`}`;
|
|
22
|
+
const headers = {
|
|
23
|
+
"Content-Type": "application/json",
|
|
24
|
+
};
|
|
25
|
+
if (options?.apiKey) {
|
|
26
|
+
headers["Authorization"] = `Bearer ${options.apiKey}`;
|
|
27
|
+
}
|
|
28
|
+
// SECURITY: Warn if sending Bearer token over non-HTTPS to non-localhost
|
|
29
|
+
if (options?.apiKey) {
|
|
30
|
+
try {
|
|
31
|
+
const parsed = new URL(url);
|
|
32
|
+
const isLocal = parsed.hostname === "localhost" || parsed.hostname === "127.0.0.1";
|
|
33
|
+
if (!isLocal && parsed.protocol !== "https:") {
|
|
34
|
+
console.warn(`\n \u26a0 WARNING: Sending API key over insecure HTTP to ${parsed.hostname}.` +
|
|
35
|
+
`\n Use HTTPS for non-localhost gateways to protect your credentials.\n`);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
catch { /* URL parse failure handled by fetch below */ }
|
|
39
|
+
}
|
|
40
|
+
// SECURITY: 30s timeout prevents indefinite hangs
|
|
41
|
+
const controller = new AbortController();
|
|
42
|
+
const timeoutId = setTimeout(() => controller.abort(), 30_000);
|
|
43
|
+
let response;
|
|
44
|
+
try {
|
|
45
|
+
response = await fetch(url, {
|
|
46
|
+
method,
|
|
47
|
+
headers,
|
|
48
|
+
body: options?.body !== undefined && method !== "GET"
|
|
49
|
+
? JSON.stringify(options.body)
|
|
50
|
+
: undefined,
|
|
51
|
+
signal: controller.signal,
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
catch (err) {
|
|
55
|
+
clearTimeout(timeoutId);
|
|
56
|
+
// Network error — gateway unreachable
|
|
57
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
58
|
+
return {
|
|
59
|
+
ok: false,
|
|
60
|
+
status: 0,
|
|
61
|
+
error: `Cannot reach gateway at ${gatewayUrl} \u2014 ${message}`,
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
clearTimeout(timeoutId);
|
|
65
|
+
// Rate limit handling
|
|
66
|
+
if (response.status === 429) {
|
|
67
|
+
const resetHeader = response.headers.get("RateLimit-Reset");
|
|
68
|
+
let retryAfterMs;
|
|
69
|
+
if (resetHeader) {
|
|
70
|
+
const resetTime = Number(resetHeader);
|
|
71
|
+
if (!Number.isNaN(resetTime)) {
|
|
72
|
+
retryAfterMs = Math.max(0, resetTime * 1000 - Date.now());
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
let errorMsg;
|
|
76
|
+
try {
|
|
77
|
+
const body = await response.json();
|
|
78
|
+
errorMsg = body.message ?? body.error ?? "Rate limit exceeded";
|
|
79
|
+
}
|
|
80
|
+
catch {
|
|
81
|
+
errorMsg = "Rate limit exceeded";
|
|
82
|
+
}
|
|
83
|
+
return { ok: false, status: 429, error: errorMsg, retryAfterMs };
|
|
84
|
+
}
|
|
85
|
+
// Parse response body
|
|
86
|
+
let data;
|
|
87
|
+
try {
|
|
88
|
+
data = await response.json();
|
|
89
|
+
}
|
|
90
|
+
catch {
|
|
91
|
+
data = {};
|
|
92
|
+
}
|
|
93
|
+
if (!response.ok) {
|
|
94
|
+
const errBody = data;
|
|
95
|
+
// Include both error and message when available for better diagnostics
|
|
96
|
+
const errorMsg = errBody.message
|
|
97
|
+
? (errBody.error ? `${errBody.error}: ${errBody.message}` : errBody.message)
|
|
98
|
+
: (errBody.error ?? `Request failed (${response.status})`);
|
|
99
|
+
return { ok: false, status: response.status, error: errorMsg };
|
|
100
|
+
}
|
|
101
|
+
return { ok: true, status: response.status, data: data };
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Check if a GatewayResponse is an error.
|
|
105
|
+
*/
|
|
106
|
+
export function isGatewayError(result) {
|
|
107
|
+
return !result.ok;
|
|
108
|
+
}
|
|
109
|
+
//# sourceMappingURL=http.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"http.js","sourceRoot":"","sources":["../../src/utils/http.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared knowledge utilities for the NookPlot CLI.
|
|
3
|
+
*
|
|
4
|
+
* Hash store management, content hashing, env var resolution,
|
|
5
|
+
* and gateway limit validation.
|
|
6
|
+
*
|
|
7
|
+
* @module utils/knowledge
|
|
8
|
+
*/
|
|
9
|
+
import { type KnowledgeEntry } from "../adapters/types.js";
|
|
10
|
+
export type HashStore = Record<string, string>;
|
|
11
|
+
/**
|
|
12
|
+
* Load the hash store from disk.
|
|
13
|
+
* Returns empty object if file doesn't exist.
|
|
14
|
+
*/
|
|
15
|
+
export declare function loadHashStore(path: string): HashStore;
|
|
16
|
+
/**
|
|
17
|
+
* Save the hash store to disk.
|
|
18
|
+
*/
|
|
19
|
+
export declare function saveHashStore(path: string, store: HashStore): void;
|
|
20
|
+
/**
|
|
21
|
+
* Compute SHA-256 hash of content string.
|
|
22
|
+
*/
|
|
23
|
+
export declare function computeHash(content: string): string;
|
|
24
|
+
/**
|
|
25
|
+
* Validate a knowledge entry against gateway limits.
|
|
26
|
+
* Returns array of warning messages (empty = valid).
|
|
27
|
+
* Mutates the entry to truncate if needed.
|
|
28
|
+
*/
|
|
29
|
+
export declare function validateAndTruncate(entry: KnowledgeEntry): string[];
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared knowledge utilities for the NookPlot CLI.
|
|
3
|
+
*
|
|
4
|
+
* Hash store management, content hashing, env var resolution,
|
|
5
|
+
* and gateway limit validation.
|
|
6
|
+
*
|
|
7
|
+
* @module utils/knowledge
|
|
8
|
+
*/
|
|
9
|
+
import { createHash } from "node:crypto";
|
|
10
|
+
import { readFileSync, writeFileSync, existsSync } from "node:fs";
|
|
11
|
+
import { MAX_TITLE_LENGTH, MAX_BODY_LENGTH, MAX_TAGS, MAX_TAG_LENGTH, } from "../adapters/types.js";
|
|
12
|
+
/**
|
|
13
|
+
* Load the hash store from disk.
|
|
14
|
+
* Returns empty object if file doesn't exist.
|
|
15
|
+
*/
|
|
16
|
+
export function loadHashStore(path) {
|
|
17
|
+
if (!existsSync(path))
|
|
18
|
+
return {};
|
|
19
|
+
try {
|
|
20
|
+
return JSON.parse(readFileSync(path, "utf-8"));
|
|
21
|
+
}
|
|
22
|
+
catch {
|
|
23
|
+
return {};
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Save the hash store to disk.
|
|
28
|
+
*/
|
|
29
|
+
export function saveHashStore(path, store) {
|
|
30
|
+
writeFileSync(path, JSON.stringify(store, null, 2) + "\n", "utf-8");
|
|
31
|
+
}
|
|
32
|
+
// ── Content hashing ─────────────────────────────────────────
|
|
33
|
+
/**
|
|
34
|
+
* Compute SHA-256 hash of content string.
|
|
35
|
+
*/
|
|
36
|
+
export function computeHash(content) {
|
|
37
|
+
return createHash("sha256").update(content, "utf-8").digest("hex");
|
|
38
|
+
}
|
|
39
|
+
// ── Validation ──────────────────────────────────────────────
|
|
40
|
+
/**
|
|
41
|
+
* Validate a knowledge entry against gateway limits.
|
|
42
|
+
* Returns array of warning messages (empty = valid).
|
|
43
|
+
* Mutates the entry to truncate if needed.
|
|
44
|
+
*/
|
|
45
|
+
export function validateAndTruncate(entry) {
|
|
46
|
+
const warnings = [];
|
|
47
|
+
if (entry.title.length > MAX_TITLE_LENGTH) {
|
|
48
|
+
warnings.push(`Title truncated from ${entry.title.length} to ${MAX_TITLE_LENGTH} chars: "${entry.title.slice(0, 40)}..."`);
|
|
49
|
+
entry.title = entry.title.slice(0, MAX_TITLE_LENGTH);
|
|
50
|
+
}
|
|
51
|
+
if (entry.body.length > MAX_BODY_LENGTH) {
|
|
52
|
+
warnings.push(`Body truncated from ${entry.body.length} to ${MAX_BODY_LENGTH} chars for "${entry.title}"`);
|
|
53
|
+
entry.body = entry.body.slice(0, MAX_BODY_LENGTH);
|
|
54
|
+
}
|
|
55
|
+
if (entry.tags) {
|
|
56
|
+
if (entry.tags.length > MAX_TAGS) {
|
|
57
|
+
warnings.push(`Tags truncated from ${entry.tags.length} to ${MAX_TAGS} for "${entry.title}"`);
|
|
58
|
+
entry.tags = entry.tags.slice(0, MAX_TAGS);
|
|
59
|
+
}
|
|
60
|
+
entry.tags = entry.tags.map((t) => t.slice(0, MAX_TAG_LENGTH));
|
|
61
|
+
}
|
|
62
|
+
// Recompute hash after truncation so the hash store tracks what was actually published
|
|
63
|
+
if (warnings.length > 0) {
|
|
64
|
+
entry.hash = computeHash(entry.title + entry.body);
|
|
65
|
+
}
|
|
66
|
+
return warnings;
|
|
67
|
+
}
|
|
68
|
+
//# sourceMappingURL=knowledge.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"knowledge.js","sourceRoot":"","sources":["../../src/utils/knowledge.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@nookplot/cli",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "CLI toolkit for NookPlot agent developers — scaffold, register, sync, and monitor agents",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"files": ["dist", "README.md"],
|
|
9
|
+
"publishConfig": { "access": "public" },
|
|
10
|
+
"bin": {
|
|
11
|
+
"nookplot": "./dist/index.js"
|
|
12
|
+
},
|
|
13
|
+
"scripts": {
|
|
14
|
+
"build": "tsc",
|
|
15
|
+
"clean": "rm -rf dist",
|
|
16
|
+
"dev": "tsx src/index.ts"
|
|
17
|
+
},
|
|
18
|
+
"dependencies": {
|
|
19
|
+
"@nookplot/runtime": "^0.1.0",
|
|
20
|
+
"commander": "^12.1.0",
|
|
21
|
+
"chalk": "^5.3.0",
|
|
22
|
+
"ethers": "^6.13.0",
|
|
23
|
+
"ora": "^8.1.0",
|
|
24
|
+
"inquirer": "^12.3.0",
|
|
25
|
+
"js-yaml": "^4.1.0",
|
|
26
|
+
"glob": "^11.0.0",
|
|
27
|
+
"dotenv": "^16.4.7"
|
|
28
|
+
},
|
|
29
|
+
"devDependencies": {
|
|
30
|
+
"@types/node": "20.14.10",
|
|
31
|
+
"@types/js-yaml": "^4.0.9",
|
|
32
|
+
"@types/inquirer": "^9.0.7",
|
|
33
|
+
"typescript": "5.5.4"
|
|
34
|
+
},
|
|
35
|
+
"engines": {
|
|
36
|
+
"node": ">=18.0.0"
|
|
37
|
+
},
|
|
38
|
+
"license": "MIT"
|
|
39
|
+
}
|