@xmemo/skill 1.1.25
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 +34 -0
- package/bin/install.mjs +251 -0
- package/package.json +24 -0
- package/skill/CHANGELOG.md +279 -0
- package/skill/SKILL.md +464 -0
- package/skill/references/ledger-operations.md +147 -0
- package/skill/references/memory-operations.md +231 -0
- package/skill/references/runtime-operations.md +118 -0
- package/skill/references/troubleshooting.md +147 -0
- package/skill/scripts/commands/account.mjs +194 -0
- package/skill/scripts/commands/auth-login.mjs +234 -0
- package/skill/scripts/commands/auth-manage.mjs +201 -0
- package/skill/scripts/commands/ledger.mjs +175 -0
- package/skill/scripts/commands/memory.mjs +306 -0
- package/skill/scripts/commands/ops.mjs +236 -0
- package/skill/scripts/lib/api.mjs +311 -0
- package/skill/scripts/lib/auth-state.mjs +253 -0
- package/skill/scripts/lib/cli-input.mjs +288 -0
- package/skill/scripts/lib/core.mjs +247 -0
- package/skill/scripts/lib/help.mjs +179 -0
- package/skill/scripts/lib/muse-vault.mjs +198 -0
- package/skill/scripts/lib/openclaw-egress.mjs +63 -0
- package/skill/scripts/xmemo-skill.mjs +184 -0
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* XMemo Standalone Skill Runtime
|
|
5
|
+
* Module Architecture Map:
|
|
6
|
+
* - lib/core.mjs: Constants, error mapping, and validation primitives.
|
|
7
|
+
* - lib/cli-input.mjs: CLI argument parsing and I/O resolution.
|
|
8
|
+
* - lib/help.mjs: Command usage registry and help text generators.
|
|
9
|
+
* - lib/api.mjs: HTTP transport, JSON parsing, and response formatting.
|
|
10
|
+
* - lib/auth-state.mjs: Credential storage and state persistence.
|
|
11
|
+
* - commands/*.mjs: Command handlers (auth-login, auth-manage, memory, ledger, account, ops).
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
import path from 'node:path';
|
|
15
|
+
|
|
16
|
+
import {
|
|
17
|
+
MAX_TIMEOUT_MS,
|
|
18
|
+
EXIT_CODE,
|
|
19
|
+
exitCodeForHttpStatus,
|
|
20
|
+
exitCodeForErrorCode,
|
|
21
|
+
exitCodeForError,
|
|
22
|
+
REST_COMMANDS,
|
|
23
|
+
SCRIPT_COMMAND,
|
|
24
|
+
parsePositiveInteger,
|
|
25
|
+
normalizeBaseUrl,
|
|
26
|
+
} from './lib/core.mjs';
|
|
27
|
+
|
|
28
|
+
import {
|
|
29
|
+
isStdoutTty,
|
|
30
|
+
parseArgs,
|
|
31
|
+
validateCommandInput,
|
|
32
|
+
readStdinContent,
|
|
33
|
+
resolveCommandInputs,
|
|
34
|
+
} from './lib/cli-input.mjs';
|
|
35
|
+
|
|
36
|
+
import {
|
|
37
|
+
COMMAND_USAGE_REGISTRY,
|
|
38
|
+
buildTopLevelHelp,
|
|
39
|
+
printUsage,
|
|
40
|
+
} from './lib/help.mjs';
|
|
41
|
+
|
|
42
|
+
import {
|
|
43
|
+
extractRequestId,
|
|
44
|
+
extractExpiresInSeconds,
|
|
45
|
+
formatRemainingValidity,
|
|
46
|
+
sanitizeTerminalText,
|
|
47
|
+
} from './lib/api.mjs';
|
|
48
|
+
|
|
49
|
+
import {
|
|
50
|
+
getStoredCredential,
|
|
51
|
+
requestTemporaryMemoryOperation,
|
|
52
|
+
} from './lib/auth-state.mjs';
|
|
53
|
+
|
|
54
|
+
import { handleAuthLogin } from './commands/auth-login.mjs';
|
|
55
|
+
import { handleAuthManage } from './commands/auth-manage.mjs';
|
|
56
|
+
import { handleMemory } from './commands/memory.mjs';
|
|
57
|
+
import { handleLedger } from './commands/ledger.mjs';
|
|
58
|
+
import { handleAccount } from './commands/account.mjs';
|
|
59
|
+
import { handleOps } from './commands/ops.mjs';
|
|
60
|
+
|
|
61
|
+
const SKILL_VERSION = '1.1.25';
|
|
62
|
+
|
|
63
|
+
async function main() {
|
|
64
|
+
let { command, subcommand, positionals, options, flags } = parseArgs(process.argv.slice(2));
|
|
65
|
+
|
|
66
|
+
if (command === 'auth-status') {
|
|
67
|
+
command = 'auth';
|
|
68
|
+
subcommand = 'status';
|
|
69
|
+
positionals = ['auth', 'status', ...positionals.slice(1)];
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
if (options.help) {
|
|
73
|
+
printUsage(command);
|
|
74
|
+
process.exit(EXIT_CODE.SUCCESS);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
if (options.version) {
|
|
78
|
+
console.log(SKILL_VERSION);
|
|
79
|
+
process.exit(EXIT_CODE.SUCCESS);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
if (!command) {
|
|
83
|
+
printUsage();
|
|
84
|
+
process.exit(EXIT_CODE.SUCCESS);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
if (!['login', 'register', 'logout', 'auth'].includes(command) && !REST_COMMANDS.has(command)) {
|
|
88
|
+
console.error(`Unknown command: ${command}`);
|
|
89
|
+
printUsage();
|
|
90
|
+
process.exit(EXIT_CODE.USER_ERROR);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
options.baseUrl = normalizeBaseUrl(options.baseUrl);
|
|
94
|
+
options.timeoutMs = parsePositiveInteger(options.timeoutMs, '--timeout-ms', MAX_TIMEOUT_MS);
|
|
95
|
+
validateCommandInput(command, subcommand, positionals, options, flags);
|
|
96
|
+
await resolveCommandInputs(command, flags, options);
|
|
97
|
+
|
|
98
|
+
const ctx = { command, subcommand, positionals, options, flags, skillVersion: SKILL_VERSION };
|
|
99
|
+
|
|
100
|
+
// 1. Auth commands executed before credential check
|
|
101
|
+
if (['login', 'register', 'logout'].includes(command)) {
|
|
102
|
+
await handleAuthLogin(ctx);
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
if (command === 'auth') {
|
|
107
|
+
await handleAuthManage(ctx);
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// 2. Doctor anonymous check
|
|
112
|
+
const credential = command === 'doctor' && options.anonymous ? null : await getStoredCredential();
|
|
113
|
+
const token = credential?.token;
|
|
114
|
+
|
|
115
|
+
if (command === 'doctor' && !token) {
|
|
116
|
+
await handleOps({ ...ctx, credential, token });
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// 3. Credential requirement
|
|
121
|
+
if (!token) {
|
|
122
|
+
console.error(`Error: No XMemo credential found. Preferred: set XMEMO_KEY. For formal account login with explicit local storage consent, run "${SCRIPT_COMMAND} login --allow-plaintext". For a limited temporary sandbox only when permitted, run "${SCRIPT_COMMAND} register --reason unattended|declined --allow-plaintext".`);
|
|
123
|
+
process.exit(EXIT_CODE.AUTH_ERROR);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// 4. Temporary token isolation
|
|
127
|
+
if (credential?.credential_type === 'temporary') {
|
|
128
|
+
if (['remember', 'recall', 'search'].includes(command)) {
|
|
129
|
+
try {
|
|
130
|
+
await requestTemporaryMemoryOperation(command, options, flags, credential);
|
|
131
|
+
} catch (e) {
|
|
132
|
+
console.error('Temporary memory request failed:', e.message);
|
|
133
|
+
process.exit(exitCodeForError(e));
|
|
134
|
+
}
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
console.error(`Temporary access supports only remember, recall, and search in its isolated sandbox. Complete formal registration at ${sanitizeTerminalText(credential.bind_url || 'the bind URL shown at registration')} to use ${command}.`);
|
|
138
|
+
process.exit(EXIT_CODE.USER_ERROR);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
// 5. Formal credential commands
|
|
142
|
+
const authCtx = { ...ctx, credential, token };
|
|
143
|
+
if (['restart-snapshot', 'restart-restore', 'recall-context', 'read', 'update', 'forget', 'remember', 'recall', 'search'].includes(command)) {
|
|
144
|
+
await handleMemory(authCtx);
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
if (['ledger-list', 'ledger-summary'].includes(command)) {
|
|
149
|
+
await handleLedger(authCtx);
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
if (['overview', 'activity', 'stats'].includes(command)) {
|
|
154
|
+
await handleAccount(authCtx);
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
await handleOps(authCtx);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
export {
|
|
162
|
+
EXIT_CODE,
|
|
163
|
+
exitCodeForHttpStatus,
|
|
164
|
+
exitCodeForErrorCode,
|
|
165
|
+
exitCodeForError,
|
|
166
|
+
formatRemainingValidity,
|
|
167
|
+
extractRequestId,
|
|
168
|
+
extractExpiresInSeconds,
|
|
169
|
+
isStdoutTty,
|
|
170
|
+
COMMAND_USAGE_REGISTRY,
|
|
171
|
+
buildTopLevelHelp,
|
|
172
|
+
parseArgs,
|
|
173
|
+
readStdinContent,
|
|
174
|
+
resolveCommandInputs,
|
|
175
|
+
};
|
|
176
|
+
|
|
177
|
+
const isDirectExecution = process.argv[1] && import.meta.url.endsWith(path.basename(process.argv[1]));
|
|
178
|
+
|
|
179
|
+
if (isDirectExecution) {
|
|
180
|
+
main().catch((error) => {
|
|
181
|
+
console.error(`Error: ${sanitizeTerminalText(error?.message || error)}`);
|
|
182
|
+
process.exit(exitCodeForError(error));
|
|
183
|
+
});
|
|
184
|
+
}
|