quilltap 4.6.0-dev → 4.6.0-dev.106
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/bin/quilltap.js +79 -101
- package/lib/completion/bash.template +152 -33
- package/lib/completion/fish.template +262 -87
- package/lib/completion/zsh.template +219 -26
- package/lib/db-commands.js +418 -11
- package/lib/db-helpers.js +90 -9
- package/lib/memories-commands.js +20 -16
- package/lib/native-modules.js +151 -0
- package/package.json +6 -3
package/bin/quilltap.js
CHANGED
|
@@ -13,6 +13,7 @@ const {
|
|
|
13
13
|
loadDbKey,
|
|
14
14
|
} = require('../lib/db-helpers');
|
|
15
15
|
const { resolveInstance } = require('../lib/instances');
|
|
16
|
+
const { resolveModuleDir, ensureNativeModules } = require('../lib/native-modules');
|
|
16
17
|
|
|
17
18
|
const PACKAGE_DIR = path.resolve(__dirname, '..');
|
|
18
19
|
|
|
@@ -137,85 +138,6 @@ function openBrowser(url) {
|
|
|
137
138
|
});
|
|
138
139
|
}
|
|
139
140
|
|
|
140
|
-
// Resolve a native module's directory, handling npm hoisting.
|
|
141
|
-
// Returns the directory containing package.json, or null if not found.
|
|
142
|
-
function resolveModuleDir(moduleName) {
|
|
143
|
-
try {
|
|
144
|
-
const pkgJson = require.resolve(moduleName + '/package.json');
|
|
145
|
-
return path.dirname(pkgJson);
|
|
146
|
-
} catch {
|
|
147
|
-
return null;
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
// Check if native modules are compiled for the current Node.js version.
|
|
152
|
-
// This handles the case where npx caches the package but the user upgrades
|
|
153
|
-
// Node.js — the cached native modules will have a stale NODE_MODULE_VERSION.
|
|
154
|
-
function ensureNativeModules() {
|
|
155
|
-
const needsRebuild = [];
|
|
156
|
-
|
|
157
|
-
// Check better-sqlite3-multiple-ciphers (provides SQLCipher encryption support).
|
|
158
|
-
// The main app depends on this via an npm alias as 'better-sqlite3', so we must
|
|
159
|
-
// ensure the SQLCipher-capable version is available and link it as 'better-sqlite3'.
|
|
160
|
-
// We must load the native binding directly to detect NODE_MODULE_VERSION mismatches.
|
|
161
|
-
try {
|
|
162
|
-
const modDir = resolveModuleDir('better-sqlite3-multiple-ciphers')
|
|
163
|
-
|| resolveModuleDir('better-sqlite3');
|
|
164
|
-
if (!modDir) throw Object.assign(new Error('not found'), { code: 'MODULE_NOT_FOUND' });
|
|
165
|
-
const bindingsPath = path.join(modDir, 'build', 'Release', 'better_sqlite3.node');
|
|
166
|
-
require(bindingsPath);
|
|
167
|
-
} catch (err) {
|
|
168
|
-
if (err.message && err.message.includes('NODE_MODULE_VERSION')) {
|
|
169
|
-
needsRebuild.push('better-sqlite3-multiple-ciphers');
|
|
170
|
-
} else if (err.code === 'MODULE_NOT_FOUND') {
|
|
171
|
-
needsRebuild.push('better-sqlite3-multiple-ciphers');
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
// Check sharp: loads its native binding eagerly on require, but we use
|
|
176
|
-
// the same explicit-path approach for consistency and reliability.
|
|
177
|
-
try {
|
|
178
|
-
require('sharp');
|
|
179
|
-
} catch (err) {
|
|
180
|
-
if (err.message && err.message.includes('NODE_MODULE_VERSION')) {
|
|
181
|
-
needsRebuild.push('sharp');
|
|
182
|
-
} else if (err.code === 'MODULE_NOT_FOUND') {
|
|
183
|
-
needsRebuild.push('sharp');
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
// Check node-pty: backs the Ariel terminal feature. Loaded dynamically by
|
|
188
|
-
// pty-manager in the standalone server, so resolution must succeed and the
|
|
189
|
-
// native binding's NODE_MODULE_VERSION must match the runtime.
|
|
190
|
-
try {
|
|
191
|
-
require('node-pty');
|
|
192
|
-
} catch (err) {
|
|
193
|
-
if (err.message && err.message.includes('NODE_MODULE_VERSION')) {
|
|
194
|
-
needsRebuild.push('node-pty');
|
|
195
|
-
} else if (err.code === 'MODULE_NOT_FOUND') {
|
|
196
|
-
needsRebuild.push('node-pty');
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
if (needsRebuild.length === 0) return;
|
|
201
|
-
|
|
202
|
-
console.log(` Rebuilding native modules for Node.js ${process.version}...`);
|
|
203
|
-
|
|
204
|
-
try {
|
|
205
|
-
execSync(`npm rebuild ${needsRebuild.join(' ')}`, {
|
|
206
|
-
cwd: PACKAGE_DIR,
|
|
207
|
-
stdio: 'inherit',
|
|
208
|
-
});
|
|
209
|
-
console.log(' Done.');
|
|
210
|
-
console.log('');
|
|
211
|
-
} catch (err) {
|
|
212
|
-
console.error('');
|
|
213
|
-
console.error(` Warning: Failed to rebuild native modules: ${err.message}`);
|
|
214
|
-
console.error(' Try running: npm rebuild --prefix ' + PACKAGE_DIR);
|
|
215
|
-
console.error('');
|
|
216
|
-
}
|
|
217
|
-
}
|
|
218
|
-
|
|
219
141
|
// Symlink native modules into the standalone directory's node_modules
|
|
220
142
|
// so that standard Node.js resolution finds them without relying on NODE_PATH.
|
|
221
143
|
function linkNativeModules(standaloneDir) {
|
|
@@ -266,25 +188,67 @@ function linkNativeModules(standaloneDir) {
|
|
|
266
188
|
|| resolveModuleDir('better-sqlite3');
|
|
267
189
|
linkModule('better-sqlite3', betterSqlite3Dir);
|
|
268
190
|
|
|
269
|
-
// Link node-pty —
|
|
270
|
-
//
|
|
271
|
-
//
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
191
|
+
// Link node-pty — but only when we have to. The standalone tarball ships
|
|
192
|
+
// node-pty intact with cross-platform prebuilds (darwin-arm64, darwin-x64,
|
|
193
|
+
// win32-arm64, win32-x64). On those platforms the tarball-shipped copy is
|
|
194
|
+
// already correct, and we MUST NOT replace it with a symlink to the
|
|
195
|
+
// npm-installed copy: `sudo npm install -g quilltap` on macOS can strip the
|
|
196
|
+
// executable bit off `spawn-helper`, and we can't chmod a root-owned file
|
|
197
|
+
// back as a non-root runtime user — pty.spawn() then fails with
|
|
198
|
+
// `posix_spawnp failed`. Only Linux (which has no node-pty prebuild) and
|
|
199
|
+
// rebuild-failure cases need the symlink.
|
|
200
|
+
const standaloneNodePtyPath = path.join(standaloneNodeModules, 'node-pty');
|
|
201
|
+
const standaloneHasUsablePty = (() => {
|
|
202
|
+
try {
|
|
203
|
+
const stat = fs.lstatSync(standaloneNodePtyPath);
|
|
204
|
+
if (stat.isSymbolicLink()) return false; // prior broken-symlink state — replace it
|
|
205
|
+
if (!stat.isDirectory()) return false;
|
|
206
|
+
} catch {
|
|
207
|
+
return false;
|
|
208
|
+
}
|
|
209
|
+
const platformPrebuildDir = path.join(
|
|
210
|
+
standaloneNodePtyPath,
|
|
211
|
+
'prebuilds',
|
|
212
|
+
`${process.platform}-${process.arch}`,
|
|
213
|
+
);
|
|
214
|
+
return fs.existsSync(platformPrebuildDir);
|
|
215
|
+
})();
|
|
216
|
+
|
|
217
|
+
if (!standaloneHasUsablePty) {
|
|
218
|
+
const nodePtyDir = resolveModuleDir('node-pty');
|
|
219
|
+
linkModule('node-pty', nodePtyDir);
|
|
220
|
+
if (nodePtyDir) {
|
|
221
|
+
// Some npm cache extractions (notably `sudo npm install -g`) strip the
|
|
222
|
+
// executable bit on spawn-helper. Restore it where we can. If chmod
|
|
223
|
+
// fails because we don't own the file (typical when the CLI was
|
|
224
|
+
// installed with sudo and is run as a non-root user), warn loudly —
|
|
225
|
+
// silent failure here produces the `posix_spawnp failed` runtime error
|
|
226
|
+
// with no actionable hint.
|
|
227
|
+
const prebuildsDir = path.join(nodePtyDir, 'prebuilds');
|
|
228
|
+
if (fs.existsSync(prebuildsDir)) {
|
|
229
|
+
try {
|
|
230
|
+
for (const entry of fs.readdirSync(prebuildsDir, { withFileTypes: true })) {
|
|
231
|
+
if (!entry.isDirectory()) continue;
|
|
232
|
+
const helper = path.join(prebuildsDir, entry.name, 'spawn-helper');
|
|
233
|
+
if (!fs.existsSync(helper)) continue;
|
|
234
|
+
try {
|
|
235
|
+
fs.chmodSync(helper, 0o755);
|
|
236
|
+
} catch (err) {
|
|
237
|
+
if (err && err.code === 'EPERM') {
|
|
238
|
+
console.error('');
|
|
239
|
+
console.error(` Warning: Could not make node-pty spawn-helper executable:`);
|
|
240
|
+
console.error(` ${helper}`);
|
|
241
|
+
console.error(` The file is owned by another user (likely root from a sudo'd`);
|
|
242
|
+
console.error(` global install). Terminal sessions will fail to spawn with`);
|
|
243
|
+
console.error(` "posix_spawnp failed" until this is fixed. Run:`);
|
|
244
|
+
console.error(` sudo chmod 755 "${helper}"`);
|
|
245
|
+
console.error('');
|
|
246
|
+
}
|
|
247
|
+
// Other errors are non-fatal — node-pty may still work if the bit was already set.
|
|
248
|
+
}
|
|
285
249
|
}
|
|
286
|
-
}
|
|
287
|
-
}
|
|
250
|
+
} catch { /* best-effort */ }
|
|
251
|
+
}
|
|
288
252
|
}
|
|
289
253
|
}
|
|
290
254
|
|
|
@@ -740,6 +704,11 @@ Subcommands (high-level shortcuts; auto-pick the right database):
|
|
|
740
704
|
log <id> Full request/response of a single LLM log
|
|
741
705
|
memories --character <id> Memories held by a character
|
|
742
706
|
(flags: --about <id|name> --source AUTO|MANUAL)
|
|
707
|
+
characters status Per-character vault readiness report:
|
|
708
|
+
flag value, vault present, single-file count,
|
|
709
|
+
Prompts/ and Scenarios/ folder counts, and any
|
|
710
|
+
divergence between DB columns and vault content.
|
|
711
|
+
(flags: --id <id|name> --diverged --blocked --limit N)
|
|
743
712
|
optimize [target...] Run maintenance (VACUUM + ANALYZE + PRAGMA optimize)
|
|
744
713
|
on the named databases, or all of them if no
|
|
745
714
|
target is given. Targets: main, llm-logs,
|
|
@@ -762,6 +731,8 @@ Low-level options (legacy; still supported):
|
|
|
762
731
|
--tables List all tables in the active database
|
|
763
732
|
--count <table> Show row count for a table
|
|
764
733
|
--repl Interactive SQL prompt (extras: .cols, .find)
|
|
734
|
+
--json Emit machine-readable JSON instead of a table
|
|
735
|
+
(works with --tables, --count, and raw SQL)
|
|
765
736
|
--llm-logs Target the LLM logs database
|
|
766
737
|
--mount-points Target the document mount-index database
|
|
767
738
|
--data-dir <path> Override data directory (pass instance root)
|
|
@@ -869,6 +840,7 @@ async function dbCommand(args) {
|
|
|
869
840
|
let lockStatus = false;
|
|
870
841
|
let lockClean = false;
|
|
871
842
|
let lockOverride = false;
|
|
843
|
+
let asJson = false;
|
|
872
844
|
|
|
873
845
|
let i = 0;
|
|
874
846
|
while (i < cleaned.length) {
|
|
@@ -878,6 +850,7 @@ async function dbCommand(args) {
|
|
|
878
850
|
case '--tables': showTables = true; break;
|
|
879
851
|
case '--count': countTable = cleaned[++i]; break;
|
|
880
852
|
case '--repl': repl = true; break;
|
|
853
|
+
case '--json': asJson = true; break;
|
|
881
854
|
case '--help': case '-h': showHelp = true; break;
|
|
882
855
|
case '--lock-status': lockStatus = true; break;
|
|
883
856
|
case '--lock-clean': lockClean = true; break;
|
|
@@ -971,22 +944,27 @@ async function dbCommand(args) {
|
|
|
971
944
|
try {
|
|
972
945
|
if (showTables) {
|
|
973
946
|
const tables = db.prepare("SELECT name FROM sqlite_master WHERE type='table' ORDER BY name").all();
|
|
974
|
-
|
|
947
|
+
if (asJson) console.log(JSON.stringify(tables.map(t => t.name), null, 2));
|
|
948
|
+
else for (const t of tables) console.log(t.name);
|
|
975
949
|
} else if (countTable) {
|
|
976
950
|
const row = db.prepare(`SELECT count(*) as count FROM "${countTable}"`).get();
|
|
977
|
-
console.log(row.count);
|
|
951
|
+
if (asJson) console.log(JSON.stringify({ table: countTable, count: row.count }, null, 2));
|
|
952
|
+
else console.log(row.count);
|
|
978
953
|
} else if (sql) {
|
|
979
954
|
const stmt = db.prepare(sql);
|
|
980
955
|
if (stmt.reader) {
|
|
981
956
|
const rows = stmt.all();
|
|
982
|
-
if (
|
|
957
|
+
if (asJson) {
|
|
958
|
+
console.log(JSON.stringify(rows, null, 2));
|
|
959
|
+
} else if (rows.length === 0) {
|
|
983
960
|
console.log('(no results)');
|
|
984
961
|
} else {
|
|
985
962
|
console.table(rows);
|
|
986
963
|
}
|
|
987
964
|
} else {
|
|
988
965
|
const info = stmt.run();
|
|
989
|
-
console.log(
|
|
966
|
+
if (asJson) console.log(JSON.stringify({ changes: info.changes, lastInsertRowid: Number(info.lastInsertRowid) }, null, 2));
|
|
967
|
+
else console.log(`Changes: ${info.changes}`);
|
|
990
968
|
}
|
|
991
969
|
} else if (repl) {
|
|
992
970
|
const readline = require('readline');
|
|
@@ -12,15 +12,19 @@ _quilltap_complete() {
|
|
|
12
12
|
cword=$COMP_CWORD
|
|
13
13
|
|
|
14
14
|
# Global options that can appear before subcommands
|
|
15
|
-
local global_opts="-d --data-dir -i --instance -p --port -o --open -v --version -h --help --update"
|
|
15
|
+
local global_opts="-d --data-dir -i --instance -p --port -o --open -v --version -h --help --update --passphrase"
|
|
16
|
+
|
|
17
|
+
# Top-level subcommands
|
|
18
|
+
local top_cmds="db docs themes instances memories memory-diff logs migrations completion"
|
|
16
19
|
|
|
17
20
|
# Get the subcommand (first non-option word after quilltap)
|
|
18
21
|
local subcommand=""
|
|
22
|
+
local subverb=""
|
|
19
23
|
local i=1
|
|
20
24
|
while [[ $i -lt $cword ]]; do
|
|
21
25
|
local word="${words[$i]}"
|
|
22
26
|
case "$word" in
|
|
23
|
-
-d|--data-dir|-i|--instance|-p|--port)
|
|
27
|
+
-d|--data-dir|-i|--instance|-p|--port|--passphrase)
|
|
24
28
|
# These take a value, skip the next word
|
|
25
29
|
((i += 2))
|
|
26
30
|
;;
|
|
@@ -33,22 +37,26 @@ _quilltap_complete() {
|
|
|
33
37
|
((i += 1))
|
|
34
38
|
;;
|
|
35
39
|
*)
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
40
|
+
if [[ -z "$subcommand" ]]; then
|
|
41
|
+
subcommand="$word"
|
|
42
|
+
elif [[ -z "$subverb" ]]; then
|
|
43
|
+
subverb="$word"
|
|
44
|
+
fi
|
|
45
|
+
((i += 1))
|
|
39
46
|
;;
|
|
40
47
|
esac
|
|
41
48
|
done
|
|
42
49
|
|
|
43
50
|
# If we're completing a global flag value
|
|
44
|
-
if [[ "$prev" == "-d" ]] || [[ "$prev" == "--data-dir" ]]
|
|
45
|
-
|
|
46
|
-
|
|
51
|
+
if [[ "$prev" == "-d" ]] || [[ "$prev" == "--data-dir" ]]; then
|
|
52
|
+
# Complete with directories
|
|
53
|
+
COMPREPLY=($(compgen -d -- "$cur"))
|
|
54
|
+
return
|
|
55
|
+
fi
|
|
56
|
+
if [[ "$prev" == "-p" ]] || [[ "$prev" == "--port" ]] || [[ "$prev" == "--passphrase" ]]; then
|
|
47
57
|
return
|
|
48
58
|
fi
|
|
49
|
-
|
|
50
59
|
if [[ "$prev" == "-i" ]] || [[ "$prev" == "--instance" ]]; then
|
|
51
|
-
# Complete with instance names
|
|
52
60
|
local instances=$(command quilltap instances list --names-only 2>/dev/null)
|
|
53
61
|
COMPREPLY=($(compgen -W "$instances" -- "$cur"))
|
|
54
62
|
return
|
|
@@ -59,53 +67,164 @@ _quilltap_complete() {
|
|
|
59
67
|
if [[ "$cur" == -* ]]; then
|
|
60
68
|
COMPREPLY=($(compgen -W "$global_opts" -- "$cur"))
|
|
61
69
|
else
|
|
62
|
-
COMPREPLY=($(compgen -W "
|
|
70
|
+
COMPREPLY=($(compgen -W "$top_cmds" -- "$cur"))
|
|
63
71
|
fi
|
|
64
72
|
return
|
|
65
73
|
fi
|
|
66
74
|
|
|
75
|
+
# Shared flag-value completions for any subcommand
|
|
76
|
+
case "$prev" in
|
|
77
|
+
--mount)
|
|
78
|
+
local mounts=$(command quilltap docs list --names-only 2>/dev/null)
|
|
79
|
+
COMPREPLY=($(compgen -W "$mounts" -- "$cur"))
|
|
80
|
+
return
|
|
81
|
+
;;
|
|
82
|
+
--character|--about)
|
|
83
|
+
# No live source; suggest common literals
|
|
84
|
+
COMPREPLY=($(compgen -W "all self none" -- "$cur"))
|
|
85
|
+
return
|
|
86
|
+
;;
|
|
87
|
+
--source)
|
|
88
|
+
COMPREPLY=($(compgen -W "AUTO MANUAL" -- "$cur"))
|
|
89
|
+
return
|
|
90
|
+
;;
|
|
91
|
+
--sort)
|
|
92
|
+
COMPREPLY=($(compgen -W "name path size modified created reinforced importance accessed reinforcement-count links" -- "$cur"))
|
|
93
|
+
return
|
|
94
|
+
;;
|
|
95
|
+
--field)
|
|
96
|
+
COMPREPLY=($(compgen -W "request response both" -- "$cur"))
|
|
97
|
+
return
|
|
98
|
+
;;
|
|
99
|
+
--type)
|
|
100
|
+
COMPREPLY=($(compgen -W "file folder" -- "$cur"))
|
|
101
|
+
return
|
|
102
|
+
;;
|
|
103
|
+
--stream)
|
|
104
|
+
COMPREPLY=($(compgen -W "combined error stdout stderr startup" -- "$cur"))
|
|
105
|
+
return
|
|
106
|
+
;;
|
|
107
|
+
esac
|
|
108
|
+
|
|
67
109
|
# Subcommand-specific completion
|
|
68
|
-
local subcommand_opts=""
|
|
69
110
|
case "$subcommand" in
|
|
70
111
|
db)
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
112
|
+
local db_verbs="schema find chats messages logs message log memories optimize backup integrity"
|
|
113
|
+
local db_flags="--instance --data-dir --passphrase --json --limit --grep \
|
|
114
|
+
--character --project --about --source --chat --message --rendered --field \
|
|
115
|
+
--tail --last --full --from --type --out --help \
|
|
116
|
+
--tables --count --repl --llm-logs --mount-points \
|
|
117
|
+
--lock-status --lock-clean --lock-override"
|
|
118
|
+
if [[ -z "$subverb" ]]; then
|
|
119
|
+
if [[ "$cur" == -* ]]; then
|
|
120
|
+
COMPREPLY=($(compgen -W "$db_flags" -- "$cur"))
|
|
121
|
+
else
|
|
122
|
+
COMPREPLY=($(compgen -W "$db_verbs" -- "$cur"))
|
|
123
|
+
fi
|
|
124
|
+
else
|
|
125
|
+
COMPREPLY=($(compgen -W "$db_flags" -- "$cur"))
|
|
74
126
|
fi
|
|
75
|
-
COMPREPLY=($(compgen -W "$subcommand_opts" -- "$cur"))
|
|
76
127
|
;;
|
|
77
128
|
docs)
|
|
78
129
|
local docs_verbs="list show files ls dir read export scan write delete mkdir move copy status find grep reindex embed"
|
|
79
|
-
|
|
80
|
-
|
|
130
|
+
local docs_flags="--mount --instance --data-dir --passphrase --port --json --help \
|
|
131
|
+
--force --rendered --links --folder --type --ext --limit --max --context --top --threshold \
|
|
132
|
+
--ignore-case -l --wait -R --recursive --sort -r --reverse --depth --max-nodes --long --semantic"
|
|
133
|
+
if [[ -z "$subverb" ]]; then
|
|
134
|
+
if [[ "$cur" == -* ]]; then
|
|
135
|
+
COMPREPLY=($(compgen -W "$docs_flags" -- "$cur"))
|
|
136
|
+
else
|
|
137
|
+
COMPREPLY=($(compgen -W "$docs_verbs" -- "$cur"))
|
|
138
|
+
fi
|
|
139
|
+
else
|
|
140
|
+
COMPREPLY=($(compgen -W "$docs_flags" -- "$cur"))
|
|
81
141
|
fi
|
|
82
|
-
COMPREPLY=($(compgen -W "$docs_verbs" -- "$cur"))
|
|
83
142
|
;;
|
|
84
143
|
themes)
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
144
|
+
local themes_verbs="list install uninstall validate export create search update registry"
|
|
145
|
+
local themes_flags="--instance --data-dir --output -o --help"
|
|
146
|
+
if [[ -z "$subverb" ]]; then
|
|
147
|
+
if [[ "$cur" == -* ]]; then
|
|
148
|
+
COMPREPLY=($(compgen -W "$themes_flags" -- "$cur"))
|
|
149
|
+
else
|
|
150
|
+
COMPREPLY=($(compgen -W "$themes_verbs" -- "$cur"))
|
|
151
|
+
fi
|
|
152
|
+
elif [[ "$subverb" == "registry" ]]; then
|
|
153
|
+
local registry_verbs="list add remove refresh keygen sign"
|
|
154
|
+
local registry_flags="--key -k --name -n --output -o --help"
|
|
155
|
+
if [[ "$cur" == -* ]]; then
|
|
156
|
+
COMPREPLY=($(compgen -W "$registry_flags" -- "$cur"))
|
|
157
|
+
else
|
|
158
|
+
COMPREPLY=($(compgen -W "$registry_verbs" -- "$cur"))
|
|
159
|
+
fi
|
|
160
|
+
else
|
|
161
|
+
COMPREPLY=($(compgen -W "$themes_flags" -- "$cur"))
|
|
88
162
|
fi
|
|
89
|
-
COMPREPLY=($(compgen -W "$subcommand_opts" -- "$cur"))
|
|
90
163
|
;;
|
|
91
164
|
instances)
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
165
|
+
local inst_verbs="list ls show path where add create remove rm delete set-passphrase passphrase default rename"
|
|
166
|
+
local inst_flags="--names-only --json --clear --help"
|
|
167
|
+
if [[ -z "$subverb" ]]; then
|
|
168
|
+
if [[ "$cur" == -* ]]; then
|
|
169
|
+
COMPREPLY=($(compgen -W "$inst_flags" -- "$cur"))
|
|
170
|
+
else
|
|
171
|
+
COMPREPLY=($(compgen -W "$inst_verbs" -- "$cur"))
|
|
172
|
+
fi
|
|
173
|
+
else
|
|
174
|
+
# Most instances verbs take a name as positional; offer registered names
|
|
175
|
+
case "$subverb" in
|
|
176
|
+
show|remove|rm|delete|set-passphrase|passphrase|default|rename)
|
|
177
|
+
local instances=$(command quilltap instances list --names-only 2>/dev/null)
|
|
178
|
+
if [[ "$cur" == -* ]]; then
|
|
179
|
+
COMPREPLY=($(compgen -W "$inst_flags" -- "$cur"))
|
|
180
|
+
else
|
|
181
|
+
COMPREPLY=($(compgen -W "$instances" -- "$cur"))
|
|
182
|
+
fi
|
|
183
|
+
;;
|
|
184
|
+
*)
|
|
185
|
+
COMPREPLY=($(compgen -W "$inst_flags" -- "$cur"))
|
|
186
|
+
;;
|
|
187
|
+
esac
|
|
95
188
|
fi
|
|
96
|
-
COMPREPLY=($(compgen -W "$subcommand_opts" -- "$cur"))
|
|
97
189
|
;;
|
|
98
190
|
memories)
|
|
99
191
|
local mem_verbs="ls find grep show tree status validate"
|
|
100
|
-
|
|
101
|
-
|
|
192
|
+
local mem_flags="--character --about --source --chat --project --since --until \
|
|
193
|
+
--min-importance --min-reinforced --has-embedding --no-embedding \
|
|
194
|
+
--sort -r --reverse --limit --full-titles --in --no-related --list \
|
|
195
|
+
--ignore-case -i --paths-only -l --max --context --depth --max-nodes \
|
|
196
|
+
--semantic --top --threshold \
|
|
197
|
+
--instance --data-dir --passphrase --port --json --help"
|
|
198
|
+
if [[ -z "$subverb" ]]; then
|
|
199
|
+
if [[ "$cur" == -* ]]; then
|
|
200
|
+
COMPREPLY=($(compgen -W "$mem_flags" -- "$cur"))
|
|
201
|
+
else
|
|
202
|
+
COMPREPLY=($(compgen -W "$mem_verbs" -- "$cur"))
|
|
203
|
+
fi
|
|
204
|
+
else
|
|
205
|
+
COMPREPLY=($(compgen -W "$mem_flags" -- "$cur"))
|
|
102
206
|
fi
|
|
103
|
-
COMPREPLY=($(compgen -W "$mem_verbs" -- "$cur"))
|
|
104
207
|
;;
|
|
105
208
|
memory-diff)
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
209
|
+
local md_flags="--instance --data-dir --passphrase --port --concurrency --out --help"
|
|
210
|
+
COMPREPLY=($(compgen -W "$md_flags" -- "$cur"))
|
|
211
|
+
;;
|
|
212
|
+
logs)
|
|
213
|
+
local logs_flags="--stream --tail -f --follow --grep \
|
|
214
|
+
--instance --data-dir --passphrase --help"
|
|
215
|
+
COMPREPLY=($(compgen -W "$logs_flags" -- "$cur"))
|
|
216
|
+
;;
|
|
217
|
+
migrations)
|
|
218
|
+
local mig_verbs="status pending run"
|
|
219
|
+
local mig_flags="--dry-run --json --instance --data-dir --passphrase --help"
|
|
220
|
+
if [[ -z "$subverb" ]]; then
|
|
221
|
+
if [[ "$cur" == -* ]]; then
|
|
222
|
+
COMPREPLY=($(compgen -W "$mig_flags" -- "$cur"))
|
|
223
|
+
else
|
|
224
|
+
COMPREPLY=($(compgen -W "$mig_verbs" -- "$cur"))
|
|
225
|
+
fi
|
|
226
|
+
else
|
|
227
|
+
COMPREPLY=($(compgen -W "$mig_flags" -- "$cur"))
|
|
109
228
|
fi
|
|
110
229
|
;;
|
|
111
230
|
completion)
|