takibibase 1.5.0 → 1.7.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/SKILL.md +7 -0
- package/package.json +1 -1
- package/takibi.mjs +35 -2
package/SKILL.md
CHANGED
|
@@ -23,6 +23,10 @@ error hints.
|
|
|
23
23
|
- Projects: `takibi projects` lists what this key can reach. `--project`
|
|
24
24
|
takes a name or a UUID; single-grant keys may omit it.
|
|
25
25
|
`takibi projects --add <name> <uuid>` keeps local aliases for offline use.
|
|
26
|
+
- Folders: `takibi folders [--project …]` lists folder names → uuids for
|
|
27
|
+
`--folder` (only folders this key's grants touch; single-grant keys may
|
|
28
|
+
omit `--project`). Discovery flow: `projects` → `folders` → scoped
|
|
29
|
+
`ask`/`search`/`doc list`.
|
|
26
30
|
- First probe: `takibi version` (needs no key; shows build + `jev` status).
|
|
27
31
|
- Update notice: the CLI polls the npm registry once a day and nudges on
|
|
28
32
|
stderr when behind (never on `--json`).
|
|
@@ -75,6 +79,9 @@ back to `search`, try `doc text` on the hits — then either answer from
|
|
|
75
79
|
evidence or say the evidence is not there. Never fill gaps with generated
|
|
76
80
|
prose presented as sourced.
|
|
77
81
|
|
|
82
|
+
Split bundled asks: one narrow ask per field — a combined question
|
|
83
|
+
abstains honestly instead of answering halfway.
|
|
84
|
+
|
|
78
85
|
## Notes (agent scratchpad, not canon)
|
|
79
86
|
|
|
80
87
|
- When to use: end-of-run debriefs (problem, what you tried, what worked,
|
package/package.json
CHANGED
package/takibi.mjs
CHANGED
|
@@ -15,6 +15,8 @@
|
|
|
15
15
|
* reads the API first and --project resolves names through it. A LOCAL
|
|
16
16
|
* map (~/.takibi/projects, `name=uuid` lines) remains as the offline
|
|
17
17
|
* fallback and for custom aliases. UUIDs pass straight through.
|
|
18
|
+
* `folders` lists granted folders via GET /v1/projects/:id/folders the
|
|
19
|
+
* same way (single-grant keys may omit --project; the CLI defaults it).
|
|
18
20
|
* - There is no GET /v1/tasks/:id, so `tasks get` lists and filters.
|
|
19
21
|
* - Account-only routes (doc download, uploads, deletes) answer 401, not
|
|
20
22
|
* 403, to Bearer callers; `doc download` refuses client-side with a hint.
|
|
@@ -34,7 +36,7 @@ import { homedir } from 'node:os';
|
|
|
34
36
|
import { join } from 'node:path';
|
|
35
37
|
|
|
36
38
|
/** Baked fallback; the published package re-reads package.json next door. */
|
|
37
|
-
const BAKED_VERSION = '1.
|
|
39
|
+
const BAKED_VERSION = '1.7.0';
|
|
38
40
|
const CLI_INFO = (() => {
|
|
39
41
|
try {
|
|
40
42
|
const pkg = JSON.parse(readFileSync(new URL('./package.json', import.meta.url), 'utf8'));
|
|
@@ -370,6 +372,7 @@ Commands:
|
|
|
370
372
|
notes keep <id> <ver> Endorse a note (expected version)
|
|
371
373
|
notes remove <id> <ver> Discard a note (expected version)
|
|
372
374
|
projects Granted projects (names -> uuids for --project)
|
|
375
|
+
folders Granted folders (names -> uuids for --folder)
|
|
373
376
|
version What build is serving + jev wired|unwired (no key needed)
|
|
374
377
|
skill Print the takibi-use agent skill (pipe it to an agent)
|
|
375
378
|
skill --install Install the skill into agent skills dirs
|
|
@@ -566,7 +569,7 @@ async function ctxFor(globals, { needKey, resolveProject = true }) {
|
|
|
566
569
|
const { warnings } = loadProjectMap();
|
|
567
570
|
for (const w of warnings) err(`warning: ${w}`);
|
|
568
571
|
if (globals.folder !== undefined && globals.folder !== null && globals.folder !== '' && !UUID_RE.test(globals.folder)) {
|
|
569
|
-
throw usageError(`--folder takes a folder UUID, not ${JSON.stringify(globals.folder)}. (
|
|
572
|
+
throw usageError(`--folder takes a folder UUID, not ${JSON.stringify(globals.folder)}. (Run \`takibi folders\` for this key's folder names.)`);
|
|
570
573
|
}
|
|
571
574
|
return { baseUrl, key, projectId, folder: globals.folder || undefined, json: globals.json, verbose: globals.verbose };
|
|
572
575
|
}
|
|
@@ -1085,6 +1088,35 @@ async function cmdProjects(tokens, globals) {
|
|
|
1085
1088
|
for (const { name, id } of entries) out(`${name} → ${id}`);
|
|
1086
1089
|
}
|
|
1087
1090
|
|
|
1091
|
+
async function cmdFolders(tokens, globals) {
|
|
1092
|
+
if (tokens.length > 0) throw usageError(`Unexpected ${JSON.stringify(tokens[0])}. Usage: takibi folders [--project <name-or-uuid>]`);
|
|
1093
|
+
const ctx = await ctxFor(globals, { needKey: true });
|
|
1094
|
+
let projectId = ctx.projectId;
|
|
1095
|
+
if (!projectId) {
|
|
1096
|
+
// The server cannot default a path param, so single-grant keys resolve
|
|
1097
|
+
// their one project client-side (ask/search default server-side).
|
|
1098
|
+
const data = await api('GET', '/v1/projects', { baseUrl: ctx.baseUrl, key: ctx.key, verbose: ctx.verbose, label: 'projects' });
|
|
1099
|
+
const ids = [...new Set((data?.projects ?? []).map((p) => p?.id).filter(Boolean))];
|
|
1100
|
+
// Tag-only grants list no collections, so an empty list is ambiguous:
|
|
1101
|
+
// the key may hold nothing, or hold tags. Say both, accurately.
|
|
1102
|
+
if (ids.length === 0) throw new CliError('This key lists no projects.', { hint: 'Tag-only keys cannot list collections — pass --project <uuid> explicitly (ask the account owner for the id), or grant this profile a collection or folder.' });
|
|
1103
|
+
if (ids.length > 1) throw usageError('This key spans projects — pass --project <name-or-uuid>.');
|
|
1104
|
+
projectId = ids[0];
|
|
1105
|
+
}
|
|
1106
|
+
const data = await api('GET', `/v1/projects/${projectId}/folders`, { baseUrl: ctx.baseUrl, key: ctx.key, verbose: ctx.verbose, label: 'folders' });
|
|
1107
|
+
if (ctx.json) {
|
|
1108
|
+
out(JSON.stringify(data, null, 2));
|
|
1109
|
+
return;
|
|
1110
|
+
}
|
|
1111
|
+
const entries = data?.folders ?? [];
|
|
1112
|
+
if (!entries.length) {
|
|
1113
|
+
out('No folders found.');
|
|
1114
|
+
err('(This project has no folders this key can reach. Tag-only keys see only folders holding their tagged files.)');
|
|
1115
|
+
return;
|
|
1116
|
+
}
|
|
1117
|
+
for (const f of entries) out(`${f.name} → ${f.id}`);
|
|
1118
|
+
}
|
|
1119
|
+
|
|
1088
1120
|
async function cmdVersion(globals) {
|
|
1089
1121
|
const baseUrl = resolveBaseUrl();
|
|
1090
1122
|
const data = await api('GET', '/version', { baseUrl, verbose: globals.verbose, label: 'version' });
|
|
@@ -1238,6 +1270,7 @@ async function main(argv) {
|
|
|
1238
1270
|
if (cmd === 'doc' || cmd === 'docs') return cmdDoc(tokens, globals);
|
|
1239
1271
|
if (cmd === 'notes' || cmd === 'note') return cmdNotes(tokens, globals);
|
|
1240
1272
|
if (cmd === 'projects') return cmdProjects(tokens, globals);
|
|
1273
|
+
if (cmd === 'folders' || cmd === 'folder') return cmdFolders(tokens, globals);
|
|
1241
1274
|
if (cmd === 'version') return cmdVersion(globals);
|
|
1242
1275
|
if (cmd === 'skill') return cmdSkill(tokens, globals);
|
|
1243
1276
|
throw usageError(`Unknown command ${JSON.stringify(cmd)}. See \`takibi --help\`.`);
|