@skillcdn/console 0.1.24 → 0.3.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/README.md +6 -5
- package/dist/api.d.ts +1 -1
- package/dist/api.d.ts.map +1 -1
- package/dist/api.js +1 -1
- package/dist/api.js.map +1 -1
- package/dist/cli/cli.d.ts.map +1 -1
- package/dist/cli/cli.js +64 -65
- package/dist/cli/cli.js.map +1 -1
- package/dist/cli/format.d.ts +4 -28
- package/dist/cli/format.d.ts.map +1 -1
- package/dist/cli/format.js +7 -261
- package/dist/cli/format.js.map +1 -1
- package/dist/cli/help.d.ts.map +1 -1
- package/dist/cli/help.js +6 -6
- package/dist/cli/help.js.map +1 -1
- package/dist/cli/pack.d.ts +46 -0
- package/dist/cli/pack.d.ts.map +1 -0
- package/dist/cli/pack.js +250 -0
- package/dist/cli/pack.js.map +1 -0
- package/dist/compat.d.ts +1 -1
- package/dist/compat.js +1 -1
- package/dist/components/decision-list.d.ts +13 -1
- package/dist/components/decision-list.d.ts.map +1 -1
- package/dist/components/decision-list.js +74 -29
- package/dist/components/decision-list.js.map +1 -1
- package/dist/components/paged.d.ts +24 -0
- package/dist/components/paged.d.ts.map +1 -1
- package/dist/components/paged.js +40 -4
- package/dist/components/paged.js.map +1 -1
- package/dist/components/skills.d.ts.map +1 -1
- package/dist/components/skills.js +8 -4
- package/dist/components/skills.js.map +1 -1
- package/dist/components/ui.d.ts +2 -0
- package/dist/components/ui.d.ts.map +1 -1
- package/dist/components/ui.js +7 -2
- package/dist/components/ui.js.map +1 -1
- package/dist/console.css +112 -5
- package/dist/console.d.ts.map +1 -1
- package/dist/console.js +2 -2
- package/dist/console.js.map +1 -1
- package/dist/data.d.ts.map +1 -1
- package/dist/data.js +27 -2
- package/dist/data.js.map +1 -1
- package/dist/i18n/en.d.ts +13 -0
- package/dist/i18n/en.d.ts.map +1 -1
- package/dist/i18n/en.js +15 -0
- package/dist/i18n/en.js.map +1 -1
- package/dist/i18n/ko.d.ts.map +1 -1
- package/dist/i18n/ko.js +15 -0
- package/dist/i18n/ko.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/router.d.ts +6 -1
- package/dist/router.d.ts.map +1 -1
- package/dist/router.js +13 -7
- package/dist/router.js.map +1 -1
- package/dist/schemas.d.ts +321 -159
- package/dist/schemas.d.ts.map +1 -1
- package/dist/schemas.js +61 -154
- package/dist/schemas.js.map +1 -1
- package/docs/specs/cli.md +3 -3
- package/docs/specs/rest.md +5 -13
- package/package.json +2 -1
- package/skills/deploying-a-console/SKILL.md +2 -2
- package/skills/working-the-board/SKILL.md +3 -3
- package/src/api.ts +2 -7
- package/src/cli/cli.ts +92 -76
- package/src/cli/format.ts +10 -328
- package/src/cli/help.ts +7 -6
- package/src/cli/pack.ts +356 -0
- package/src/compat.ts +1 -1
- package/src/components/decision-list.tsx +227 -94
- package/src/components/paged.tsx +72 -3
- package/src/components/skills.tsx +51 -33
- package/src/components/ui.tsx +16 -3
- package/src/console.tsx +3 -0
- package/src/data.ts +32 -2
- package/src/i18n/en.ts +18 -0
- package/src/i18n/ko.ts +17 -0
- package/src/index.ts +9 -1
- package/src/router.ts +20 -9
- package/src/schemas.ts +76 -180
- package/src/styles/console.css +112 -5
package/src/cli/format.ts
CHANGED
|
@@ -15,13 +15,6 @@ import type {
|
|
|
15
15
|
RestProjectRules,
|
|
16
16
|
RestRules,
|
|
17
17
|
RestRun,
|
|
18
|
-
RestSkillBrowse,
|
|
19
|
-
RestSkillBrowseEntry,
|
|
20
|
-
RestSkillFile,
|
|
21
|
-
RestSkillFind,
|
|
22
|
-
RestSkillLoad,
|
|
23
|
-
RestSkillPage,
|
|
24
|
-
RestSkills,
|
|
25
18
|
RestTask,
|
|
26
19
|
RestVersion,
|
|
27
20
|
RestVersionSummary,
|
|
@@ -247,70 +240,6 @@ export function formatArtifact(
|
|
|
247
240
|
return artifact.label === null ? what : `${artifact.label}: ${what}`;
|
|
248
241
|
}
|
|
249
242
|
|
|
250
|
-
const SKILLS_WORDS: Readonly<Record<Exclude<RestSkills["status"], "none" | "ready">, string>> = {
|
|
251
|
-
indexing: "SkillCDN is still indexing the repository; ask again in a moment.",
|
|
252
|
-
failed: "SkillCDN could not index the repository.",
|
|
253
|
-
not_found:
|
|
254
|
-
"SkillCDN does not serve this address to the console: nothing is there, or the pack is private and the project holds no pack token for it (console project pack-token <key> --stdin, for an owner).",
|
|
255
|
-
token_invalid:
|
|
256
|
-
"The pack token the project holds no longer works at SkillCDN: an owner sets a new one (console project pack-token <key> --stdin).",
|
|
257
|
-
unavailable: "SkillCDN could not be reached; ask again later.",
|
|
258
|
-
};
|
|
259
|
-
|
|
260
|
-
/** A count with its noun: `1 skill`, `2 skills`. */
|
|
261
|
-
const counted = (n: number, noun: string): string => `${n} ${noun}${n === 1 ? "" : "s"}`;
|
|
262
|
-
|
|
263
|
-
/**
|
|
264
|
-
* The organization's skills: where they are, the pack by name and by count, each skill with
|
|
265
|
-
* what an agent loads it by, where a person connects an agent that has no connection to the
|
|
266
|
-
* address, and where the console's own skills are on this machine, when the command knows.
|
|
267
|
-
*/
|
|
268
|
-
export function formatSkills(skills: RestSkills, ownSkills?: string): string {
|
|
269
|
-
const own =
|
|
270
|
-
ownSkills === undefined
|
|
271
|
-
? []
|
|
272
|
-
: ["", `The console's own skills, for working the board: ${ownSkills}`];
|
|
273
|
-
if (skills.status === "none" || skills.address === null || skills.page === null) {
|
|
274
|
-
return ["No skills address: neither this project nor the console names one.", ...own].join(
|
|
275
|
-
"\n",
|
|
276
|
-
);
|
|
277
|
-
}
|
|
278
|
-
const head = `skills at ${skills.address}, served by ${skills.source}: ${skills.status}`;
|
|
279
|
-
if (skills.status !== "ready") {
|
|
280
|
-
return [head, SKILLS_WORDS[skills.status], ...own].join("\n");
|
|
281
|
-
}
|
|
282
|
-
const lines = [head];
|
|
283
|
-
if (skills.pack !== undefined) {
|
|
284
|
-
const named = [skills.pack.name, skills.pack.description]
|
|
285
|
-
.filter((text): text is string => text !== null)
|
|
286
|
-
.join(" ");
|
|
287
|
-
if (named !== "") {
|
|
288
|
-
lines.push(named);
|
|
289
|
-
}
|
|
290
|
-
}
|
|
291
|
-
if (skills.counts !== undefined) {
|
|
292
|
-
lines.push(
|
|
293
|
-
`${counted(skills.counts.skills, "skill")}, ${counted(skills.counts.documents, "document")}: console skills <folder> shows what a folder holds (. for the root), console skills --search <words> finds skills and documents by words.`,
|
|
294
|
-
);
|
|
295
|
-
}
|
|
296
|
-
if (skills.items.length === 0) {
|
|
297
|
-
lines.push("No skills at this address.");
|
|
298
|
-
}
|
|
299
|
-
// The path, which console skill takes, and the URI beside it, which a host's own connection takes.
|
|
300
|
-
for (const skill of skills.items) {
|
|
301
|
-
lines.push(
|
|
302
|
-
`${skill.name} ${skill.description}`,
|
|
303
|
-
` ${skill.path}${skill.uri === null ? "" : ` ${skill.uri}`}`,
|
|
304
|
-
);
|
|
305
|
-
}
|
|
306
|
-
lines.push(
|
|
307
|
-
"",
|
|
308
|
-
`Read a skill whole with console skill <path>, its rules first, and a file of the pack with console skill --file <path>; or load it by its URI through your own SkillCDN connection to this address, which a person makes at ${skills.page}. --json adds the page of each, for a person.`,
|
|
309
|
-
...own,
|
|
310
|
-
);
|
|
311
|
-
return lines.join("\n");
|
|
312
|
-
}
|
|
313
|
-
|
|
314
243
|
/** One half of the rules: where it comes from, and the text as it stands. */
|
|
315
244
|
function formatRulesHalf(where: "the workspace" | "this project", rules: RestRules): string {
|
|
316
245
|
const page = rules.page;
|
|
@@ -417,19 +346,25 @@ export function formatDecisionLine(decision: RestDecision): string {
|
|
|
417
346
|
return `${decision.id} ${state} ${decision.question} (asked by ${asker(decision)})`;
|
|
418
347
|
}
|
|
419
348
|
|
|
349
|
+
/** The options, one a line; the person's own answer, when they wrote one, is the last and says so. */
|
|
420
350
|
export function formatOptions(decision: RestDecision): string {
|
|
421
|
-
return decision.options
|
|
351
|
+
return decision.options
|
|
352
|
+
.map(
|
|
353
|
+
(option) =>
|
|
354
|
+
` ${option.id}) ${option.label}${option.own === true ? " (the person's own answer, not one given)" : ""}`,
|
|
355
|
+
)
|
|
356
|
+
.join("\n");
|
|
422
357
|
}
|
|
423
358
|
|
|
424
|
-
/** The answer, with who gave it; or that there is none yet. */
|
|
359
|
+
/** The answer, with who gave it, and that it is in their own words when it is; or that there is none yet. */
|
|
425
360
|
export function formatAnswer(decision: RestDecision): string {
|
|
426
361
|
const { answer } = decision;
|
|
427
362
|
if (answer === null) {
|
|
428
363
|
return "waits for a person.";
|
|
429
364
|
}
|
|
430
|
-
const
|
|
365
|
+
const chosen = decision.options.find((option) => option.id === answer.option);
|
|
431
366
|
const lines = [
|
|
432
|
-
`Answered: ${answer.option}) ${label ?? answer.option}, by ${answer.by.login} at ${answer.at}`,
|
|
367
|
+
`Answered: ${answer.option}) ${chosen?.label ?? answer.option}${chosen?.own === true ? ", in their own words" : ""}, by ${answer.by.login} at ${answer.at}`,
|
|
433
368
|
];
|
|
434
369
|
if (answer.note !== null && answer.note.length > 0) {
|
|
435
370
|
lines.push(`Note: ${answer.note}`);
|
|
@@ -531,256 +466,3 @@ export function formatVersion(path: string, version: RestVersion): string {
|
|
|
531
466
|
}
|
|
532
467
|
|
|
533
468
|
/** The text of one path across the pages a skill came in: the fragments joined in order. */
|
|
534
|
-
function joinTexts(
|
|
535
|
-
pages: readonly RestSkillPage[],
|
|
536
|
-
pick: (page: RestSkillPage) => readonly { readonly path: string; readonly body: string }[],
|
|
537
|
-
): { readonly path: string; readonly body: string }[] {
|
|
538
|
-
const joined = new Map<string, string>();
|
|
539
|
-
for (const page of pages) {
|
|
540
|
-
for (const text of pick(page)) {
|
|
541
|
-
joined.set(text.path, (joined.get(text.path) ?? "") + text.body);
|
|
542
|
-
}
|
|
543
|
-
}
|
|
544
|
-
return [...joined.entries()].map(([path, body]) => ({ path, body }));
|
|
545
|
-
}
|
|
546
|
-
|
|
547
|
-
const NO_ADDRESS = "No skills address: neither this project nor the console names one.";
|
|
548
|
-
|
|
549
|
-
/**
|
|
550
|
-
* One skill, as load_skill lays it out for a model (ADR-0028): the rules from the repository's
|
|
551
|
-
* root to the nearest manifest, the body, the included files, each under a line that names its
|
|
552
|
-
* path; then the files the skill has and what it refers to. A skill described only is named and
|
|
553
|
-
* pointed at, and nothing of its body is shown.
|
|
554
|
-
*/
|
|
555
|
-
export function formatSkillLoad(loaded: RestSkillLoad, pages: readonly RestSkillPage[]): string {
|
|
556
|
-
if (loaded.status === "none" || loaded.address === null) {
|
|
557
|
-
return NO_ADDRESS;
|
|
558
|
-
}
|
|
559
|
-
const head = `skill at ${loaded.address}, served by ${loaded.source}: ${loaded.status}`;
|
|
560
|
-
if (loaded.status !== "ready") {
|
|
561
|
-
return [head, SKILLS_WORDS[loaded.status]].join("\n");
|
|
562
|
-
}
|
|
563
|
-
const [first] = pages;
|
|
564
|
-
if (first === undefined) {
|
|
565
|
-
return [head, "Nothing was read."].join("\n");
|
|
566
|
-
}
|
|
567
|
-
const last = pages[pages.length - 1] ?? first;
|
|
568
|
-
const lines = [
|
|
569
|
-
`${first.name} ${first.description}`,
|
|
570
|
-
`skill ${first.path} at ${loaded.address}, served by ${loaded.source}`,
|
|
571
|
-
];
|
|
572
|
-
if (first.serving.license !== null) {
|
|
573
|
-
lines.push(`license: ${first.serving.license}`);
|
|
574
|
-
}
|
|
575
|
-
if (!first.serving.full) {
|
|
576
|
-
lines.push(
|
|
577
|
-
"",
|
|
578
|
-
`Described only: the license keeps the skill at its source. Read it there: ${first.serving.sourceUrl ?? loaded.page ?? loaded.source}`,
|
|
579
|
-
);
|
|
580
|
-
return lines.join("\n");
|
|
581
|
-
}
|
|
582
|
-
for (const rule of joinTexts(pages, (page) => page.rules)) {
|
|
583
|
-
lines.push("", `--- applicable rules: ${rule.path} ---`, rule.body.trimEnd());
|
|
584
|
-
}
|
|
585
|
-
lines.push(
|
|
586
|
-
"",
|
|
587
|
-
`--- skill: ${first.path} ---`,
|
|
588
|
-
pages
|
|
589
|
-
.map((page) => page.body)
|
|
590
|
-
.join("")
|
|
591
|
-
.trimEnd(),
|
|
592
|
-
);
|
|
593
|
-
for (const file of joinTexts(pages, (page) => page.included)) {
|
|
594
|
-
lines.push("", `--- included file: ${file.path} ---`, file.body.trimEnd());
|
|
595
|
-
}
|
|
596
|
-
if (!last.complete) {
|
|
597
|
-
lines.push("", "The skill did not come whole: the deployment stopped before the end.");
|
|
598
|
-
}
|
|
599
|
-
if (last.files.length > 0) {
|
|
600
|
-
lines.push(
|
|
601
|
-
"",
|
|
602
|
-
`Files of the skill, read with console skill --file <path>: ${last.files.join(", ")}`,
|
|
603
|
-
);
|
|
604
|
-
}
|
|
605
|
-
if (last.references.length > 0) {
|
|
606
|
-
lines.push(
|
|
607
|
-
`References: ${last.references
|
|
608
|
-
.map((reference) =>
|
|
609
|
-
reference.status === "available"
|
|
610
|
-
? reference.path
|
|
611
|
-
: `${reference.path} (${reference.status})`,
|
|
612
|
-
)
|
|
613
|
-
.join(", ")}`,
|
|
614
|
-
);
|
|
615
|
-
}
|
|
616
|
-
if (last.warnings.length > 0) {
|
|
617
|
-
lines.push(`Warnings: ${last.warnings.join("; ")}`);
|
|
618
|
-
}
|
|
619
|
-
lines.push(
|
|
620
|
-
"",
|
|
621
|
-
"Paths from the repository's root are the only identifiers. The content is the pack's, under its license; what a private pack says stays in your work.",
|
|
622
|
-
);
|
|
623
|
-
return lines.join("\n");
|
|
624
|
-
}
|
|
625
|
-
|
|
626
|
-
/** A file of the pack as read: its text whole, or what the folder holds. */
|
|
627
|
-
export function formatSkillFile(read: RestSkillFile, content: string): string {
|
|
628
|
-
if (read.status === "none" || read.address === null) {
|
|
629
|
-
return NO_ADDRESS;
|
|
630
|
-
}
|
|
631
|
-
const head = `file at ${read.address}, served by ${read.source}: ${read.status}`;
|
|
632
|
-
if (read.status !== "ready") {
|
|
633
|
-
return [
|
|
634
|
-
head,
|
|
635
|
-
read.status === "failed"
|
|
636
|
-
? "SkillCDN will not carry this file: it is too large, or not text. Read it at the repository."
|
|
637
|
-
: SKILLS_WORDS[read.status],
|
|
638
|
-
].join("\n");
|
|
639
|
-
}
|
|
640
|
-
if (read.folder !== null) {
|
|
641
|
-
return [
|
|
642
|
-
`folder ${read.folder.path} at ${read.address}${read.folder.truncated ? " (cut)" : ""}`,
|
|
643
|
-
...read.folder.entries.map(
|
|
644
|
-
(entry) =>
|
|
645
|
-
`${entry.kind === "directory" ? "d" : "f"} ${entry.path}${entry.size === null ? "" : ` ${entry.size}`}`,
|
|
646
|
-
),
|
|
647
|
-
"",
|
|
648
|
-
"console skills <folder> shows a folder with its skills marked, what each folder holds and the README that introduces it.",
|
|
649
|
-
].join("\n");
|
|
650
|
-
}
|
|
651
|
-
if (read.file === null) {
|
|
652
|
-
return `${head}: nothing was read.`;
|
|
653
|
-
}
|
|
654
|
-
return [
|
|
655
|
-
`--- file: ${read.file.path} (${read.file.totalLength} characters) ---`,
|
|
656
|
-
content.trimEnd(),
|
|
657
|
-
].join("\n");
|
|
658
|
-
}
|
|
659
|
-
|
|
660
|
-
/** One entry of a browsed folder: what it is, its path, its words, and the facts of its kind. */
|
|
661
|
-
function formatBrowseEntry(entry: RestSkillBrowseEntry): string {
|
|
662
|
-
const facts: string[] = [];
|
|
663
|
-
if (entry.kind === "directory") {
|
|
664
|
-
if (entry.skillCount > 0) {
|
|
665
|
-
facts.push(counted(entry.skillCount, "skill"));
|
|
666
|
-
}
|
|
667
|
-
if (entry.documentCount > 0) {
|
|
668
|
-
facts.push(counted(entry.documentCount, "document"));
|
|
669
|
-
}
|
|
670
|
-
if (entry.overviewPath !== null) {
|
|
671
|
-
facts.push(`README ${entry.overviewPath}`);
|
|
672
|
-
}
|
|
673
|
-
}
|
|
674
|
-
if (entry.kind === "skill") {
|
|
675
|
-
if (entry.license !== null) {
|
|
676
|
-
facts.push(entry.license);
|
|
677
|
-
}
|
|
678
|
-
if (entry.describedOnly) {
|
|
679
|
-
facts.push("described only");
|
|
680
|
-
}
|
|
681
|
-
}
|
|
682
|
-
if (entry.kind === "file" && entry.size !== null) {
|
|
683
|
-
facts.push(`${entry.size} bytes`);
|
|
684
|
-
}
|
|
685
|
-
const words = [entry.name, entry.description]
|
|
686
|
-
.filter((text): text is string => text !== null && text !== "")
|
|
687
|
-
.join(" ");
|
|
688
|
-
const mark = entry.kind === "skill" ? "skill" : entry.kind === "directory" ? "d" : "f";
|
|
689
|
-
return `${mark} ${entry.path}${words === "" ? "" : ` ${words}`}${facts.length === 0 ? "" : ` (${facts.join("; ")})`}`;
|
|
690
|
-
}
|
|
691
|
-
|
|
692
|
-
/**
|
|
693
|
-
* What a folder of the pack holds, as browse_repo lays it out: the README that introduces the
|
|
694
|
-
* folder, then its skills, its folders with what each holds, and its files, across the pages the
|
|
695
|
-
* listing came in.
|
|
696
|
-
*/
|
|
697
|
-
export function formatSkillBrowse(
|
|
698
|
-
browsed: RestSkillBrowse,
|
|
699
|
-
folders: readonly NonNullable<RestSkillBrowse["folder"]>[],
|
|
700
|
-
): string {
|
|
701
|
-
if (browsed.status === "none" || browsed.address === null) {
|
|
702
|
-
return NO_ADDRESS;
|
|
703
|
-
}
|
|
704
|
-
const head = `folder at ${browsed.address}, served by ${browsed.source}: ${browsed.status}`;
|
|
705
|
-
if (browsed.status !== "ready") {
|
|
706
|
-
return [head, SKILLS_WORDS[browsed.status]].join("\n");
|
|
707
|
-
}
|
|
708
|
-
const [first] = folders;
|
|
709
|
-
if (first === undefined) {
|
|
710
|
-
return [head, "Nothing was read."].join("\n");
|
|
711
|
-
}
|
|
712
|
-
const last = folders[folders.length - 1] ?? first;
|
|
713
|
-
const lines = [`folder ${first.path === "" ? "/" : first.path} at ${browsed.address}`];
|
|
714
|
-
if (first.overview !== null) {
|
|
715
|
-
const words = [first.overview.title, first.overview.description]
|
|
716
|
-
.filter((text): text is string => text !== null && text !== "")
|
|
717
|
-
.join(" ");
|
|
718
|
-
lines.push(` ${words === "" ? "" : `${words} `}(README: ${first.overview.path})`);
|
|
719
|
-
}
|
|
720
|
-
const entries = folders.flatMap((folder) => folder.entries);
|
|
721
|
-
if (entries.length === 0) {
|
|
722
|
-
lines.push("Nothing in this folder.");
|
|
723
|
-
}
|
|
724
|
-
for (const entry of entries) {
|
|
725
|
-
lines.push(formatBrowseEntry(entry));
|
|
726
|
-
}
|
|
727
|
-
if (last.nextCursor !== null) {
|
|
728
|
-
lines.push("More entries: the listing stopped before the end of the folder.");
|
|
729
|
-
}
|
|
730
|
-
lines.push(
|
|
731
|
-
"",
|
|
732
|
-
"Read a skill with console skill <path>; a file, or a README named above, with console skill --file <path>; a folder with console skills <folder>.",
|
|
733
|
-
);
|
|
734
|
-
return lines.join("\n");
|
|
735
|
-
}
|
|
736
|
-
|
|
737
|
-
/**
|
|
738
|
-
* What words found in the pack, as search_repo lays it out: skills with the files of theirs that
|
|
739
|
-
* matched, documents on their own, in relevance order; words, not meaning.
|
|
740
|
-
*/
|
|
741
|
-
export function formatSkillFind(found: RestSkillFind): string {
|
|
742
|
-
if (found.status === "none" || found.address === null) {
|
|
743
|
-
return NO_ADDRESS;
|
|
744
|
-
}
|
|
745
|
-
const head = `search at ${found.address}, served by ${found.source}: ${found.status}`;
|
|
746
|
-
if (found.status !== "ready") {
|
|
747
|
-
return [head, SKILLS_WORDS[found.status]].join("\n");
|
|
748
|
-
}
|
|
749
|
-
if (found.found === null) {
|
|
750
|
-
return [head, "Nothing was read."].join("\n");
|
|
751
|
-
}
|
|
752
|
-
const { query, path, items, nextCursor } = found.found;
|
|
753
|
-
const where = path === null || path === "" ? "" : ` within ${path}`;
|
|
754
|
-
const lines = [
|
|
755
|
-
`found for "${query}"${where} at ${found.address}: ${counted(items.length, "result")}`,
|
|
756
|
-
];
|
|
757
|
-
for (const item of items) {
|
|
758
|
-
if (item.kind === "skill") {
|
|
759
|
-
lines.push(
|
|
760
|
-
`skill ${item.path} ${item.name} ${item.description}${item.describedOnly ? " (described only)" : ""}`,
|
|
761
|
-
);
|
|
762
|
-
for (const file of item.files) {
|
|
763
|
-
lines.push(` file ${file.path}${file.title === null ? "" : ` ${file.title}`}`);
|
|
764
|
-
}
|
|
765
|
-
if (item.moreFiles > 0) {
|
|
766
|
-
lines.push(` and ${counted(item.moreFiles, "more file")}`);
|
|
767
|
-
}
|
|
768
|
-
} else {
|
|
769
|
-
lines.push(
|
|
770
|
-
`document ${item.path}${item.title === null ? "" : ` ${item.title}`}${item.summary === null ? "" : ` ${item.summary}`}`,
|
|
771
|
-
);
|
|
772
|
-
}
|
|
773
|
-
}
|
|
774
|
-
if (nextCursor !== null) {
|
|
775
|
-
lines.push(
|
|
776
|
-
"More matched: narrow the words, or search within a folder (console skills <folder> --search <words>).",
|
|
777
|
-
);
|
|
778
|
-
}
|
|
779
|
-
if (items.length > 0) {
|
|
780
|
-
lines.push(
|
|
781
|
-
"",
|
|
782
|
-
"Read a skill with console skill <path>, a file or a document with console skill --file <path>.",
|
|
783
|
-
);
|
|
784
|
-
}
|
|
785
|
-
return lines.join("\n");
|
|
786
|
-
}
|
package/src/cli/help.ts
CHANGED
|
@@ -285,11 +285,12 @@ export const COMMAND_HELP: Readonly<Record<string, CommandHelp>> = {
|
|
|
285
285
|
],
|
|
286
286
|
},
|
|
287
287
|
skills: {
|
|
288
|
-
usage:
|
|
288
|
+
usage:
|
|
289
|
+
"skills | skills <folder> | skills --search <words> [<folder>] [--limit <n>] [--cursor <cursor>]",
|
|
289
290
|
synopsis:
|
|
290
291
|
"The project's pack: its skills; what a folder of it holds; or what words find in it.",
|
|
291
292
|
about:
|
|
292
|
-
"The project's pack,
|
|
293
|
+
"The project's pack, read by the console at the project's address, or the organization's: at a SkillCDN deployment, with the pack token the project holds where the pack is private (ADR-0028), or from a directory on the console's machine for a local address (ADR-0031). Alone: where the pack is and what a client is told of it on connect, then every skill with the path of its SKILL.md and every document, as a connection of your own would list them, and where the console's own skills are on this machine. With a folder (. for the root): what it holds, whole, as browse_repo lays it out for a model: its skills, its folders with what each holds and the README that introduces it, its files. With --search: what the words find, as search_repo does: skills first, with the files of theirs that matched, then documents, in relevance order; words, not meaning, in the language the pack is written in; within the folder when one is named; 10 unless --limit says otherwise, up to 25, and a nextCursor line says when more matched, which --cursor continues. The text is the one an MCP client's model is given, with the reads named as these commands. --json answers with the console's own JSON: what the pack answered, in the shapes of the main repository's REST API, the pages of a folder joined.",
|
|
293
294
|
limits: ["search: 1 to 500 characters; limit: 1 to 25"],
|
|
294
295
|
refusals: [
|
|
295
296
|
"status not_found: the pack is not served to the console; private, with no pack token on the project",
|
|
@@ -301,11 +302,11 @@ export const COMMAND_HELP: Readonly<Record<string, CommandHelp>> = {
|
|
|
301
302
|
synopsis:
|
|
302
303
|
"One skill of the pack whole, its rules first; or with --file a file of the pack, or what a folder holds.",
|
|
303
304
|
about:
|
|
304
|
-
"One skill of the project's pack, whole, as load_skill lays it out for
|
|
305
|
+
"One skill of the project's pack, whole, as load_skill lays it out for a model: the rules of the repository from its root to the nearest manifest, the skill's instructions, the files it includes, then its supporting files and what it refers to; the pages it came in are joined. Read by the console from the pack, with the pack token the project holds where the pack is private, so you need no connection of your own. <path> is the path of the SKILL.md from the repository's root, as console skills lists it, or the URI the pack names it by (skill://<host>/<owner>/<name>/<path>). --file <path> reads a file of the pack instead, whole, as read_repo_file does, or what a folder holds, and takes no skill's path beside it; console skills <folder> shows a folder with more. --json answers with what the pack answered, in the shapes of the main repository's REST API, the pages joined.",
|
|
305
306
|
refusals: [
|
|
306
307
|
"status not_found: the pack is not served to the console; private, with no pack token on the project",
|
|
307
308
|
"status token_invalid: the pack token the project holds no longer works; an owner sets a new one",
|
|
308
|
-
"status failed, for a file:
|
|
309
|
+
"status failed, for a file: the pack will not carry it, too large or not text",
|
|
309
310
|
],
|
|
310
311
|
},
|
|
311
312
|
rules: {
|
|
@@ -370,7 +371,7 @@ export const COMMAND_HELP: Readonly<Record<string, CommandHelp>> = {
|
|
|
370
371
|
'ask "<question>" --option "<label>" --option "<label>" [...] [--body <markdown>|--file <path>] [--wait <seconds>]',
|
|
371
372
|
synopsis:
|
|
372
373
|
"Raises a decision a person must make, with options, and waits a while for the answer.",
|
|
373
|
-
about: `Raises a decision a person must make: the question, the options to choose from, and what they need to know. The run waits for the answer. The command waits 60 seconds for it unless --wait says otherwise, and exits with 3 if it is still to come: keep waiting with \`console decision <id> --wait 100\`, within what your shell gives one command. The decision's id is printed as soon as it is raised. ${ON_THE_RUN}`,
|
|
374
|
+
about: `Raises a decision a person must make: the question, the options to choose from, and what they need to know. The run waits for the answer. The command waits 60 seconds for it unless --wait says otherwise, and exits with 3 if it is still to come: keep waiting with \`console decision <id> --wait 100\`, within what your shell gives one command. The decision's id is printed as soon as it is raised. The person chooses one of the options, or answers in their own words: the answer then names one more option, their words, marked own; act on it as given. ${ON_THE_RUN}`,
|
|
374
375
|
limits: [
|
|
375
376
|
`question: one line, up to ${MAX_QUESTION_LENGTH} characters`,
|
|
376
377
|
`options: ${MIN_OPTIONS} to ${MAX_OPTIONS}, each one line up to ${MAX_OPTION_LABEL_LENGTH} characters`,
|
|
@@ -383,7 +384,7 @@ export const COMMAND_HELP: Readonly<Record<string, CommandHelp>> = {
|
|
|
383
384
|
synopsis:
|
|
384
385
|
"One decision in full; waits for its answer with --wait; writes what followed with --outcome.",
|
|
385
386
|
about:
|
|
386
|
-
"One decision, with its context, its options, its answer and what followed. With --wait, holds on for the answer that long, and exits with 3 if it is still to come. With --outcome, writes down what followed the decision, so that it reads as a record.",
|
|
387
|
+
"One decision, with its context, its options, its answer (one of the options, or the person's own words as one more, marked own) and what followed. With --wait, holds on for the answer that long, and exits with 3 if it is still to come. With --outcome, writes down what followed the decision, so that it reads as a record.",
|
|
387
388
|
limits: [`outcome: ${MARKDOWN}`],
|
|
388
389
|
refusals: ["decision.not_found: no decision has that id"],
|
|
389
390
|
},
|