@skillcdn/console 0.1.17 → 0.1.19

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 (154) hide show
  1. package/README.md +4 -4
  2. package/SKILLCDN.md +1 -1
  3. package/dist/api.d.ts +3 -2
  4. package/dist/api.d.ts.map +1 -1
  5. package/dist/api.js +2 -1
  6. package/dist/api.js.map +1 -1
  7. package/dist/cli/cli.d.ts +11 -1
  8. package/dist/cli/cli.d.ts.map +1 -1
  9. package/dist/cli/cli.js +496 -51
  10. package/dist/cli/cli.js.map +1 -1
  11. package/dist/cli/credentials.d.ts +102 -3
  12. package/dist/cli/credentials.d.ts.map +1 -1
  13. package/dist/cli/credentials.js +177 -8
  14. package/dist/cli/credentials.js.map +1 -1
  15. package/dist/cli/directory.d.ts +6 -0
  16. package/dist/cli/directory.d.ts.map +1 -1
  17. package/dist/cli/directory.js +37 -6
  18. package/dist/cli/directory.js.map +1 -1
  19. package/dist/cli/format.d.ts +11 -2
  20. package/dist/cli/format.d.ts.map +1 -1
  21. package/dist/cli/format.js +114 -5
  22. package/dist/cli/format.js.map +1 -1
  23. package/dist/cli/help.d.ts.map +1 -1
  24. package/dist/cli/help.js +49 -25
  25. package/dist/cli/help.js.map +1 -1
  26. package/dist/cli/install.d.ts +21 -0
  27. package/dist/cli/install.d.ts.map +1 -0
  28. package/dist/cli/install.js +87 -0
  29. package/dist/cli/install.js.map +1 -0
  30. package/dist/cli/main.js +22 -3
  31. package/dist/cli/main.js.map +1 -1
  32. package/dist/cli/notices.d.ts +13 -0
  33. package/dist/cli/notices.d.ts.map +1 -0
  34. package/dist/cli/notices.js +31 -0
  35. package/dist/cli/notices.js.map +1 -0
  36. package/dist/client.d.ts +36 -3
  37. package/dist/client.d.ts.map +1 -1
  38. package/dist/client.js +22 -4
  39. package/dist/client.js.map +1 -1
  40. package/dist/compat.d.ts +66 -0
  41. package/dist/compat.d.ts.map +1 -0
  42. package/dist/compat.js +115 -0
  43. package/dist/compat.js.map +1 -0
  44. package/dist/components/board.d.ts +9 -1
  45. package/dist/components/board.d.ts.map +1 -1
  46. package/dist/components/board.js +82 -5
  47. package/dist/components/board.js.map +1 -1
  48. package/dist/components/calendar.d.ts +3 -1
  49. package/dist/components/calendar.d.ts.map +1 -1
  50. package/dist/components/calendar.js +21 -2
  51. package/dist/components/calendar.js.map +1 -1
  52. package/dist/components/comments.d.ts.map +1 -1
  53. package/dist/components/comments.js +12 -4
  54. package/dist/components/comments.js.map +1 -1
  55. package/dist/components/event-feed.d.ts.map +1 -1
  56. package/dist/components/event-feed.js +4 -0
  57. package/dist/components/event-feed.js.map +1 -1
  58. package/dist/components/goals.d.ts +20 -2
  59. package/dist/components/goals.d.ts.map +1 -1
  60. package/dist/components/goals.js +50 -13
  61. package/dist/components/goals.js.map +1 -1
  62. package/dist/components/markdown.d.ts +6 -0
  63. package/dist/components/markdown.d.ts.map +1 -1
  64. package/dist/components/markdown.js +7 -0
  65. package/dist/components/markdown.js.map +1 -1
  66. package/dist/components/pictures.d.ts +68 -0
  67. package/dist/components/pictures.d.ts.map +1 -0
  68. package/dist/components/pictures.js +213 -0
  69. package/dist/components/pictures.js.map +1 -0
  70. package/dist/components/projects.d.ts +12 -0
  71. package/dist/components/projects.d.ts.map +1 -1
  72. package/dist/components/projects.js +15 -0
  73. package/dist/components/projects.js.map +1 -1
  74. package/dist/components/roadmap.d.ts +37 -0
  75. package/dist/components/roadmap.d.ts.map +1 -0
  76. package/dist/components/roadmap.js +76 -0
  77. package/dist/components/roadmap.js.map +1 -0
  78. package/dist/components/task-view.d.ts +3 -0
  79. package/dist/components/task-view.d.ts.map +1 -1
  80. package/dist/components/task-view.js +6 -4
  81. package/dist/components/task-view.js.map +1 -1
  82. package/dist/components/tokens.d.ts +2 -0
  83. package/dist/components/tokens.d.ts.map +1 -1
  84. package/dist/components/tokens.js +13 -3
  85. package/dist/components/tokens.js.map +1 -1
  86. package/dist/console.css +486 -3
  87. package/dist/console.d.ts.map +1 -1
  88. package/dist/console.js +132 -17
  89. package/dist/console.js.map +1 -1
  90. package/dist/data.d.ts +16 -1
  91. package/dist/data.d.ts.map +1 -1
  92. package/dist/data.js +48 -3
  93. package/dist/data.js.map +1 -1
  94. package/dist/i18n/en.d.ts +76 -0
  95. package/dist/i18n/en.d.ts.map +1 -1
  96. package/dist/i18n/en.js +74 -2
  97. package/dist/i18n/en.js.map +1 -1
  98. package/dist/i18n/ko.d.ts.map +1 -1
  99. package/dist/i18n/ko.js +74 -2
  100. package/dist/i18n/ko.js.map +1 -1
  101. package/dist/index.d.ts +6 -4
  102. package/dist/index.d.ts.map +1 -1
  103. package/dist/index.js +6 -4
  104. package/dist/index.js.map +1 -1
  105. package/dist/router.d.ts +31 -7
  106. package/dist/router.d.ts.map +1 -1
  107. package/dist/router.js +48 -8
  108. package/dist/router.js.map +1 -1
  109. package/dist/rules.js +5 -5
  110. package/dist/rules.js.map +1 -1
  111. package/dist/schemas.d.ts +200 -0
  112. package/dist/schemas.d.ts.map +1 -1
  113. package/dist/schemas.js +96 -0
  114. package/dist/schemas.js.map +1 -1
  115. package/dist/vocabulary.d.ts +2 -2
  116. package/dist/vocabulary.d.ts.map +1 -1
  117. package/dist/vocabulary.js +3 -0
  118. package/dist/vocabulary.js.map +1 -1
  119. package/docs/specs/cli.md +26 -15
  120. package/docs/specs/rest.md +31 -9
  121. package/package.json +3 -2
  122. package/skills/working-the-board/SKILL.md +11 -4
  123. package/src/api.ts +36 -0
  124. package/src/cli/cli.ts +616 -54
  125. package/src/cli/credentials.ts +276 -14
  126. package/src/cli/directory.ts +43 -6
  127. package/src/cli/format.ts +146 -5
  128. package/src/cli/help.ts +51 -25
  129. package/src/cli/install.ts +111 -0
  130. package/src/cli/main.ts +23 -3
  131. package/src/cli/notices.ts +48 -0
  132. package/src/client.ts +91 -6
  133. package/src/compat.ts +173 -0
  134. package/src/components/board.tsx +154 -8
  135. package/src/components/calendar.tsx +41 -1
  136. package/src/components/comments.tsx +20 -10
  137. package/src/components/event-feed.tsx +4 -0
  138. package/src/components/goals.tsx +234 -88
  139. package/src/components/markdown.tsx +19 -0
  140. package/src/components/pictures.tsx +389 -0
  141. package/src/components/projects.tsx +68 -0
  142. package/src/components/roadmap.tsx +242 -0
  143. package/src/components/task-view.tsx +43 -2
  144. package/src/components/tokens.tsx +38 -1
  145. package/src/console.tsx +278 -4
  146. package/src/data.ts +73 -2
  147. package/src/i18n/en.ts +77 -2
  148. package/src/i18n/ko.ts +77 -2
  149. package/src/index.ts +35 -0
  150. package/src/router.ts +70 -11
  151. package/src/rules.ts +5 -5
  152. package/src/schemas.ts +117 -0
  153. package/src/styles/console.css +486 -3
  154. package/src/vocabulary.ts +3 -0
@@ -1,11 +1,157 @@
1
- import { chmod, mkdir, readFile, rm, writeFile } from "node:fs/promises";
1
+ import { chmod, mkdir, readFile, rename, rm, stat, writeFile } from "node:fs/promises";
2
2
  import { homedir } from "node:os";
3
3
  import { join } from "node:path";
4
+ import process from "node:process";
4
5
  import * as z from "zod/mini";
5
- const credentialsSchema = z.object({
6
+ export const EMPTY_CREDENTIALS = { default: undefined, logins: [] };
7
+ /** How many consoles one machine may be signed in to: far more than anyone has. */
8
+ export const MAX_LOGINS = 100;
9
+ /** How large the file may be before it is not read: far above a hundred logins. */
10
+ const MAX_FILE_BYTES = 64 * 1024;
11
+ export class CredentialsError extends Error {
12
+ code;
13
+ path;
14
+ constructor(code, path) {
15
+ super(code === "credentials.too_large"
16
+ ? `The credentials file ${path} is larger than the command reads.`
17
+ : `The credentials file ${path} could not be read as one.`);
18
+ this.name = "CredentialsError";
19
+ this.code = code;
20
+ this.path = path;
21
+ }
22
+ }
23
+ const loginSchema = z.object({
24
+ url: z.string().check(z.minLength(1), z.maxLength(2048)),
25
+ account: z.optional(z.string().check(z.minLength(1), z.maxLength(254))),
26
+ token: z.string().check(z.minLength(1), z.maxLength(1024)),
27
+ agent: z.optional(z.string().check(z.maxLength(200))),
28
+ since: z.optional(z.string().check(z.maxLength(40))),
29
+ });
30
+ const fileSchema = z.object({
31
+ version: z.literal(2),
32
+ default: z.optional(z.string().check(z.minLength(1), z.maxLength(2048))),
33
+ logins: z.array(loginSchema).check(z.maxLength(MAX_LOGINS)),
34
+ });
35
+ /** The file as the command kept it before 2026-10: one console, one token. */
36
+ const firstFileSchema = z.object({
6
37
  url: z.string().check(z.minLength(1)),
7
38
  token: z.string().check(z.minLength(1)),
8
39
  });
40
+ /** What a file says, in the current shape; one in the first shape reads as one login, the default. Nothing for anything else. */
41
+ export function parseCredentials(json) {
42
+ const current = fileSchema.safeParse(json);
43
+ if (current.success) {
44
+ return {
45
+ default: current.data.default,
46
+ logins: current.data.logins.map((login) => ({
47
+ url: login.url,
48
+ account: login.account,
49
+ token: login.token,
50
+ agent: login.agent,
51
+ since: login.since,
52
+ })),
53
+ };
54
+ }
55
+ const first = firstFileSchema.safeParse(json);
56
+ if (first.success) {
57
+ return {
58
+ default: first.data.url,
59
+ logins: [
60
+ {
61
+ url: first.data.url,
62
+ account: undefined,
63
+ token: first.data.token,
64
+ agent: undefined,
65
+ since: undefined,
66
+ },
67
+ ],
68
+ };
69
+ }
70
+ return undefined;
71
+ }
72
+ /** The logins at one console. */
73
+ export function loginsAt(credentials, url) {
74
+ return credentials.logins.filter((login) => login.url === url);
75
+ }
76
+ /** The consoles signed in to, each once, in the order they were signed in to. */
77
+ export function consolesOf(credentials) {
78
+ return [...new Set(credentials.logins.map((login) => login.url))];
79
+ }
80
+ /**
81
+ * With a login kept: in place of the one at the same console for the same account, else added.
82
+ * The first login kept is the default console, and one kept as the default is.
83
+ */
84
+ export function withLogin(credentials, login, options = {}) {
85
+ const rest = credentials.logins.filter((kept) => !(kept.url === login.url && kept.account === login.account));
86
+ const first = credentials.logins.length === 0 ? login.url : undefined;
87
+ return {
88
+ default: options.default === true ? login.url : (credentials.default ?? first),
89
+ logins: [...rest, login],
90
+ };
91
+ }
92
+ /**
93
+ * Without the login at a console, for one account or for every account there. The default
94
+ * stays while a login at it remains; else it moves to the one console left, or to none.
95
+ */
96
+ export function withoutLogin(credentials, url, account) {
97
+ const logins = credentials.logins.filter((kept) => !(kept.url === url && (account === undefined || kept.account === account)));
98
+ const consoles = [...new Set(logins.map((kept) => kept.url))];
99
+ const [only] = consoles;
100
+ const fallback = consoles.length === 1 ? only : undefined;
101
+ return {
102
+ default: credentials.default !== undefined && consoles.includes(credentials.default)
103
+ ? credentials.default
104
+ : fallback,
105
+ logins,
106
+ };
107
+ }
108
+ /**
109
+ * Which console a command talks to, and with what (ADR-0027). The address comes first: the
110
+ * flag, else the environment, else the directory, else the default login. The token is then
111
+ * the one for that address and no other: the environment's token where its address is that
112
+ * one, else the login kept for it, for the account named or the one account there.
113
+ */
114
+ export function resolveLogin(lookup) {
115
+ const { envUrl, envToken } = lookup;
116
+ if ((envUrl === undefined) !== (envToken === undefined)) {
117
+ return {
118
+ ok: false,
119
+ reason: "environment_half",
120
+ have: envUrl === undefined ? "CONSOLE_TOKEN" : "CONSOLE_URL",
121
+ };
122
+ }
123
+ const credentials = lookup.credentials ?? EMPTY_CREDENTIALS;
124
+ const consoles = consolesOf(credentials);
125
+ const [source, url] = lookup.flagUrl !== undefined
126
+ ? ["flag", lookup.flagUrl]
127
+ : envUrl !== undefined
128
+ ? ["environment", envUrl]
129
+ : lookup.directoryUrl !== undefined
130
+ ? ["directory", lookup.directoryUrl]
131
+ : ["default", credentials.default ?? (consoles.length === 1 ? consoles[0] : undefined)];
132
+ if (url === undefined) {
133
+ return { ok: false, reason: "nothing" };
134
+ }
135
+ const account = lookup.flagAccount ?? lookup.directoryAccount;
136
+ if (envUrl !== undefined && envToken !== undefined && envUrl === url) {
137
+ return { ok: true, url, token: envToken, account, source, via: "environment" };
138
+ }
139
+ const at = loginsAt(credentials, url);
140
+ const chosen = account === undefined ? at : at.filter((login) => login.account === account);
141
+ const [login] = chosen;
142
+ if (login === undefined) {
143
+ return { ok: false, reason: "no_login", url, account, source };
144
+ }
145
+ if (chosen.length > 1) {
146
+ return {
147
+ ok: false,
148
+ reason: "ambiguous",
149
+ url,
150
+ accounts: chosen.map((kept) => kept.account ?? "?"),
151
+ };
152
+ }
153
+ return { ok: true, url, token: login.token, account: login.account, source, via: "login" };
154
+ }
9
155
  const FILE_NAME = "credentials.json";
10
156
  /** The directory the file lives in: under `XDG_CONFIG_HOME`, or `~/.config`. */
11
157
  export function defaultConfigDir(env) {
@@ -16,24 +162,47 @@ export function createFileStore(directory) {
16
162
  const path = join(directory, FILE_NAME);
17
163
  return {
18
164
  async load() {
19
- let content;
165
+ let size;
20
166
  try {
21
- content = await readFile(path, "utf8");
167
+ size = (await stat(path)).size;
22
168
  }
23
169
  catch {
24
170
  return undefined;
25
171
  }
172
+ if (size > MAX_FILE_BYTES) {
173
+ throw new CredentialsError("credentials.too_large", path);
174
+ }
175
+ let json;
26
176
  try {
27
- const parsed = credentialsSchema.safeParse(JSON.parse(content));
28
- return parsed.success ? parsed.data : undefined;
177
+ json = JSON.parse(await readFile(path, "utf8"));
29
178
  }
30
179
  catch {
31
- return undefined;
180
+ throw new CredentialsError("credentials.malformed", path);
181
+ }
182
+ const parsed = parseCredentials(json);
183
+ if (parsed === undefined) {
184
+ throw new CredentialsError("credentials.malformed", path);
32
185
  }
186
+ return parsed;
33
187
  },
34
188
  async save(credentials) {
35
189
  await mkdir(directory, { recursive: true, mode: 0o700 });
36
- await writeFile(path, `${JSON.stringify(credentials, null, 2)}\n`, { mode: 0o600 });
190
+ const file = {
191
+ version: 2,
192
+ default: credentials.default,
193
+ logins: credentials.logins.map((login) => ({
194
+ url: login.url,
195
+ account: login.account,
196
+ token: login.token,
197
+ agent: login.agent,
198
+ since: login.since,
199
+ })),
200
+ };
201
+ // Written beside the file and moved over it in one step, so that a command that stops
202
+ // half-way leaves the file as it was, whole.
203
+ const draft = `${path}.${process.pid}.tmp`;
204
+ await writeFile(draft, `${JSON.stringify(file, null, 2)}\n`, { mode: 0o600 });
205
+ await rename(draft, path);
37
206
  // The mode above applies to a file made now; one that was there keeps its own, so it is set again.
38
207
  await chmod(path, 0o600).catch(() => undefined);
39
208
  return path;
@@ -1 +1 @@
1
- {"version":3,"file":"credentials.js","sourceRoot":"","sources":["../../src/cli/credentials.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACzE,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,KAAK,CAAC,MAAM,UAAU,CAAC;AAoB9B,MAAM,iBAAiB,GAAG,CAAC,CAAC,MAAM,CAAC;IACjC,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;IACrC,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;CACxC,CAAC,CAAC;AAEH,MAAM,SAAS,GAAG,kBAAkB,CAAC;AAErC,gFAAgF;AAChF,MAAM,UAAU,gBAAgB,CAAC,GAAiD;IAChF,MAAM,IAAI,GAAG,GAAG,CAAC,eAAe,CAAC;IACjC,OAAO,IAAI,CACT,IAAI,KAAK,SAAS,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,IAAI,EAC3E,kBAAkB,CACnB,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,SAAiB;IAC/C,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;IACxC,OAAO;QACL,KAAK,CAAC,IAAI;YACR,IAAI,OAAe,CAAC;YACpB,IAAI,CAAC;gBACH,OAAO,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;YACzC,CAAC;YAAC,MAAM,CAAC;gBACP,OAAO,SAAS,CAAC;YACnB,CAAC;YACD,IAAI,CAAC;gBACH,MAAM,MAAM,GAAG,iBAAiB,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;gBAChE,OAAO,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC;YAClD,CAAC;YAAC,MAAM,CAAC;gBACP,OAAO,SAAS,CAAC;YACnB,CAAC;QACH,CAAC;QACD,KAAK,CAAC,IAAI,CAAC,WAAW;YACpB,MAAM,KAAK,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;YACzD,MAAM,SAAS,CAAC,IAAI,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,WAAW,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;YACpF,mGAAmG;YACnG,MAAM,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;YAChD,OAAO,IAAI,CAAC;QACd,CAAC;QACD,KAAK,CAAC,KAAK;YACT,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QAClC,CAAC;KACF,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"credentials.js","sourceRoot":"","sources":["../../src/cli/credentials.ts"],"names":[],"mappings":"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"}
@@ -3,6 +3,10 @@ export declare const DIRECTORY_FILE = ".skillcdn-console.json";
3
3
  export interface DirectorySettings {
4
4
  /** The key of the project the directory's work belongs to. */
5
5
  readonly project: string;
6
+ /** The origin of the console the directory is bound to; the default login when left out. */
7
+ readonly url?: string | undefined;
8
+ /** The account at that console, where several are signed in to it. */
9
+ readonly account?: string | undefined;
6
10
  }
7
11
  export interface DirectoryStore {
8
12
  /** The settings of the working directory, or of the nearest directory above it that has them. */
@@ -10,5 +14,7 @@ export interface DirectoryStore {
10
14
  /** Writes the settings into the working directory and answers where. */
11
15
  save(settings: DirectorySettings): Promise<string>;
12
16
  }
17
+ /** What a file says, with nothing but the three settings kept; nothing for anything else. */
18
+ export declare function parseDirectorySettings(json: unknown): DirectorySettings | undefined;
13
19
  export declare function createDirectoryStore(cwd: string): DirectoryStore;
14
20
  //# sourceMappingURL=directory.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"directory.d.ts","sourceRoot":"","sources":["../../src/cli/directory.ts"],"names":[],"mappings":"AASA,iEAAiE;AACjE,eAAO,MAAM,cAAc,2BAA2B,CAAC;AAEvD,MAAM,WAAW,iBAAiB;IAChC,8DAA8D;IAC9D,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,cAAc;IAC7B,iGAAiG;IACjG,IAAI,IAAI,OAAO,CAAC,iBAAiB,GAAG,SAAS,CAAC,CAAC;IAC/C,wEAAwE;IACxE,IAAI,CAAC,QAAQ,EAAE,iBAAiB,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;CACpD;AAID,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,GAAG,cAAc,CAgChE"}
1
+ {"version":3,"file":"directory.d.ts","sourceRoot":"","sources":["../../src/cli/directory.ts"],"names":[],"mappings":"AAcA,iEAAiE;AACjE,eAAO,MAAM,cAAc,2BAA2B,CAAC;AAKvD,MAAM,WAAW,iBAAiB;IAChC,8DAA8D;IAC9D,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,4FAA4F;IAC5F,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAClC,sEAAsE;IACtE,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACvC;AAED,MAAM,WAAW,cAAc;IAC7B,iGAAiG;IACjG,IAAI,IAAI,OAAO,CAAC,iBAAiB,GAAG,SAAS,CAAC,CAAC;IAC/C,wEAAwE;IACxE,IAAI,CAAC,QAAQ,EAAE,iBAAiB,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;CACpD;AAQD,6FAA6F;AAC7F,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,OAAO,GAAG,iBAAiB,GAAG,SAAS,CAUnF;AAED,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,GAAG,cAAc,CAwChE"}
@@ -3,11 +3,34 @@ import { dirname, join } from "node:path";
3
3
  import * as z from "zod/mini";
4
4
  // What a working directory says about the project it belongs to: `.skillcdn-console.json` in
5
5
  // it or in a directory above it, as `.nvmrc` and its kind are found. Written by `console use`,
6
- // and meant to be committed, so that everyone who works in the checkout, and every agent they
7
- // run in it, is in the same project without saying so.
6
+ // and meant to be committed in a private repository, so that everyone who works in the
7
+ // checkout, and every agent they run in it, is in the same project without saying so; left out
8
+ // of a public one, since it may name the organization's console. It names the project, and
9
+ // where the checkout is bound to a console other than the default login, that console and the
10
+ // account there (ADR-0027). Never a token, a code or anything secret: the token for the console
11
+ // it names is looked up in the credentials the command keeps, and a key this file does not
12
+ // know is dropped on reading.
8
13
  /** The file's name, in the working directory or one above it. */
9
14
  export const DIRECTORY_FILE = ".skillcdn-console.json";
10
- const settingsSchema = z.object({ project: z.string().check(z.minLength(1)) });
15
+ /** How large the file may be before it is not read: a few names, never more. */
16
+ const MAX_FILE_CHARS = 16 * 1024;
17
+ const settingsSchema = z.object({
18
+ project: z.string().check(z.minLength(1), z.maxLength(100)),
19
+ url: z.optional(z.string().check(z.minLength(1), z.maxLength(2048))),
20
+ account: z.optional(z.string().check(z.minLength(1), z.maxLength(254))),
21
+ });
22
+ /** What a file says, with nothing but the three settings kept; nothing for anything else. */
23
+ export function parseDirectorySettings(json) {
24
+ const parsed = settingsSchema.safeParse(json);
25
+ if (!parsed.success) {
26
+ return undefined;
27
+ }
28
+ return {
29
+ project: parsed.data.project,
30
+ ...(parsed.data.url === undefined ? {} : { url: parsed.data.url }),
31
+ ...(parsed.data.account === undefined ? {} : { account: parsed.data.account }),
32
+ };
33
+ }
11
34
  export function createDirectoryStore(cwd) {
12
35
  return {
13
36
  async load() {
@@ -21,9 +44,11 @@ export function createDirectoryStore(cwd) {
21
44
  content = undefined;
22
45
  }
23
46
  if (content !== undefined) {
47
+ if (content.length > MAX_FILE_CHARS) {
48
+ return undefined;
49
+ }
24
50
  try {
25
- const parsed = settingsSchema.safeParse(JSON.parse(content));
26
- return parsed.success ? parsed.data : undefined;
51
+ return parseDirectorySettings(JSON.parse(content));
27
52
  }
28
53
  catch {
29
54
  return undefined;
@@ -38,7 +63,13 @@ export function createDirectoryStore(cwd) {
38
63
  },
39
64
  async save(settings) {
40
65
  const path = join(cwd, DIRECTORY_FILE);
41
- await writeFile(path, `${JSON.stringify(settings, null, 2)}\n`);
66
+ // The three settings, named one by one: nothing else ever reaches this file.
67
+ const written = {
68
+ project: settings.project,
69
+ ...(settings.url === undefined ? {} : { url: settings.url }),
70
+ ...(settings.account === undefined ? {} : { account: settings.account }),
71
+ };
72
+ await writeFile(path, `${JSON.stringify(written, null, 2)}\n`);
42
73
  return path;
43
74
  },
44
75
  };
@@ -1 +1 @@
1
- {"version":3,"file":"directory.js","sourceRoot":"","sources":["../../src/cli/directory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,KAAK,CAAC,MAAM,UAAU,CAAC;AAE9B,6FAA6F;AAC7F,+FAA+F;AAC/F,8FAA8F;AAC9F,uDAAuD;AAEvD,iEAAiE;AACjE,MAAM,CAAC,MAAM,cAAc,GAAG,wBAAwB,CAAC;AAcvD,MAAM,cAAc,GAAG,CAAC,CAAC,MAAM,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;AAE/E,MAAM,UAAU,oBAAoB,CAAC,GAAW;IAC9C,OAAO;QACL,KAAK,CAAC,IAAI;YACR,IAAI,SAAS,GAAG,GAAG,CAAC;YACpB,SAAS,CAAC;gBACR,IAAI,OAA2B,CAAC;gBAChC,IAAI,CAAC;oBACH,OAAO,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,SAAS,EAAE,cAAc,CAAC,EAAE,MAAM,CAAC,CAAC;gBACpE,CAAC;gBAAC,MAAM,CAAC;oBACP,OAAO,GAAG,SAAS,CAAC;gBACtB,CAAC;gBACD,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;oBAC1B,IAAI,CAAC;wBACH,MAAM,MAAM,GAAG,cAAc,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;wBAC7D,OAAO,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC;oBAClD,CAAC;oBAAC,MAAM,CAAC;wBACP,OAAO,SAAS,CAAC;oBACnB,CAAC;gBACH,CAAC;gBACD,MAAM,KAAK,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC;gBACjC,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;oBACxB,OAAO,SAAS,CAAC;gBACnB,CAAC;gBACD,SAAS,GAAG,KAAK,CAAC;YACpB,CAAC;QACH,CAAC;QACD,KAAK,CAAC,IAAI,CAAC,QAAQ;YACjB,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,EAAE,cAAc,CAAC,CAAC;YACvC,MAAM,SAAS,CAAC,IAAI,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;YAChE,OAAO,IAAI,CAAC;QACd,CAAC;KACF,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"directory.js","sourceRoot":"","sources":["../../src/cli/directory.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import type { RestArtifact, RestCategory, RestComment, RestDecision, RestDocument, RestDocumentSummary, RestDocuments, RestGoal, RestListing, RestMember, RestPerson, RestPersonWork, RestProject, RestProjectRules, RestRules, RestRun, 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, RestSkillFile, RestSkillLoad, RestSkillPage, RestSkills, RestTask, RestVersion, RestVersionSummary, RestWork } from "../schemas.js";
2
2
  /** One project: its key, its name, what the person is in it, and what waits in it. */
3
3
  export declare function formatProjectLine(project: RestProject): string;
4
4
  /** One project in full: what it is, how it is marked, and what the person is in it. */
@@ -32,7 +32,7 @@ export declare function formatArtifact(artifact: RestArtifact, fileUrl?: (artifa
32
32
  export declare function formatSkills(skills: RestSkills, ownSkills?: string): string;
33
33
  /** The rules that hold: the workspace's, and what the project adds when the command works in one. */
34
34
  export declare function formatRules(rules: RestProjectRules | RestRules): string;
35
- /** One goal: its id, its state, its title, when it is due, and how far it is. */
35
+ /** One goal: its id, its state, its title, its category, its days, and how far it is. */
36
36
  export declare function formatGoalLine(goal: RestGoal): string;
37
37
  /** One goal in full; with the tasks that work towards it, when given. */
38
38
  export declare function formatGoal(goal: RestGoal, tasks?: readonly RestTask[]): string;
@@ -56,4 +56,13 @@ export declare function formatDocument(document: RestDocument, fileUrl?: (fileId
56
56
  export declare function formatVersionLine(version: RestVersionSummary): string;
57
57
  /** One version of a document, with its body as it was. */
58
58
  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;
59
68
  //# sourceMappingURL=format.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"format.d.ts","sourceRoot":"","sources":["../../src/cli/format.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"format.d.ts","sourceRoot":"","sources":["../../src/cli/format.ts"],"names":[],"mappings":"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"}
@@ -24,6 +24,7 @@ export function formatProject(project) {
24
24
  `project ${project.key}: ${project.name}`,
25
25
  `visibility: ${project.visibility} role: ${project.role} skills: ${project.skillsAddress ?? "the organization's"}`,
26
26
  `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}`}`,
27
28
  ];
28
29
  if (project.description.trim().length > 0) {
29
30
  lines.push("", project.description.trimEnd());
@@ -65,6 +66,9 @@ export function formatTaskLine(task) {
65
66
  if (task.openDecisions > 0) {
66
67
  notes.push(`${plural(task.openDecisions, "decision")} waiting`);
67
68
  }
69
+ if (task.archivedAt !== null) {
70
+ notes.push("archived");
71
+ }
68
72
  return `#${task.number} ${task.state} ${task.priority} ${task.title} (${notes.join("; ")})`;
69
73
  }
70
74
  /** The plan and what happened, as a line each, only where there is something to say. */
@@ -82,6 +86,7 @@ function scheduleLines(task) {
82
86
  const happened = [
83
87
  task.startedAt === null ? undefined : `started: ${task.startedAt}`,
84
88
  task.doneAt === null ? undefined : `done: ${task.doneAt}`,
89
+ task.archivedAt === null ? undefined : `archived: ${task.archivedAt}`,
85
90
  ].filter((part) => part !== undefined);
86
91
  if (happened.length > 0) {
87
92
  lines.push(happened.join(" "));
@@ -183,7 +188,8 @@ export function formatArtifact(artifact, fileUrl) {
183
188
  const SKILLS_WORDS = {
184
189
  indexing: "SkillCDN is still indexing the repository; ask again in a moment.",
185
190
  failed: "SkillCDN could not index the repository.",
186
- not_found: "SkillCDN does not serve this address to the console.",
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).",
187
193
  unavailable: "SkillCDN could not be reached; ask again later.",
188
194
  };
189
195
  /**
@@ -209,7 +215,7 @@ export function formatSkills(skills, ownSkills) {
209
215
  for (const skill of skills.items) {
210
216
  lines.push(`${skill.name} ${skill.description}`, ` ${skill.uri ?? skill.path}`);
211
217
  }
212
- lines.push("", `Load a skill by its URI through your SkillCDN connection to this address; an agent without one is connected by a person at ${skills.page}. --json adds the page of each, for a person.`, ...own);
218
+ lines.push("", `Read a skill whole with console skill <path>, its rules first, and a file of the pack with console skill <path> --file <file>; 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);
213
219
  return lines.join("\n");
214
220
  }
215
221
  /** One half of the rules: where it comes from, and the text as it stands. */
@@ -244,16 +250,21 @@ function progressOf(goal) {
244
250
  const working = counts.in_progress + counts.in_review;
245
251
  return `${counts.done}/${total} done${working === 0 ? "" : `, ${working} in progress`}${counts.dropped === 0 ? "" : `, ${counts.dropped} dropped`}`;
246
252
  }
247
- /** One goal: its id, its state, its title, when it is due, and how far it is. */
253
+ /** One goal: its id, its state, its title, its category, its days, and how far it is. */
248
254
  export function formatGoalLine(goal) {
249
- const notes = [goal.dueOn === null ? "no target day" : `due ${goal.dueOn}`, progressOf(goal)];
255
+ const notes = [
256
+ ...(goal.category === null ? [] : [goal.category.key]),
257
+ ...(goal.startsOn === null ? [] : [`starts ${goal.startsOn}`]),
258
+ goal.dueOn === null ? "no target day" : `due ${goal.dueOn}`,
259
+ progressOf(goal),
260
+ ];
250
261
  return `${goal.id} ${goal.state} ${goal.title} (${notes.join("; ")})`;
251
262
  }
252
263
  /** One goal in full; with the tasks that work towards it, when given. */
253
264
  export function formatGoal(goal, tasks) {
254
265
  const lines = [
255
266
  `goal ${goal.id}: ${goal.title}`,
256
- `state: ${goal.state} due: ${goal.dueOn ?? "none"} set by: ${goal.createdBy.login}`,
267
+ `state: ${goal.state} category: ${goal.category?.key ?? "none"} starts: ${goal.startsOn ?? "none"} due: ${goal.dueOn ?? "none"} set by: ${goal.createdBy.login}`,
257
268
  `progress: ${progressOf(goal)}`,
258
269
  ];
259
270
  if (goal.body.trim().length > 0) {
@@ -399,4 +410,102 @@ export function formatVersion(path, version) {
399
410
  }
400
411
  return lines.join("\n");
401
412
  }
413
+ /** The text of one path across the pages a skill came in: the fragments joined in order. */
414
+ function joinTexts(pages, pick) {
415
+ const joined = new Map();
416
+ for (const page of pages) {
417
+ for (const text of pick(page)) {
418
+ joined.set(text.path, (joined.get(text.path) ?? "") + text.body);
419
+ }
420
+ }
421
+ return [...joined.entries()].map(([path, body]) => ({ path, body }));
422
+ }
423
+ const NO_ADDRESS = "No skills address: neither this project nor the console names one.";
424
+ /**
425
+ * One skill, as load_skill lays it out for a model (ADR-0028): the rules from the repository's
426
+ * root to the nearest manifest, the body, the included files, each under a line that names its
427
+ * path; then the files the skill has and what it refers to. A skill described only is named and
428
+ * pointed at, and nothing of its body is shown.
429
+ */
430
+ export function formatSkillLoad(loaded, pages) {
431
+ if (loaded.status === "none" || loaded.address === null) {
432
+ return NO_ADDRESS;
433
+ }
434
+ const head = `skill at ${loaded.address}, served by ${loaded.source}: ${loaded.status}`;
435
+ if (loaded.status !== "ready") {
436
+ return [head, SKILLS_WORDS[loaded.status]].join("\n");
437
+ }
438
+ const [first] = pages;
439
+ if (first === undefined) {
440
+ return [head, "Nothing was read."].join("\n");
441
+ }
442
+ const last = pages[pages.length - 1] ?? first;
443
+ const lines = [
444
+ `${first.name} ${first.description}`,
445
+ `skill ${first.path} at ${loaded.address}, served by ${loaded.source}`,
446
+ ];
447
+ if (first.serving.license !== null) {
448
+ lines.push(`license: ${first.serving.license}`);
449
+ }
450
+ if (!first.serving.full) {
451
+ lines.push("", `Described only: the license keeps the skill at its source. Read it there: ${first.serving.sourceUrl ?? loaded.page ?? loaded.source}`);
452
+ return lines.join("\n");
453
+ }
454
+ for (const rule of joinTexts(pages, (page) => page.rules)) {
455
+ lines.push("", `--- applicable rules: ${rule.path} ---`, rule.body.trimEnd());
456
+ }
457
+ lines.push("", `--- skill: ${first.path} ---`, pages
458
+ .map((page) => page.body)
459
+ .join("")
460
+ .trimEnd());
461
+ for (const file of joinTexts(pages, (page) => page.included)) {
462
+ lines.push("", `--- included file: ${file.path} ---`, file.body.trimEnd());
463
+ }
464
+ if (!last.complete) {
465
+ lines.push("", "The skill did not come whole: the deployment stopped before the end.");
466
+ }
467
+ if (last.files.length > 0) {
468
+ lines.push("", `Files of the skill, read with console skill ${first.path} --file <path>: ${last.files.join(", ")}`);
469
+ }
470
+ if (last.references.length > 0) {
471
+ lines.push(`References: ${last.references
472
+ .map((reference) => reference.status === "available"
473
+ ? reference.path
474
+ : `${reference.path} (${reference.status})`)
475
+ .join(", ")}`);
476
+ }
477
+ if (last.warnings.length > 0) {
478
+ lines.push(`Warnings: ${last.warnings.join("; ")}`);
479
+ }
480
+ 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.");
481
+ return lines.join("\n");
482
+ }
483
+ /** A file of the pack as read: its text whole, or what the folder holds. */
484
+ export function formatSkillFile(read, content) {
485
+ if (read.status === "none" || read.address === null) {
486
+ return NO_ADDRESS;
487
+ }
488
+ const head = `file at ${read.address}, served by ${read.source}: ${read.status}`;
489
+ if (read.status !== "ready") {
490
+ return [
491
+ head,
492
+ read.status === "failed"
493
+ ? "SkillCDN will not carry this file: it is too large, or not text. Read it at the repository."
494
+ : SKILLS_WORDS[read.status],
495
+ ].join("\n");
496
+ }
497
+ if (read.folder !== null) {
498
+ return [
499
+ `folder ${read.folder.path} at ${read.address}${read.folder.truncated ? " (cut)" : ""}`,
500
+ ...read.folder.entries.map((entry) => `${entry.kind === "directory" ? "d" : "f"} ${entry.path}${entry.size === null ? "" : ` ${entry.size}`}`),
501
+ ].join("\n");
502
+ }
503
+ if (read.file === null) {
504
+ return `${head}: nothing was read.`;
505
+ }
506
+ return [
507
+ `--- file: ${read.file.path} (${read.file.totalLength} characters) ---`,
508
+ content.trimEnd(),
509
+ ].join("\n");
510
+ }
402
511
  //# sourceMappingURL=format.js.map