@skillcdn/console 0.1.24 → 0.3.1

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.
Files changed (156) hide show
  1. package/README.md +8 -7
  2. package/dist/api.d.ts +2 -2
  3. package/dist/api.d.ts.map +1 -1
  4. package/dist/api.js +2 -2
  5. package/dist/api.js.map +1 -1
  6. package/dist/cli/cli.d.ts +1 -1
  7. package/dist/cli/cli.d.ts.map +1 -1
  8. package/dist/cli/cli.js +248 -92
  9. package/dist/cli/cli.js.map +1 -1
  10. package/dist/cli/credentials.d.ts +5 -0
  11. package/dist/cli/credentials.d.ts.map +1 -1
  12. package/dist/cli/credentials.js +2 -0
  13. package/dist/cli/credentials.js.map +1 -1
  14. package/dist/cli/directory.d.ts +7 -0
  15. package/dist/cli/directory.d.ts.map +1 -1
  16. package/dist/cli/directory.js +7 -0
  17. package/dist/cli/directory.js.map +1 -1
  18. package/dist/cli/format.d.ts +13 -28
  19. package/dist/cli/format.d.ts.map +1 -1
  20. package/dist/cli/format.js +74 -274
  21. package/dist/cli/format.js.map +1 -1
  22. package/dist/cli/help.d.ts.map +1 -1
  23. package/dist/cli/help.js +36 -19
  24. package/dist/cli/help.js.map +1 -1
  25. package/dist/cli/pack.d.ts +46 -0
  26. package/dist/cli/pack.d.ts.map +1 -0
  27. package/dist/cli/pack.js +250 -0
  28. package/dist/cli/pack.js.map +1 -0
  29. package/dist/client.d.ts +26 -1
  30. package/dist/client.d.ts.map +1 -1
  31. package/dist/client.js +14 -1
  32. package/dist/client.js.map +1 -1
  33. package/dist/compat.d.ts +1 -1
  34. package/dist/compat.js +1 -1
  35. package/dist/components/calendar.d.ts +5 -1
  36. package/dist/components/calendar.d.ts.map +1 -1
  37. package/dist/components/calendar.js +3 -3
  38. package/dist/components/calendar.js.map +1 -1
  39. package/dist/components/decision-list.d.ts +13 -1
  40. package/dist/components/decision-list.d.ts.map +1 -1
  41. package/dist/components/decision-list.js +74 -29
  42. package/dist/components/decision-list.js.map +1 -1
  43. package/dist/components/event-feed.d.ts.map +1 -1
  44. package/dist/components/event-feed.js +2 -0
  45. package/dist/components/event-feed.js.map +1 -1
  46. package/dist/components/pack-connect.d.ts +23 -0
  47. package/dist/components/pack-connect.d.ts.map +1 -0
  48. package/dist/components/pack-connect.js +86 -0
  49. package/dist/components/pack-connect.js.map +1 -0
  50. package/dist/components/pack-token.d.ts +27 -0
  51. package/dist/components/pack-token.d.ts.map +1 -0
  52. package/dist/components/pack-token.js +11 -0
  53. package/dist/components/pack-token.js.map +1 -0
  54. package/dist/components/paged.d.ts +24 -0
  55. package/dist/components/paged.d.ts.map +1 -1
  56. package/dist/components/paged.js +40 -4
  57. package/dist/components/paged.js.map +1 -1
  58. package/dist/components/projects.d.ts +13 -0
  59. package/dist/components/projects.d.ts.map +1 -1
  60. package/dist/components/projects.js +37 -5
  61. package/dist/components/projects.js.map +1 -1
  62. package/dist/components/skills.d.ts.map +1 -1
  63. package/dist/components/skills.js +8 -4
  64. package/dist/components/skills.js.map +1 -1
  65. package/dist/components/ui.d.ts +2 -0
  66. package/dist/components/ui.d.ts.map +1 -1
  67. package/dist/components/ui.js +7 -2
  68. package/dist/components/ui.js.map +1 -1
  69. package/dist/components/work.d.ts +3 -1
  70. package/dist/components/work.d.ts.map +1 -1
  71. package/dist/components/work.js +1 -1
  72. package/dist/components/work.js.map +1 -1
  73. package/dist/components/workspace.d.ts +46 -0
  74. package/dist/components/workspace.d.ts.map +1 -0
  75. package/dist/components/workspace.js +124 -0
  76. package/dist/components/workspace.js.map +1 -0
  77. package/dist/console.css +268 -5
  78. package/dist/console.d.ts.map +1 -1
  79. package/dist/console.js +62 -23
  80. package/dist/console.js.map +1 -1
  81. package/dist/data.d.ts +16 -1
  82. package/dist/data.d.ts.map +1 -1
  83. package/dist/data.js +64 -2
  84. package/dist/data.js.map +1 -1
  85. package/dist/dates.d.ts +12 -2
  86. package/dist/dates.d.ts.map +1 -1
  87. package/dist/dates.js +20 -2
  88. package/dist/dates.js.map +1 -1
  89. package/dist/i18n/en.d.ts +66 -0
  90. package/dist/i18n/en.d.ts.map +1 -1
  91. package/dist/i18n/en.js +80 -8
  92. package/dist/i18n/en.js.map +1 -1
  93. package/dist/i18n/ko.d.ts.map +1 -1
  94. package/dist/i18n/ko.js +75 -7
  95. package/dist/i18n/ko.js.map +1 -1
  96. package/dist/index.d.ts +5 -2
  97. package/dist/index.d.ts.map +1 -1
  98. package/dist/index.js +5 -2
  99. package/dist/index.js.map +1 -1
  100. package/dist/router.d.ts +10 -5
  101. package/dist/router.d.ts.map +1 -1
  102. package/dist/router.js +24 -9
  103. package/dist/router.js.map +1 -1
  104. package/dist/routes.d.ts +4 -0
  105. package/dist/routes.d.ts.map +1 -1
  106. package/dist/routes.js +4 -0
  107. package/dist/routes.js.map +1 -1
  108. package/dist/schemas.d.ts +500 -158
  109. package/dist/schemas.d.ts.map +1 -1
  110. package/dist/schemas.js +169 -165
  111. package/dist/schemas.js.map +1 -1
  112. package/dist/vocabulary.d.ts +19 -1
  113. package/dist/vocabulary.d.ts.map +1 -1
  114. package/dist/vocabulary.js +16 -0
  115. package/dist/vocabulary.js.map +1 -1
  116. package/docs/specs/cli.md +19 -14
  117. package/docs/specs/rest.md +34 -19
  118. package/package.json +2 -1
  119. package/skills/building-a-console/SKILL.md +5 -5
  120. package/skills/building-a-console/references/the-look-from-a-website.md +39 -0
  121. package/skills/deploying-a-console/SKILL.md +9 -8
  122. package/skills/working-the-board/SKILL.md +5 -5
  123. package/skills/working-the-board/references/setting-up.md +1 -1
  124. package/skills/working-the-board/references/terms.md +2 -0
  125. package/skills/working-the-board/references/the-sentence.md +1 -1
  126. package/src/api.ts +18 -7
  127. package/src/cli/cli.ts +345 -109
  128. package/src/cli/credentials.ts +7 -0
  129. package/src/cli/directory.ts +9 -0
  130. package/src/cli/format.ts +82 -341
  131. package/src/cli/help.ts +43 -19
  132. package/src/cli/pack.ts +356 -0
  133. package/src/client.ts +84 -0
  134. package/src/compat.ts +1 -1
  135. package/src/components/calendar.tsx +8 -2
  136. package/src/components/decision-list.tsx +227 -94
  137. package/src/components/event-feed.tsx +2 -0
  138. package/src/components/pack-connect.tsx +179 -0
  139. package/src/components/pack-token.tsx +74 -0
  140. package/src/components/paged.tsx +72 -3
  141. package/src/components/projects.tsx +108 -9
  142. package/src/components/skills.tsx +51 -33
  143. package/src/components/ui.tsx +16 -3
  144. package/src/components/work.tsx +4 -1
  145. package/src/components/workspace.tsx +298 -0
  146. package/src/console.tsx +176 -29
  147. package/src/data.ts +89 -2
  148. package/src/dates.ts +23 -2
  149. package/src/i18n/en.ts +94 -8
  150. package/src/i18n/ko.ts +84 -7
  151. package/src/index.ts +25 -1
  152. package/src/router.ts +37 -14
  153. package/src/routes.ts +4 -0
  154. package/src/schemas.ts +202 -189
  155. package/src/styles/console.css +268 -5
  156. package/src/vocabulary.ts +25 -0
@@ -12,6 +12,13 @@ import * as z from "zod/mini";
12
12
  // know is dropped on reading.
13
13
  /** The file's name, in the working directory or one above it. */
14
14
  export const DIRECTORY_FILE = ".skillcdn-console.json";
15
+ /**
16
+ * The sentence a checkout's agreement carries to send the agents working there to the console:
17
+ * the one the skill working-the-board keeps (references/the-sentence.md) and this repository's
18
+ * own agreement carries. `console use` prints it, since nothing tells an agent to look until the
19
+ * checkout says so, as `skillcdn use` prints the sentence for a pack.
20
+ */
21
+ export const THE_SENTENCE = "**Bound to a console?** When `.skillcdn-console.json` is in this checkout, or `console whoami` names a project, work the task through that SkillCDN console (`console help` says how).";
15
22
  /** How large the file may be before it is not read: a few names, never more. */
16
23
  const MAX_FILE_CHARS = 16 * 1024;
17
24
  const settingsSchema = z.object({
@@ -1 +1 @@
1
- {"version":3,"file":"directory.js","sourceRoot":"","sources":["../../src/cli/directory.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"directory.js","sourceRoot":"","sources":["../../src/cli/directory.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,11 @@
1
- import type { RestArtifact, RestCategory, RestComment, RestDecision, RestDocument, RestDocumentSummary, RestDocuments, RestGoal, RestListing, RestMember, RestPerson, RestPersonWork, RestProject, RestProjectRules, RestRules, RestRun, RestSkillBrowse, RestSkillFile, RestSkillFind, RestSkillLoad, RestSkillPage, RestSkills, RestTask, RestVersion, RestVersionSummary, RestWork } from "../schemas.js";
1
+ import type { RestArtifact, RestCategory, RestComment, RestDecision, RestDocument, RestDocumentSummary, RestDocuments, RestGoal, RestListing, RestMember, RestPerson, RestPersonWork, RestProject, RestProjectRules, RestRules, RestRun, RestTask, RestVersion, RestVersionSummary, RestWork, RestWorkspace } from "../schemas.js";
2
+ /** Says which time zone the moments printed from now on are in, or none. */
3
+ export declare function setMomentZone(zone: string | undefined): void;
4
+ /**
5
+ * An instant as the command prints it: in the workspace's time zone, as ISO 8601 with its
6
+ * offset (`2026-10-18T15:04:17+09:00`), when a zone is known; else as the API gave it, in UTC.
7
+ */
8
+ export declare function moment(iso: string): string;
2
9
  /** One project: its key, its name, what the person is in it, and what waits in it. */
3
10
  export declare function formatProjectLine(project: RestProject): string;
4
11
  /** One project in full: what it is, how it is marked, and what the person is in it. */
@@ -7,6 +14,8 @@ export declare function formatProject(project: RestProject): string;
7
14
  export declare function formatPersonLine(person: RestPerson): string;
8
15
  /** One login let in that nobody has signed in with yet (ADR-0022). */
9
16
  export declare function formatListingLine(listing: RestListing): string;
17
+ /** The workspace as its Settings page shows it: what it is called, who sees whom, the week, the time zone, where the skills come from, and what tokens may last. */
18
+ export declare function formatWorkspace(workspace: RestWorkspace): string;
10
19
  /** One member of a project: their login, what they are in it, and since when. */
11
20
  export declare function formatMemberLine(member: RestMember): string;
12
21
  /** The line under a page of a listing that has more after it: how to ask for the next page. */
@@ -24,12 +33,6 @@ export declare function formatRunLine(run: RestRun): string;
24
33
  export declare function formatRun(run: RestRun, fileUrl?: (artifactId: string) => string): string;
25
34
  /** What was handed in: the link, or the file with its size and where its bytes are read. */
26
35
  export declare function formatArtifact(artifact: RestArtifact, fileUrl?: (artifactId: string) => string): string;
27
- /**
28
- * The organization's skills: where they are, the pack by name and by count, each skill with
29
- * what an agent loads it by, where a person connects an agent that has no connection to the
30
- * address, and where the console's own skills are on this machine, when the command knows.
31
- */
32
- export declare function formatSkills(skills: RestSkills, ownSkills?: string): string;
33
36
  /** The rules that hold: the workspace's, and what the project adds when the command works in one. */
34
37
  export declare function formatRules(rules: RestProjectRules | RestRules): string;
35
38
  /** One goal: its id, its state, its title, its category, its days, and how far it is. */
@@ -43,8 +46,9 @@ export declare function formatWork(work: RestWork): string;
43
46
  /** Another person's plate: their open tasks, each with its project; no decisions, which wait for anyone. */
44
47
  export declare function formatPersonWork(person: RestPerson, work: RestPersonWork): string;
45
48
  export declare function formatDecisionLine(decision: RestDecision): string;
49
+ /** The options, one a line; the person's own answer, when they wrote one, is the last and says so. */
46
50
  export declare function formatOptions(decision: RestDecision): string;
47
- /** The answer, with who gave it; or that there is none yet. */
51
+ /** The answer, with who gave it, and that it is in their own words when it is; or that there is none yet. */
48
52
  export declare function formatAnswer(decision: RestDecision): string;
49
53
  export declare function formatDecision(decision: RestDecision): string;
50
54
  /** One document in a list: its path, its title, its version, who wrote it last and when. */
@@ -56,24 +60,5 @@ export declare function formatDocument(document: RestDocument, fileUrl?: (fileId
56
60
  export declare function formatVersionLine(version: RestVersionSummary): string;
57
61
  /** One version of a document, with its body as it was. */
58
62
  export declare function formatVersion(path: string, version: RestVersion): string;
59
- /**
60
- * One skill, as load_skill lays it out for a model (ADR-0028): the rules from the repository's
61
- * root to the nearest manifest, the body, the included files, each under a line that names its
62
- * path; then the files the skill has and what it refers to. A skill described only is named and
63
- * pointed at, and nothing of its body is shown.
64
- */
65
- export declare function formatSkillLoad(loaded: RestSkillLoad, pages: readonly RestSkillPage[]): string;
66
- /** A file of the pack as read: its text whole, or what the folder holds. */
67
- export declare function formatSkillFile(read: RestSkillFile, content: string): string;
68
- /**
69
- * What a folder of the pack holds, as browse_repo lays it out: the README that introduces the
70
- * folder, then its skills, its folders with what each holds, and its files, across the pages the
71
- * listing came in.
72
- */
73
- export declare function formatSkillBrowse(browsed: RestSkillBrowse, folders: readonly NonNullable<RestSkillBrowse["folder"]>[]): string;
74
- /**
75
- * What words found in the pack, as search_repo lays it out: skills with the files of theirs that
76
- * matched, documents on their own, in relevance order; words, not meaning.
77
- */
78
- export declare function formatSkillFind(found: RestSkillFind): string;
63
+ /** The text of one path across the pages a skill came in: the fragments joined in order. */
79
64
  //# sourceMappingURL=format.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"format.d.ts","sourceRoot":"","sources":["../../src/cli/format.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,YAAY,EACZ,YAAY,EACZ,WAAW,EACX,YAAY,EACZ,YAAY,EACZ,mBAAmB,EACnB,aAAa,EACb,QAAQ,EACR,WAAW,EACX,UAAU,EACV,UAAU,EACV,cAAc,EACd,WAAW,EACX,gBAAgB,EAChB,SAAS,EACT,OAAO,EACP,eAAe,EAEf,aAAa,EACb,aAAa,EACb,aAAa,EACb,aAAa,EACb,UAAU,EACV,QAAQ,EACR,WAAW,EACX,kBAAkB,EAClB,QAAQ,EACT,MAAM,eAAe,CAAC;AAoBvB,sFAAsF;AACtF,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,WAAW,GAAG,MAAM,CAM9D;AAED,uFAAuF;AACvF,wBAAgB,aAAa,CAAC,OAAO,EAAE,WAAW,GAAG,MAAM,CAW1D;AAED,yIAAyI;AACzI,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,UAAU,GAAG,MAAM,CAK3D;AAKD,sEAAsE;AACtE,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,WAAW,GAAG,MAAM,CAE9D;AAED,iFAAiF;AACjF,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,UAAU,GAAG,MAAM,CAE3D;AAED,+FAA+F;AAC/F,wBAAgB,UAAU,CAAC,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAE/E;AAED,wBAAgB,cAAc,CAAC,IAAI,EAAE,QAAQ,GAAG,MAAM,CAkBrD;AAyBD,oFAAoF;AACpF,wBAAgB,UAAU,CACxB,IAAI,EAAE,QAAQ,EACd,SAAS,CAAC,EAAE,SAAS,YAAY,EAAE,EACnC,IAAI,CAAC,EAAE,SAAS,OAAO,EAAE,EACzB,QAAQ,CAAC,EAAE,SAAS,WAAW,EAAE,GAChC,MAAM,CAmCR;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,WAAW,GAAG,MAAM,CAa1D;AAED,wBAAgB,aAAa,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,CASlD;AAED,sFAAsF;AACtF,wBAAgB,SAAS,CAAC,GAAG,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,MAAM,GAAG,MAAM,CAqBxF;AAED,4FAA4F;AAC5F,wBAAgB,cAAc,CAC5B,QAAQ,EAAE,YAAY,EACtB,OAAO,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,MAAM,GACvC,MAAM,CAMR;AAeD;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,UAAU,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,CA4C3E;AAmBD,qGAAqG;AACrG,wBAAgB,WAAW,CAAC,KAAK,EAAE,gBAAgB,GAAG,SAAS,GAAG,MAAM,CASvE;AAUD,yFAAyF;AACzF,wBAAgB,cAAc,CAAC,IAAI,EAAE,QAAQ,GAAG,MAAM,CAQrD;AAED,yEAAyE;AACzE,wBAAgB,UAAU,CAAC,IAAI,EAAE,QAAQ,EAAE,KAAK,CAAC,EAAE,SAAS,QAAQ,EAAE,GAAG,MAAM,CAgB9E;AAED,kEAAkE;AAClE,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,YAAY,GAAG,MAAM,CAEjE;AAED,2FAA2F;AAC3F,wBAAgB,UAAU,CAAC,IAAI,EAAE,QAAQ,GAAG,MAAM,CAejD;AAED,4GAA4G;AAC5G,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,cAAc,GAAG,MAAM,CAQjF;AAED,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,YAAY,GAAG,MAAM,CAGjE;AAED,wBAAgB,aAAa,CAAC,QAAQ,EAAE,YAAY,GAAG,MAAM,CAE5D;AAED,+DAA+D;AAC/D,wBAAgB,YAAY,CAAC,QAAQ,EAAE,YAAY,GAAG,MAAM,CAa3D;AAED,wBAAgB,cAAc,CAAC,QAAQ,EAAE,YAAY,GAAG,MAAM,CAa7D;AAMD,4FAA4F;AAC5F,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,mBAAmB,GAAG,MAAM,CAMxE;AAED,iEAAiE;AACjE,wBAAgB,eAAe,CAAC,OAAO,EAAE,aAAa,GAAG,MAAM,CAS9D;AAED,oGAAoG;AACpG,wBAAgB,cAAc,CAC5B,QAAQ,EAAE,YAAY,EACtB,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,MAAM,GACnC,MAAM,CAkCR;AAED,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,kBAAkB,GAAG,MAAM,CAErE;AAED,0DAA0D;AAC1D,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,GAAG,MAAM,CAMxE;AAkBD;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,aAAa,EAAE,KAAK,EAAE,SAAS,aAAa,EAAE,GAAG,MAAM,CAqE9F;AAED,4EAA4E;AAC5E,wBAAgB,eAAe,CAAC,IAAI,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CA+B5E;AAkCD;;;;GAIG;AACH,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,eAAe,EACxB,OAAO,EAAE,SAAS,WAAW,CAAC,eAAe,CAAC,QAAQ,CAAC,CAAC,EAAE,GACzD,MAAM,CAmCR;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,aAAa,GAAG,MAAM,CA6C5D"}
1
+ {"version":3,"file":"format.d.ts","sourceRoot":"","sources":["../../src/cli/format.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,YAAY,EACZ,YAAY,EACZ,WAAW,EACX,YAAY,EACZ,YAAY,EACZ,mBAAmB,EACnB,aAAa,EACb,QAAQ,EACR,WAAW,EACX,UAAU,EACV,UAAU,EACV,cAAc,EACd,WAAW,EACX,gBAAgB,EAChB,SAAS,EACT,OAAO,EACP,QAAQ,EACR,WAAW,EACX,kBAAkB,EAClB,QAAQ,EACR,aAAa,EACd,MAAM,eAAe,CAAC;AAWvB,4EAA4E;AAC5E,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAE5D;AAED;;;GAGG;AACH,wBAAgB,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CA4B1C;AAcD,sFAAsF;AACtF,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,WAAW,GAAG,MAAM,CAM9D;AAED,uFAAuF;AACvF,wBAAgB,aAAa,CAAC,OAAO,EAAE,WAAW,GAAG,MAAM,CAW1D;AAED,yIAAyI;AACzI,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,UAAU,GAAG,MAAM,CAK3D;AAKD,sEAAsE;AACtE,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,WAAW,GAAG,MAAM,CAE9D;AAED,oKAAoK;AACpK,wBAAgB,eAAe,CAAC,SAAS,EAAE,aAAa,GAAG,MAAM,CAahE;AAED,iFAAiF;AACjF,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,UAAU,GAAG,MAAM,CAE3D;AAED,+FAA+F;AAC/F,wBAAgB,UAAU,CAAC,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAE/E;AAED,wBAAgB,cAAc,CAAC,IAAI,EAAE,QAAQ,GAAG,MAAM,CAkBrD;AAyBD,oFAAoF;AACpF,wBAAgB,UAAU,CACxB,IAAI,EAAE,QAAQ,EACd,SAAS,CAAC,EAAE,SAAS,YAAY,EAAE,EACnC,IAAI,CAAC,EAAE,SAAS,OAAO,EAAE,EACzB,QAAQ,CAAC,EAAE,SAAS,WAAW,EAAE,GAChC,MAAM,CAmCR;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,WAAW,GAAG,MAAM,CAa1D;AAED,wBAAgB,aAAa,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,CASlD;AAED,sFAAsF;AACtF,wBAAgB,SAAS,CAAC,GAAG,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,MAAM,GAAG,MAAM,CAqBxF;AAED,4FAA4F;AAC5F,wBAAgB,cAAc,CAC5B,QAAQ,EAAE,YAAY,EACtB,OAAO,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,MAAM,GACvC,MAAM,CAMR;AAmBD,qGAAqG;AACrG,wBAAgB,WAAW,CAAC,KAAK,EAAE,gBAAgB,GAAG,SAAS,GAAG,MAAM,CASvE;AAUD,yFAAyF;AACzF,wBAAgB,cAAc,CAAC,IAAI,EAAE,QAAQ,GAAG,MAAM,CAQrD;AAED,yEAAyE;AACzE,wBAAgB,UAAU,CAAC,IAAI,EAAE,QAAQ,EAAE,KAAK,CAAC,EAAE,SAAS,QAAQ,EAAE,GAAG,MAAM,CAgB9E;AAED,kEAAkE;AAClE,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,YAAY,GAAG,MAAM,CAEjE;AAED,2FAA2F;AAC3F,wBAAgB,UAAU,CAAC,IAAI,EAAE,QAAQ,GAAG,MAAM,CAejD;AAED,4GAA4G;AAC5G,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,cAAc,GAAG,MAAM,CAQjF;AAED,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,YAAY,GAAG,MAAM,CAGjE;AAED,sGAAsG;AACtG,wBAAgB,aAAa,CAAC,QAAQ,EAAE,YAAY,GAAG,MAAM,CAO5D;AAED,6GAA6G;AAC7G,wBAAgB,YAAY,CAAC,QAAQ,EAAE,YAAY,GAAG,MAAM,CAa3D;AAED,wBAAgB,cAAc,CAAC,QAAQ,EAAE,YAAY,GAAG,MAAM,CAa7D;AAMD,4FAA4F;AAC5F,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,mBAAmB,GAAG,MAAM,CAMxE;AAED,iEAAiE;AACjE,wBAAgB,eAAe,CAAC,OAAO,EAAE,aAAa,GAAG,MAAM,CAS9D;AAED,oGAAoG;AACpG,wBAAgB,cAAc,CAC5B,QAAQ,EAAE,YAAY,EACtB,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,MAAM,GACnC,MAAM,CAkCR;AAED,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,kBAAkB,GAAG,MAAM,CAErE;AAED,0DAA0D;AAC1D,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,GAAG,MAAM,CAMxE;AAED,4FAA4F"}
@@ -2,6 +2,45 @@
2
2
  // Plain text, for an agent to read and a person to skim; ids are given, since the commands take
3
3
  // them, and the words are the vocabulary's own, since the options take those.
4
4
  const plural = (count, word) => `${count} ${word}${count === 1 ? "" : "s"}`;
5
+ /** The time zone moments are printed in: the workspace's, as the command last learned it (ADR-0035); none leaves them as the API gives them. */
6
+ let momentZone;
7
+ /** Says which time zone the moments printed from now on are in, or none. */
8
+ export function setMomentZone(zone) {
9
+ momentZone = zone;
10
+ }
11
+ /**
12
+ * An instant as the command prints it: in the workspace's time zone, as ISO 8601 with its
13
+ * offset (`2026-10-18T15:04:17+09:00`), when a zone is known; else as the API gave it, in UTC.
14
+ */
15
+ export function moment(iso) {
16
+ if (momentZone === undefined) {
17
+ return iso;
18
+ }
19
+ const date = new Date(iso);
20
+ if (Number.isNaN(date.getTime())) {
21
+ return iso;
22
+ }
23
+ let parts;
24
+ try {
25
+ parts = new Intl.DateTimeFormat("en-US", {
26
+ timeZone: momentZone,
27
+ hourCycle: "h23",
28
+ year: "numeric",
29
+ month: "2-digit",
30
+ day: "2-digit",
31
+ hour: "2-digit",
32
+ minute: "2-digit",
33
+ second: "2-digit",
34
+ timeZoneName: "longOffset",
35
+ }).formatToParts(date);
36
+ }
37
+ catch {
38
+ return iso;
39
+ }
40
+ const of = (type) => parts.find((part) => part.type === type)?.value ?? "";
41
+ const offset = of("timeZoneName").replace("GMT", "");
42
+ return `${of("year")}-${of("month")}-${of("day")}T${of("hour")}:${of("minute")}:${of("second")}${offset === "" ? "Z" : offset}`;
43
+ }
5
44
  const indent = (text) => text
6
45
  .trimEnd()
7
46
  .split("\n")
@@ -24,7 +63,7 @@ export function formatProject(project) {
24
63
  `project ${project.key}: ${project.name}`,
25
64
  `visibility: ${project.visibility} role: ${project.role} skills: ${project.skillsAddress ?? "the organization's"}`,
26
65
  `color: ${project.color ?? "none"} symbol: ${project.symbol ?? "none"} image: ${project.icon === null ? "none" : project.icon.contentType}`,
27
- `pack token: ${project.packToken === null ? "none" : `set ${project.packToken.setAt}`}`,
66
+ `pack token: ${project.packToken === null ? "none" : `set ${moment(project.packToken.setAt)}`}`,
28
67
  ];
29
68
  if (project.description.trim().length > 0) {
30
69
  lines.push("", project.description.trimEnd());
@@ -44,9 +83,24 @@ const HOST_NAMES = { gh: "GitHub", google: "Google" };
44
83
  export function formatListingLine(listing) {
45
84
  return `${listing.login} (let in at ${HOST_NAMES[listing.host]}, not signed in yet)`;
46
85
  }
86
+ /** The workspace as its Settings page shows it: what it is called, who sees whom, the week, the time zone, where the skills come from, and what tokens may last. */
87
+ export function formatWorkspace(workspace) {
88
+ const visibility = workspace.peopleVisibility ?? "everyone";
89
+ const zone = workspace.timeZone ?? null;
90
+ const token = workspace.skills.packToken ?? null;
91
+ return [
92
+ `workspace ${workspace.name}`,
93
+ `people visibility: ${visibility} (${visibility === "everyone" ? "everyone sees everyone" : "a member sees only the people they share a project with; an administrator sees everyone"})`,
94
+ `week begins on: ${workspace.weekStart ?? "auto"} (auto: the system default, as each device has it)`,
95
+ `time zone: ${zone ?? "none"} (${zone === null ? "moments are printed as the API gives them, in UTC" : "moments are printed in it, as ISO 8601 with its offset"})`,
96
+ `skills: ${workspace.skills.address ?? "no address of the organization's"} at ${workspace.skills.source}`,
97
+ `SkillCDN token: ${token === null ? "none" : `set ${moment(token.setAt)}`} (${token === null ? "the organization's pack is read with none" : "the organization's pack is read with it by a project with no address and no token of its own"})`,
98
+ `token days at most: ${workspace.tokenDaysAtMost ?? "a person chooses"}`,
99
+ ].join("\n");
100
+ }
47
101
  /** One member of a project: their login, what they are in it, and since when. */
48
102
  export function formatMemberLine(member) {
49
- return `${member.person.login} ${member.role} (since ${member.addedAt.slice(0, 10)})`;
103
+ return `${member.person.login} ${member.role} (since ${moment(member.addedAt).slice(0, 10)})`;
50
104
  }
51
105
  /** The line under a page of a listing that has more after it: how to ask for the next page. */
52
106
  export function formatMore(more, limit, offset) {
@@ -84,9 +138,9 @@ function scheduleLines(task) {
84
138
  lines.push(plan.join(" "));
85
139
  }
86
140
  const happened = [
87
- task.startedAt === null ? undefined : `started: ${task.startedAt}`,
88
- task.doneAt === null ? undefined : `done: ${task.doneAt}`,
89
- task.archivedAt === null ? undefined : `archived: ${task.archivedAt}`,
141
+ task.startedAt === null ? undefined : `started: ${moment(task.startedAt)}`,
142
+ task.doneAt === null ? undefined : `done: ${moment(task.doneAt)}`,
143
+ task.archivedAt === null ? undefined : `archived: ${moment(task.archivedAt)}`,
90
144
  ].filter((part) => part !== undefined);
91
145
  if (happened.length > 0) {
92
146
  lines.push(happened.join(" "));
@@ -136,7 +190,7 @@ export function formatTask(task, decisions, runs, comments) {
136
190
  */
137
191
  export function formatComment(comment) {
138
192
  const who = comment.agent === null ? comment.author.login : `${comment.author.login} as ${comment.agent}`;
139
- const lines = [` ${who}, ${comment.createdAt}, comment ${comment.id}:`];
193
+ const lines = [` ${who}, ${moment(comment.createdAt)}, comment ${comment.id}:`];
140
194
  if (comment.body.trim().length > 0) {
141
195
  lines.push(indent(comment.body));
142
196
  }
@@ -151,7 +205,7 @@ export function formatRunLine(run) {
151
205
  notes.push(`waiting for decision ${run.waitingFor}`);
152
206
  }
153
207
  if (run.endedAt === null) {
154
- notes.push(`last heard ${run.lastHeardAt}`);
208
+ notes.push(`last heard ${moment(run.lastHeardAt)}`);
155
209
  }
156
210
  return `${run.id} ${run.status} ${run.agent} for ${run.person.login} task #${run.taskNumber} (${notes.join(", ")})`;
157
211
  }
@@ -159,7 +213,7 @@ export function formatRunLine(run) {
159
213
  export function formatRun(run, fileUrl) {
160
214
  const lines = [
161
215
  formatRunLine(run),
162
- `started: ${run.startedAt}${run.endedAt === null ? "" : ` ended: ${run.endedAt}`}`,
216
+ `started: ${moment(run.startedAt)}${run.endedAt === null ? "" : ` ended: ${moment(run.endedAt)}`}`,
163
217
  ];
164
218
  if (run.summary !== null) {
165
219
  lines.push("", "summary:", indent(run.summary));
@@ -167,7 +221,7 @@ export function formatRun(run, fileUrl) {
167
221
  if (run.reports.length > 0) {
168
222
  lines.push("", "reports:");
169
223
  for (const report of run.reports) {
170
- lines.push(` [${report.createdAt}]`, indent(report.body));
224
+ lines.push(` [${moment(report.createdAt)}]`, indent(report.body));
171
225
  }
172
226
  }
173
227
  if (run.artifacts.length > 0) {
@@ -185,59 +239,12 @@ export function formatArtifact(artifact, fileUrl) {
185
239
  : `${artifact.file.name} (${artifact.file.size} bytes, ${artifact.file.contentType}${fileUrl === undefined ? "" : `; read at ${fileUrl(artifact.id)}`}; console file ${artifact.id})`;
186
240
  return artifact.label === null ? what : `${artifact.label}: ${what}`;
187
241
  }
188
- const SKILLS_WORDS = {
189
- indexing: "SkillCDN is still indexing the repository; ask again in a moment.",
190
- failed: "SkillCDN could not index the repository.",
191
- not_found: "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).",
192
- token_invalid: "The pack token the project holds no longer works at SkillCDN: an owner sets a new one (console project pack-token <key> --stdin).",
193
- unavailable: "SkillCDN could not be reached; ask again later.",
194
- };
195
- /** A count with its noun: `1 skill`, `2 skills`. */
196
- const counted = (n, noun) => `${n} ${noun}${n === 1 ? "" : "s"}`;
197
- /**
198
- * The organization's skills: where they are, the pack by name and by count, each skill with
199
- * what an agent loads it by, where a person connects an agent that has no connection to the
200
- * address, and where the console's own skills are on this machine, when the command knows.
201
- */
202
- export function formatSkills(skills, ownSkills) {
203
- const own = ownSkills === undefined
204
- ? []
205
- : ["", `The console's own skills, for working the board: ${ownSkills}`];
206
- if (skills.status === "none" || skills.address === null || skills.page === null) {
207
- return ["No skills address: neither this project nor the console names one.", ...own].join("\n");
208
- }
209
- const head = `skills at ${skills.address}, served by ${skills.source}: ${skills.status}`;
210
- if (skills.status !== "ready") {
211
- return [head, SKILLS_WORDS[skills.status], ...own].join("\n");
212
- }
213
- const lines = [head];
214
- if (skills.pack !== undefined) {
215
- const named = [skills.pack.name, skills.pack.description]
216
- .filter((text) => text !== null)
217
- .join(" ");
218
- if (named !== "") {
219
- lines.push(named);
220
- }
221
- }
222
- if (skills.counts !== undefined) {
223
- lines.push(`${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.`);
224
- }
225
- if (skills.items.length === 0) {
226
- lines.push("No skills at this address.");
227
- }
228
- // The path, which console skill takes, and the URI beside it, which a host's own connection takes.
229
- for (const skill of skills.items) {
230
- lines.push(`${skill.name} ${skill.description}`, ` ${skill.path}${skill.uri === null ? "" : ` ${skill.uri}`}`);
231
- }
232
- lines.push("", `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.`, ...own);
233
- return lines.join("\n");
234
- }
235
242
  /** One half of the rules: where it comes from, and the text as it stands. */
236
243
  function formatRulesHalf(where, rules) {
237
244
  const page = rules.page;
238
245
  const facts = page === null
239
246
  ? undefined
240
- : `v${page.version}, by ${writer(page.updatedBy, page.agent)}; ${page.updatedAt}`;
247
+ : `v${page.version}, by ${writer(page.updatedBy, page.agent)}; ${moment(page.updatedAt)}`;
241
248
  if (rules.source === "none" || rules.body === null) {
242
249
  return `Rules of ${where}: none of its own; the workspace's hold.`;
243
250
  }
@@ -328,18 +335,21 @@ export function formatDecisionLine(decision) {
328
335
  const state = decision.answer === null ? "waiting" : `answered ${decision.answer.option}`;
329
336
  return `${decision.id} ${state} ${decision.question} (asked by ${asker(decision)})`;
330
337
  }
338
+ /** The options, one a line; the person's own answer, when they wrote one, is the last and says so. */
331
339
  export function formatOptions(decision) {
332
- return decision.options.map((option) => ` ${option.id}) ${option.label}`).join("\n");
340
+ return decision.options
341
+ .map((option) => ` ${option.id}) ${option.label}${option.own === true ? " (the person's own answer, not one given)" : ""}`)
342
+ .join("\n");
333
343
  }
334
- /** The answer, with who gave it; or that there is none yet. */
344
+ /** The answer, with who gave it, and that it is in their own words when it is; or that there is none yet. */
335
345
  export function formatAnswer(decision) {
336
346
  const { answer } = decision;
337
347
  if (answer === null) {
338
348
  return "waits for a person.";
339
349
  }
340
- const label = decision.options.find((option) => option.id === answer.option)?.label;
350
+ const chosen = decision.options.find((option) => option.id === answer.option);
341
351
  const lines = [
342
- `Answered: ${answer.option}) ${label ?? answer.option}, by ${answer.by.login} at ${answer.at}`,
352
+ `Answered: ${answer.option}) ${chosen?.label ?? answer.option}${chosen?.own === true ? ", in their own words" : ""}, by ${answer.by.login} at ${answer.at}`,
343
353
  ];
344
354
  if (answer.note !== null && answer.note.length > 0) {
345
355
  lines.push(`Note: ${answer.note}`);
@@ -368,7 +378,7 @@ export function formatDocumentLine(document) {
368
378
  if (document.archivedAt !== null) {
369
379
  notes.push("archived");
370
380
  }
371
- return `${document.path} ${document.title} (${notes.join(", ")}; ${document.updatedAt})`;
381
+ return `${document.path} ${document.title} (${notes.join(", ")}; ${moment(document.updatedAt)})`;
372
382
  }
373
383
  /** A folder's folders and pages, or the pages a search found. */
374
384
  export function formatDocuments(listing) {
@@ -385,7 +395,7 @@ export function formatDocuments(listing) {
385
395
  export function formatDocument(document, fileUrl) {
386
396
  const lines = [
387
397
  `${document.path}: ${document.title}`,
388
- `version ${document.version}, by ${writer(document.updatedBy, document.agent)} at ${document.updatedAt}${document.archivedAt === null ? "" : `; archived ${document.archivedAt}`}`,
398
+ `version ${document.version}, by ${writer(document.updatedBy, document.agent)} at ${moment(document.updatedAt)}${document.archivedAt === null ? "" : `; archived ${moment(document.archivedAt)}`}`,
389
399
  `id: ${document.id}`,
390
400
  ];
391
401
  if (document.body.trim().length > 0) {
@@ -414,7 +424,7 @@ export function formatDocument(document, fileUrl) {
414
424
  return lines.join("\n");
415
425
  }
416
426
  export function formatVersionLine(version) {
417
- return `v${version.number} ${version.title} (by ${writer(version.author, version.agent)}; ${version.createdAt})`;
427
+ return `v${version.number} ${version.title} (by ${writer(version.author, version.agent)}; ${moment(version.createdAt)})`;
418
428
  }
419
429
  /** One version of a document, with its body as it was. */
420
430
  export function formatVersion(path, version) {
@@ -425,214 +435,4 @@ export function formatVersion(path, version) {
425
435
  return lines.join("\n");
426
436
  }
427
437
  /** The text of one path across the pages a skill came in: the fragments joined in order. */
428
- function joinTexts(pages, pick) {
429
- const joined = new Map();
430
- for (const page of pages) {
431
- for (const text of pick(page)) {
432
- joined.set(text.path, (joined.get(text.path) ?? "") + text.body);
433
- }
434
- }
435
- return [...joined.entries()].map(([path, body]) => ({ path, body }));
436
- }
437
- const NO_ADDRESS = "No skills address: neither this project nor the console names one.";
438
- /**
439
- * One skill, as load_skill lays it out for a model (ADR-0028): the rules from the repository's
440
- * root to the nearest manifest, the body, the included files, each under a line that names its
441
- * path; then the files the skill has and what it refers to. A skill described only is named and
442
- * pointed at, and nothing of its body is shown.
443
- */
444
- export function formatSkillLoad(loaded, pages) {
445
- if (loaded.status === "none" || loaded.address === null) {
446
- return NO_ADDRESS;
447
- }
448
- const head = `skill at ${loaded.address}, served by ${loaded.source}: ${loaded.status}`;
449
- if (loaded.status !== "ready") {
450
- return [head, SKILLS_WORDS[loaded.status]].join("\n");
451
- }
452
- const [first] = pages;
453
- if (first === undefined) {
454
- return [head, "Nothing was read."].join("\n");
455
- }
456
- const last = pages[pages.length - 1] ?? first;
457
- const lines = [
458
- `${first.name} ${first.description}`,
459
- `skill ${first.path} at ${loaded.address}, served by ${loaded.source}`,
460
- ];
461
- if (first.serving.license !== null) {
462
- lines.push(`license: ${first.serving.license}`);
463
- }
464
- if (!first.serving.full) {
465
- lines.push("", `Described only: the license keeps the skill at its source. Read it there: ${first.serving.sourceUrl ?? loaded.page ?? loaded.source}`);
466
- return lines.join("\n");
467
- }
468
- for (const rule of joinTexts(pages, (page) => page.rules)) {
469
- lines.push("", `--- applicable rules: ${rule.path} ---`, rule.body.trimEnd());
470
- }
471
- lines.push("", `--- skill: ${first.path} ---`, pages
472
- .map((page) => page.body)
473
- .join("")
474
- .trimEnd());
475
- for (const file of joinTexts(pages, (page) => page.included)) {
476
- lines.push("", `--- included file: ${file.path} ---`, file.body.trimEnd());
477
- }
478
- if (!last.complete) {
479
- lines.push("", "The skill did not come whole: the deployment stopped before the end.");
480
- }
481
- if (last.files.length > 0) {
482
- lines.push("", `Files of the skill, read with console skill --file <path>: ${last.files.join(", ")}`);
483
- }
484
- if (last.references.length > 0) {
485
- lines.push(`References: ${last.references
486
- .map((reference) => reference.status === "available"
487
- ? reference.path
488
- : `${reference.path} (${reference.status})`)
489
- .join(", ")}`);
490
- }
491
- if (last.warnings.length > 0) {
492
- lines.push(`Warnings: ${last.warnings.join("; ")}`);
493
- }
494
- lines.push("", "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.");
495
- return lines.join("\n");
496
- }
497
- /** A file of the pack as read: its text whole, or what the folder holds. */
498
- export function formatSkillFile(read, content) {
499
- if (read.status === "none" || read.address === null) {
500
- return NO_ADDRESS;
501
- }
502
- const head = `file at ${read.address}, served by ${read.source}: ${read.status}`;
503
- if (read.status !== "ready") {
504
- return [
505
- head,
506
- read.status === "failed"
507
- ? "SkillCDN will not carry this file: it is too large, or not text. Read it at the repository."
508
- : SKILLS_WORDS[read.status],
509
- ].join("\n");
510
- }
511
- if (read.folder !== null) {
512
- return [
513
- `folder ${read.folder.path} at ${read.address}${read.folder.truncated ? " (cut)" : ""}`,
514
- ...read.folder.entries.map((entry) => `${entry.kind === "directory" ? "d" : "f"} ${entry.path}${entry.size === null ? "" : ` ${entry.size}`}`),
515
- "",
516
- "console skills <folder> shows a folder with its skills marked, what each folder holds and the README that introduces it.",
517
- ].join("\n");
518
- }
519
- if (read.file === null) {
520
- return `${head}: nothing was read.`;
521
- }
522
- return [
523
- `--- file: ${read.file.path} (${read.file.totalLength} characters) ---`,
524
- content.trimEnd(),
525
- ].join("\n");
526
- }
527
- /** One entry of a browsed folder: what it is, its path, its words, and the facts of its kind. */
528
- function formatBrowseEntry(entry) {
529
- const facts = [];
530
- if (entry.kind === "directory") {
531
- if (entry.skillCount > 0) {
532
- facts.push(counted(entry.skillCount, "skill"));
533
- }
534
- if (entry.documentCount > 0) {
535
- facts.push(counted(entry.documentCount, "document"));
536
- }
537
- if (entry.overviewPath !== null) {
538
- facts.push(`README ${entry.overviewPath}`);
539
- }
540
- }
541
- if (entry.kind === "skill") {
542
- if (entry.license !== null) {
543
- facts.push(entry.license);
544
- }
545
- if (entry.describedOnly) {
546
- facts.push("described only");
547
- }
548
- }
549
- if (entry.kind === "file" && entry.size !== null) {
550
- facts.push(`${entry.size} bytes`);
551
- }
552
- const words = [entry.name, entry.description]
553
- .filter((text) => text !== null && text !== "")
554
- .join(" ");
555
- const mark = entry.kind === "skill" ? "skill" : entry.kind === "directory" ? "d" : "f";
556
- return `${mark} ${entry.path}${words === "" ? "" : ` ${words}`}${facts.length === 0 ? "" : ` (${facts.join("; ")})`}`;
557
- }
558
- /**
559
- * What a folder of the pack holds, as browse_repo lays it out: the README that introduces the
560
- * folder, then its skills, its folders with what each holds, and its files, across the pages the
561
- * listing came in.
562
- */
563
- export function formatSkillBrowse(browsed, folders) {
564
- if (browsed.status === "none" || browsed.address === null) {
565
- return NO_ADDRESS;
566
- }
567
- const head = `folder at ${browsed.address}, served by ${browsed.source}: ${browsed.status}`;
568
- if (browsed.status !== "ready") {
569
- return [head, SKILLS_WORDS[browsed.status]].join("\n");
570
- }
571
- const [first] = folders;
572
- if (first === undefined) {
573
- return [head, "Nothing was read."].join("\n");
574
- }
575
- const last = folders[folders.length - 1] ?? first;
576
- const lines = [`folder ${first.path === "" ? "/" : first.path} at ${browsed.address}`];
577
- if (first.overview !== null) {
578
- const words = [first.overview.title, first.overview.description]
579
- .filter((text) => text !== null && text !== "")
580
- .join(" ");
581
- lines.push(` ${words === "" ? "" : `${words} `}(README: ${first.overview.path})`);
582
- }
583
- const entries = folders.flatMap((folder) => folder.entries);
584
- if (entries.length === 0) {
585
- lines.push("Nothing in this folder.");
586
- }
587
- for (const entry of entries) {
588
- lines.push(formatBrowseEntry(entry));
589
- }
590
- if (last.nextCursor !== null) {
591
- lines.push("More entries: the listing stopped before the end of the folder.");
592
- }
593
- lines.push("", "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>.");
594
- return lines.join("\n");
595
- }
596
- /**
597
- * What words found in the pack, as search_repo lays it out: skills with the files of theirs that
598
- * matched, documents on their own, in relevance order; words, not meaning.
599
- */
600
- export function formatSkillFind(found) {
601
- if (found.status === "none" || found.address === null) {
602
- return NO_ADDRESS;
603
- }
604
- const head = `search at ${found.address}, served by ${found.source}: ${found.status}`;
605
- if (found.status !== "ready") {
606
- return [head, SKILLS_WORDS[found.status]].join("\n");
607
- }
608
- if (found.found === null) {
609
- return [head, "Nothing was read."].join("\n");
610
- }
611
- const { query, path, items, nextCursor } = found.found;
612
- const where = path === null || path === "" ? "" : ` within ${path}`;
613
- const lines = [
614
- `found for "${query}"${where} at ${found.address}: ${counted(items.length, "result")}`,
615
- ];
616
- for (const item of items) {
617
- if (item.kind === "skill") {
618
- lines.push(`skill ${item.path} ${item.name} ${item.description}${item.describedOnly ? " (described only)" : ""}`);
619
- for (const file of item.files) {
620
- lines.push(` file ${file.path}${file.title === null ? "" : ` ${file.title}`}`);
621
- }
622
- if (item.moreFiles > 0) {
623
- lines.push(` and ${counted(item.moreFiles, "more file")}`);
624
- }
625
- }
626
- else {
627
- lines.push(`document ${item.path}${item.title === null ? "" : ` ${item.title}`}${item.summary === null ? "" : ` ${item.summary}`}`);
628
- }
629
- }
630
- if (nextCursor !== null) {
631
- lines.push("More matched: narrow the words, or search within a folder (console skills <folder> --search <words>).");
632
- }
633
- if (items.length > 0) {
634
- lines.push("", "Read a skill with console skill <path>, a file or a document with console skill --file <path>.");
635
- }
636
- return lines.join("\n");
637
- }
638
438
  //# sourceMappingURL=format.js.map