@skillcdn/console 0.3.2 → 0.4.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.
- package/README.md +4 -3
- package/dist/api.d.ts +2 -2
- package/dist/api.d.ts.map +1 -1
- package/dist/api.js +2 -2
- package/dist/api.js.map +1 -1
- package/dist/cli/cli.d.ts.map +1 -1
- package/dist/cli/cli.js +132 -18
- package/dist/cli/cli.js.map +1 -1
- package/dist/cli/format.d.ts.map +1 -1
- package/dist/cli/format.js +6 -4
- package/dist/cli/format.js.map +1 -1
- package/dist/cli/help.d.ts.map +1 -1
- package/dist/cli/help.js +72 -21
- package/dist/cli/help.js.map +1 -1
- package/dist/cli/pack.d.ts +7 -2
- package/dist/cli/pack.d.ts.map +1 -1
- package/dist/cli/pack.js +16 -2
- package/dist/cli/pack.js.map +1 -1
- package/dist/client.d.ts +19 -3
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +11 -1
- package/dist/client.js.map +1 -1
- package/dist/compat.d.ts +1 -1
- package/dist/compat.js +2 -2
- package/dist/components/board.d.ts +12 -1
- package/dist/components/board.d.ts.map +1 -1
- package/dist/components/board.js +52 -4
- package/dist/components/board.js.map +1 -1
- package/dist/components/calendar.d.ts +4 -0
- package/dist/components/calendar.d.ts.map +1 -1
- package/dist/components/calendar.js +61 -22
- package/dist/components/calendar.js.map +1 -1
- package/dist/components/decision-form.d.ts +12 -4
- package/dist/components/decision-form.d.ts.map +1 -1
- package/dist/components/decision-form.js +24 -6
- package/dist/components/decision-form.js.map +1 -1
- package/dist/components/decision-list.d.ts +4 -0
- package/dist/components/decision-list.d.ts.map +1 -1
- package/dist/components/decision-list.js +9 -6
- package/dist/components/decision-list.js.map +1 -1
- package/dist/components/documents.d.ts.map +1 -1
- package/dist/components/documents.js +3 -3
- package/dist/components/documents.js.map +1 -1
- package/dist/components/event-feed.d.ts.map +1 -1
- package/dist/components/event-feed.js +63 -8
- package/dist/components/event-feed.js.map +1 -1
- package/dist/components/markdown.d.ts.map +1 -1
- package/dist/components/markdown.js +6 -3
- package/dist/components/markdown.js.map +1 -1
- package/dist/components/my-decisions.d.ts +20 -0
- package/dist/components/my-decisions.d.ts.map +1 -0
- package/dist/components/my-decisions.js +36 -0
- package/dist/components/my-decisions.js.map +1 -0
- package/dist/components/pack-connect.d.ts +3 -1
- package/dist/components/pack-connect.d.ts.map +1 -1
- package/dist/components/pack-connect.js +4 -4
- package/dist/components/pack-connect.js.map +1 -1
- package/dist/components/pack-token.d.ts +3 -1
- package/dist/components/pack-token.d.ts.map +1 -1
- package/dist/components/pack-token.js +1 -1
- package/dist/components/pack-token.js.map +1 -1
- package/dist/components/people.d.ts.map +1 -1
- package/dist/components/people.js +14 -3
- package/dist/components/people.js.map +1 -1
- package/dist/components/projects.d.ts.map +1 -1
- package/dist/components/projects.js +3 -3
- package/dist/components/projects.js.map +1 -1
- package/dist/components/remote-pictures.d.ts +6 -0
- package/dist/components/remote-pictures.d.ts.map +1 -0
- package/dist/components/remote-pictures.js +8 -0
- package/dist/components/remote-pictures.js.map +1 -0
- package/dist/components/roadmap.js +1 -1
- package/dist/components/roadmap.js.map +1 -1
- package/dist/components/runs.d.ts.map +1 -1
- package/dist/components/runs.js +1 -1
- package/dist/components/runs.js.map +1 -1
- package/dist/components/shell.d.ts.map +1 -1
- package/dist/components/shell.js +36 -1
- package/dist/components/shell.js.map +1 -1
- package/dist/components/sign-in.d.ts.map +1 -1
- package/dist/components/sign-in.js +49 -2
- package/dist/components/sign-in.js.map +1 -1
- package/dist/components/task-list.js +1 -1
- package/dist/components/task-list.js.map +1 -1
- package/dist/components/task-view.d.ts.map +1 -1
- package/dist/components/task-view.js +2 -2
- package/dist/components/task-view.js.map +1 -1
- package/dist/components/ui.d.ts +13 -2
- package/dist/components/ui.d.ts.map +1 -1
- package/dist/components/ui.js +21 -14
- package/dist/components/ui.js.map +1 -1
- package/dist/console.css +1686 -425
- package/dist/console.d.ts.map +1 -1
- package/dist/console.js +83 -13
- package/dist/console.js.map +1 -1
- package/dist/data.d.ts +15 -2
- package/dist/data.d.ts.map +1 -1
- package/dist/data.js +18 -19
- package/dist/data.js.map +1 -1
- package/dist/i18n/en.d.ts +48 -1
- package/dist/i18n/en.d.ts.map +1 -1
- package/dist/i18n/en.js +50 -3
- package/dist/i18n/en.js.map +1 -1
- package/dist/i18n/ko.d.ts.map +1 -1
- package/dist/i18n/ko.js +47 -4
- package/dist/i18n/ko.js.map +1 -1
- package/dist/index.d.ts +3 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -2
- package/dist/index.js.map +1 -1
- package/dist/limits.d.ts +14 -0
- package/dist/limits.d.ts.map +1 -1
- package/dist/limits.js +14 -0
- package/dist/limits.js.map +1 -1
- package/dist/router.d.ts +9 -1
- package/dist/router.d.ts.map +1 -1
- package/dist/router.js +12 -0
- package/dist/router.js.map +1 -1
- package/dist/routes.d.ts +5 -1
- package/dist/routes.d.ts.map +1 -1
- package/dist/routes.js +5 -1
- package/dist/routes.js.map +1 -1
- package/dist/rules.js +1 -1
- package/dist/rules.js.map +1 -1
- package/dist/schemas.d.ts +272 -4
- package/dist/schemas.d.ts.map +1 -1
- package/dist/schemas.js +33 -8
- package/dist/schemas.js.map +1 -1
- package/dist/web.d.ts.map +1 -1
- package/dist/web.js +3 -2
- package/dist/web.js.map +1 -1
- package/docs/specs/cli.md +11 -10
- package/docs/specs/rest.md +33 -17
- package/package.json +2 -2
- package/skills/building-a-console/SKILL.md +5 -5
- package/skills/building-a-console/references/the-default-console.md +4 -4
- package/skills/building-a-console/references/the-look-from-a-website.md +5 -5
- package/skills/working-the-board/SKILL.md +6 -4
- package/skills/working-the-board/references/setting-up.md +1 -1
- package/skills/working-the-board/references/terms.md +1 -1
- package/src/api.ts +10 -0
- package/src/cli/cli.ts +162 -19
- package/src/cli/format.ts +11 -4
- package/src/cli/help.ts +79 -20
- package/src/cli/pack.ts +17 -1
- package/src/client.ts +51 -2
- package/src/compat.ts +2 -2
- package/src/components/board.tsx +114 -21
- package/src/components/calendar.tsx +207 -102
- package/src/components/decision-form.tsx +71 -23
- package/src/components/decision-list.tsx +30 -3
- package/src/components/documents.tsx +27 -11
- package/src/components/event-feed.tsx +116 -33
- package/src/components/markdown.tsx +6 -3
- package/src/components/my-decisions.tsx +138 -0
- package/src/components/pack-connect.tsx +10 -7
- package/src/components/pack-token.tsx +4 -1
- package/src/components/people.tsx +20 -8
- package/src/components/projects.tsx +7 -5
- package/src/components/remote-pictures.ts +19 -0
- package/src/components/roadmap.tsx +1 -1
- package/src/components/runs.tsx +5 -1
- package/src/components/shell.tsx +36 -1
- package/src/components/sign-in.tsx +114 -13
- package/src/components/task-list.tsx +1 -1
- package/src/components/task-view.tsx +48 -47
- package/src/components/ui.tsx +70 -14
- package/src/console.tsx +153 -32
- package/src/data.ts +37 -20
- package/src/i18n/en.ts +53 -3
- package/src/i18n/ko.ts +50 -4
- package/src/index.ts +3 -0
- package/src/limits.ts +14 -0
- package/src/router.ts +18 -1
- package/src/routes.ts +5 -1
- package/src/rules.ts +1 -1
- package/src/schemas.ts +37 -8
- package/src/styles/console.css +1686 -425
- package/src/web.ts +3 -2
package/src/cli/cli.ts
CHANGED
|
@@ -801,13 +801,19 @@ const logout: Command = async (args, io) => {
|
|
|
801
801
|
}
|
|
802
802
|
// The token is given up at the console first, so that it is good for nothing from now on;
|
|
803
803
|
// one the console no longer knows is gone already. A console out of reach leaves it to the
|
|
804
|
-
// Agents page, and the person is told so.
|
|
805
|
-
|
|
804
|
+
// Agents page, and the person is told so. A console that keeps it because the person is out
|
|
805
|
+
// (ADR-0044) is told so too: the token is theirs again when they are back in.
|
|
806
|
+
let outcome: "gone" | "kept" | "left" = "gone";
|
|
806
807
|
try {
|
|
807
808
|
await clientOf(io, url, login.token).giveUpToken();
|
|
808
809
|
} catch (error) {
|
|
809
|
-
if (
|
|
810
|
-
|
|
810
|
+
if (
|
|
811
|
+
error instanceof ApiError &&
|
|
812
|
+
(error.code === "auth.deactivated" || error.code === "auth.not_admitted")
|
|
813
|
+
) {
|
|
814
|
+
outcome = "kept";
|
|
815
|
+
} else if (!(error instanceof ApiError && error.code === "auth.required")) {
|
|
816
|
+
outcome = "left";
|
|
811
817
|
}
|
|
812
818
|
}
|
|
813
819
|
const next = withoutLogin(credentials, url, login.account);
|
|
@@ -818,9 +824,11 @@ const logout: Command = async (args, io) => {
|
|
|
818
824
|
}
|
|
819
825
|
const whom = login.account === undefined ? "" : ` as ${login.account}`;
|
|
820
826
|
io.stdout(
|
|
821
|
-
gone
|
|
827
|
+
outcome === "gone"
|
|
822
828
|
? `Signed out of ${url}${whom}: the token is given up at the console and forgotten here.\n`
|
|
823
|
-
:
|
|
829
|
+
: outcome === "kept"
|
|
830
|
+
? `Signed out of ${url}${whom} here: the console keeps the token while the person is out, for when they are back in.\n`
|
|
831
|
+
: `Signed out of ${url}${whom} here, but the console could not be reached to give the token up: a person removes it on the Agents page.\n`,
|
|
824
832
|
);
|
|
825
833
|
envNote();
|
|
826
834
|
return EXIT.ok;
|
|
@@ -1172,8 +1180,37 @@ const skills: Command = async (args, io) => {
|
|
|
1172
1180
|
return EXIT.ok;
|
|
1173
1181
|
};
|
|
1174
1182
|
|
|
1183
|
+
/** The most characters one read of a file asks for: what the console's API allows on one page. */
|
|
1184
|
+
const MAX_FILE_LIMIT = 100_000;
|
|
1185
|
+
|
|
1186
|
+
/** A count given as a flag, within its bounds, or nothing; anything else is not understood. */
|
|
1187
|
+
function countOf(
|
|
1188
|
+
given: string | undefined,
|
|
1189
|
+
name: string,
|
|
1190
|
+
bounds: { readonly least: number; readonly most?: number },
|
|
1191
|
+
): number | undefined {
|
|
1192
|
+
if (given === undefined) {
|
|
1193
|
+
return undefined;
|
|
1194
|
+
}
|
|
1195
|
+
const count = Number(given);
|
|
1196
|
+
if (
|
|
1197
|
+
!Number.isInteger(count) ||
|
|
1198
|
+
count < bounds.least ||
|
|
1199
|
+
(bounds.most !== undefined && count > bounds.most)
|
|
1200
|
+
) {
|
|
1201
|
+
const range =
|
|
1202
|
+
bounds.most === undefined ? `${bounds.least} or more` : `${bounds.least} to ${bounds.most}`;
|
|
1203
|
+
throw misuse(`Not a number for --${name}, ${range}: ${given}`);
|
|
1204
|
+
}
|
|
1205
|
+
return count;
|
|
1206
|
+
}
|
|
1207
|
+
|
|
1175
1208
|
const skill: Command = async (args, io) => {
|
|
1176
|
-
const { values, positionals } = parse(args, {
|
|
1209
|
+
const { values, positionals } = parse(args, {
|
|
1210
|
+
file: { type: "string" },
|
|
1211
|
+
offset: { type: "string" },
|
|
1212
|
+
limit: { type: "string" },
|
|
1213
|
+
});
|
|
1177
1214
|
const file = text(values, "file");
|
|
1178
1215
|
// A file is read by its own path from the repository's root; a skill's path beside it would be
|
|
1179
1216
|
// ignored, which reads as if it mattered, so the two together are not understood.
|
|
@@ -1182,6 +1219,17 @@ const skill: Command = async (args, io) => {
|
|
|
1182
1219
|
"Say one: console skill <path of its SKILL.md> for a skill, or console skill --file <path> for a file of the pack.",
|
|
1183
1220
|
);
|
|
1184
1221
|
}
|
|
1222
|
+
// A section is a page of a file read as asked (SkillCDN 0.4): the flags mean nothing without one.
|
|
1223
|
+
if (
|
|
1224
|
+
file === undefined &&
|
|
1225
|
+
(text(values, "offset") !== undefined || text(values, "limit") !== undefined)
|
|
1226
|
+
) {
|
|
1227
|
+
throw misuse(
|
|
1228
|
+
"--offset and --limit go with --file: console skill --file <path> [--offset <n>] [--limit <n>]",
|
|
1229
|
+
);
|
|
1230
|
+
}
|
|
1231
|
+
const offset = countOf(text(values, "offset"), "offset", { least: 0 });
|
|
1232
|
+
const limit = countOf(text(values, "limit"), "limit", { least: 1, most: MAX_FILE_LIMIT });
|
|
1185
1233
|
const session = await open(io, values);
|
|
1186
1234
|
const project = await session.project();
|
|
1187
1235
|
const { listing, summary } = await packOf(project);
|
|
@@ -1189,6 +1237,16 @@ const skill: Command = async (args, io) => {
|
|
|
1189
1237
|
answer(io, session, listing, () => formatSkills(listing, io.skillsDir));
|
|
1190
1238
|
return EXIT.ok;
|
|
1191
1239
|
}
|
|
1240
|
+
if (file !== undefined && (offset !== undefined || limit !== undefined)) {
|
|
1241
|
+
// One page as asked, the section a search or an outline named; the result says where the
|
|
1242
|
+
// file continues, and asks for nothing.
|
|
1243
|
+
const page = await project.skillFile(file, { offset, limit });
|
|
1244
|
+
const section = page.read === null ? undefined : joinFile([page], summary, limit);
|
|
1245
|
+
answer(io, session, { ...page, read: section === undefined ? null : bodyOfFile(section) }, () =>
|
|
1246
|
+
formatSkillFile(page, section),
|
|
1247
|
+
);
|
|
1248
|
+
return EXIT.ok;
|
|
1249
|
+
}
|
|
1192
1250
|
if (file !== undefined) {
|
|
1193
1251
|
// The file whole, page after page, as the console reads it from the pack.
|
|
1194
1252
|
const pages: RestSkillFile[] = [];
|
|
@@ -1800,11 +1858,16 @@ const ask: Command = async (args, io) => {
|
|
|
1800
1858
|
file: { type: "string" },
|
|
1801
1859
|
run: { type: "string" },
|
|
1802
1860
|
wait: { type: "string" },
|
|
1861
|
+
to: { type: "string" },
|
|
1803
1862
|
});
|
|
1804
1863
|
const question = theOne(
|
|
1805
1864
|
positionals,
|
|
1806
1865
|
'Say the question: console ask "<question>" --option "<label>" --option "<label>"',
|
|
1807
1866
|
);
|
|
1867
|
+
const to = text(values, "to");
|
|
1868
|
+
if (to === "none") {
|
|
1869
|
+
throw misuse("Say whom the decision is for: --to <login|me>.");
|
|
1870
|
+
}
|
|
1808
1871
|
const options = texts(values, "option");
|
|
1809
1872
|
if (options.length < MIN_OPTIONS || options.length > MAX_OPTIONS) {
|
|
1810
1873
|
throw misuse(`Give ${MIN_OPTIONS} to ${MAX_OPTIONS} options, one --option each.`);
|
|
@@ -1814,21 +1877,58 @@ const ask: Command = async (args, io) => {
|
|
|
1814
1877
|
const session = await open(io, values);
|
|
1815
1878
|
const project = await session.project();
|
|
1816
1879
|
const runId = await currentRun(project, values);
|
|
1880
|
+
// Whom the decision is for (ADR-0042): the person the agent works for, unless --to names another.
|
|
1881
|
+
const deciderId = await personIdOf(session, to);
|
|
1817
1882
|
const raised = await project.raiseDecision({
|
|
1818
1883
|
question,
|
|
1819
1884
|
options: options.map((label) => ({ label })),
|
|
1820
1885
|
runId,
|
|
1821
1886
|
...(body === undefined ? {} : { body }),
|
|
1887
|
+
...(typeof deciderId === "string" ? { deciderId } : {}),
|
|
1822
1888
|
});
|
|
1823
1889
|
// The id is printed before any waiting, so that a wait cut short loses nothing.
|
|
1824
1890
|
io.stdout(
|
|
1825
1891
|
session.json
|
|
1826
1892
|
? `${JSON.stringify(raised, null, 2)}\n`
|
|
1827
|
-
: `Decision ${raised.id} raised on run ${runId}; the run waits for
|
|
1893
|
+
: `Decision ${raised.id} raised on run ${runId}; the run waits for ${raised.decider.login}.\ndecision id: ${raised.id}\n${formatOptions(raised)}\n`,
|
|
1828
1894
|
);
|
|
1829
1895
|
return settle(io, session, project, raised, seconds, true);
|
|
1830
1896
|
};
|
|
1831
1897
|
|
|
1898
|
+
/**
|
|
1899
|
+
* Writes a person's answer on a decision, in their name through the agent (ADR-0021): the
|
|
1900
|
+
* option they chose, or their own words, and a note about it, so that a choice made in chat
|
|
1901
|
+
* or in passing reaches the record the run waits on.
|
|
1902
|
+
*/
|
|
1903
|
+
const answering: Command = async (args, io) => {
|
|
1904
|
+
const { values, positionals } = parse(args, {
|
|
1905
|
+
option: { type: "string" },
|
|
1906
|
+
own: { type: "string" },
|
|
1907
|
+
note: { type: "string" },
|
|
1908
|
+
file: { type: "string" },
|
|
1909
|
+
});
|
|
1910
|
+
const id = theOne(
|
|
1911
|
+
positionals,
|
|
1912
|
+
'Say which decision: console answer <id> --option <n>|--own "<answer>" [--note <markdown>|--file <path>]',
|
|
1913
|
+
);
|
|
1914
|
+
const option = text(values, "option");
|
|
1915
|
+
const own = text(values, "own");
|
|
1916
|
+
if ((option === undefined) === (own === undefined)) {
|
|
1917
|
+
throw misuse(
|
|
1918
|
+
'Say the option chosen, --option <n>, or the person\'s own answer, --own "<words>": one of the two.',
|
|
1919
|
+
);
|
|
1920
|
+
}
|
|
1921
|
+
const note = await bodyOf(io, values, text(values, "note"));
|
|
1922
|
+
const session = await open(io, values);
|
|
1923
|
+
const project = await session.project();
|
|
1924
|
+
const answered = await project.answerDecision(id, {
|
|
1925
|
+
...(own === undefined ? { option } : { own }),
|
|
1926
|
+
...(note === undefined ? {} : { note }),
|
|
1927
|
+
});
|
|
1928
|
+
answer(io, session, answered, () => formatDecision(answered));
|
|
1929
|
+
return EXIT.ok;
|
|
1930
|
+
};
|
|
1931
|
+
|
|
1832
1932
|
const decision: Command = async (args, io) => {
|
|
1833
1933
|
const { values, positionals } = parse(args, {
|
|
1834
1934
|
wait: { type: "string" },
|
|
@@ -2139,14 +2239,37 @@ const goal: Command = async (args, io) => {
|
|
|
2139
2239
|
};
|
|
2140
2240
|
|
|
2141
2241
|
const decisions: Command = async (args, io) => {
|
|
2142
|
-
const { values } = parse(
|
|
2242
|
+
const { values } = parse(
|
|
2243
|
+
args,
|
|
2244
|
+
{
|
|
2245
|
+
open: { type: "boolean" },
|
|
2246
|
+
mine: { type: "boolean" },
|
|
2247
|
+
raised: { type: "boolean" },
|
|
2248
|
+
...PAGE_OPTIONS,
|
|
2249
|
+
},
|
|
2250
|
+
false,
|
|
2251
|
+
);
|
|
2143
2252
|
const page = pageOf(values);
|
|
2144
2253
|
const session = await open(io, values);
|
|
2254
|
+
const open_ = on(values, "open") ? { open: true } : {};
|
|
2255
|
+
if (on(values, "mine") || on(values, "raised")) {
|
|
2256
|
+
// One's own across the projects (ADR-0042), addressed to the person or raised by them for
|
|
2257
|
+
// someone else: the waiting first, each with its project's key.
|
|
2258
|
+
const raised = on(values, "raised");
|
|
2259
|
+
const found = await session.client.myDecisions({ ...open_, raised, ...page });
|
|
2260
|
+
answer(io, session, found, () =>
|
|
2261
|
+
found.items.length === 0
|
|
2262
|
+
? raised
|
|
2263
|
+
? "No decisions you asked of others."
|
|
2264
|
+
: "No decisions of yours."
|
|
2265
|
+
: found.items
|
|
2266
|
+
.map(({ project, decision }) => `${project.key} ${formatDecisionLine(decision)}`)
|
|
2267
|
+
.join("\n") + formatMore(found.more, page.limit, page.offset),
|
|
2268
|
+
);
|
|
2269
|
+
return EXIT.ok;
|
|
2270
|
+
}
|
|
2145
2271
|
const project = await session.project();
|
|
2146
|
-
const found = await project.decisions({
|
|
2147
|
-
...(on(values, "open") ? { open: true } : {}),
|
|
2148
|
-
...page,
|
|
2149
|
-
});
|
|
2272
|
+
const found = await project.decisions({ ...open_, ...page });
|
|
2150
2273
|
answer(io, session, found, () =>
|
|
2151
2274
|
found.items.length === 0
|
|
2152
2275
|
? "No decisions."
|
|
@@ -2384,8 +2507,8 @@ const workspace: Command = async (args, io) => {
|
|
|
2384
2507
|
set: (token) => client.setWorkspacePackToken({ token }),
|
|
2385
2508
|
remove: () => client.removeWorkspacePackToken(),
|
|
2386
2509
|
connect: () => client.connectWorkspacePackToken(),
|
|
2387
|
-
async
|
|
2388
|
-
const state = await client.
|
|
2510
|
+
async claim() {
|
|
2511
|
+
const state = await client.claimWorkspacePackTokenConnection();
|
|
2389
2512
|
return state.status === "connected"
|
|
2390
2513
|
? { status: "connected", held: state.workspace }
|
|
2391
2514
|
: state;
|
|
@@ -2545,7 +2668,8 @@ interface TokenHolder<T> {
|
|
|
2545
2668
|
set(token: string): Promise<T>;
|
|
2546
2669
|
remove(): Promise<T>;
|
|
2547
2670
|
connect(): Promise<RestPackConnectStarted>;
|
|
2548
|
-
|
|
2671
|
+
/** Asks the console to claim the token at the deployment (ADR-0046), and answers how it stands. */
|
|
2672
|
+
claim(): Promise<
|
|
2549
2673
|
| { readonly status: "none" }
|
|
2550
2674
|
| { readonly status: "pending" }
|
|
2551
2675
|
| { readonly status: "ended"; readonly reason: keyof typeof PACK_CONNECT_ENDED }
|
|
@@ -2577,7 +2701,7 @@ async function packToken<T>(
|
|
|
2577
2701
|
);
|
|
2578
2702
|
for (;;) {
|
|
2579
2703
|
await io.sleep(started.intervalSeconds * 1000);
|
|
2580
|
-
const state = await holder.
|
|
2704
|
+
const state = await holder.claim();
|
|
2581
2705
|
if (state.status === "pending") {
|
|
2582
2706
|
continue;
|
|
2583
2707
|
}
|
|
@@ -2625,8 +2749,8 @@ const projectPackToken: Command = async (args, io) => {
|
|
|
2625
2749
|
set: (token) => project.setPackToken({ token }),
|
|
2626
2750
|
remove: () => project.removePackToken(),
|
|
2627
2751
|
connect: () => project.connectPackToken(),
|
|
2628
|
-
async
|
|
2629
|
-
const state = await project.
|
|
2752
|
+
async claim() {
|
|
2753
|
+
const state = await project.claimPackTokenConnection();
|
|
2630
2754
|
return state.status === "connected" ? { status: "connected", held: state.project } : state;
|
|
2631
2755
|
},
|
|
2632
2756
|
},
|
|
@@ -2869,6 +2993,7 @@ const COMMANDS: Readonly<Record<string, Command>> = {
|
|
|
2869
2993
|
comment,
|
|
2870
2994
|
file,
|
|
2871
2995
|
ask,
|
|
2996
|
+
answer: answering,
|
|
2872
2997
|
decision,
|
|
2873
2998
|
decisions,
|
|
2874
2999
|
finish: ending("finished"),
|
|
@@ -3006,6 +3131,10 @@ function hintFor(error: ApiError, io: CliIo, seen: ConsoleSeen): string {
|
|
|
3006
3131
|
return `Install the console's version: ${updateWords(io, seen.version)}; or ask the console's operator to update the console.\n`;
|
|
3007
3132
|
case "auth.required":
|
|
3008
3133
|
return "The token is not one the console knows, any more or at all. A person signs the command in again: console login\n";
|
|
3134
|
+
case "auth.deactivated":
|
|
3135
|
+
return "Tell the person: they are taken back in on the People page, by an administrator or by their organization, and this token works again then. console logout forgets it here meanwhile.\n";
|
|
3136
|
+
case "auth.not_admitted":
|
|
3137
|
+
return "Tell the person: they are back in when what let them in is named again, or when an administrator lists their login and they sign in again, and this token works again then. console logout forgets it here meanwhile.\n";
|
|
3009
3138
|
case "project.not_found":
|
|
3010
3139
|
return "No project has this key, or it is not yours to see. console projects lists the projects you may work in.\n";
|
|
3011
3140
|
case "document.not_found":
|
|
@@ -3030,6 +3159,20 @@ function hintFor(error: ApiError, io: CliIo, seen: ConsoleSeen): string {
|
|
|
3030
3159
|
return "What was asked is an administrator's, or an owner's of the project, and the person this token acts as is not one here. Hand the step to them.\n";
|
|
3031
3160
|
case "project.key_taken":
|
|
3032
3161
|
return "A project has that key already. console projects lists them.\n";
|
|
3162
|
+
case "project.too_many":
|
|
3163
|
+
return "The workspace holds as many projects as one may. Work goes on in a project there is.\n";
|
|
3164
|
+
case "project.too_many_bytes":
|
|
3165
|
+
return "The project's files hold as many bytes together as this console allows. Hand in a link to where the file is instead, and say so in the report.\n";
|
|
3166
|
+
case "task.too_many":
|
|
3167
|
+
return "The project holds as many tasks as one may, those put away counted. The work goes on in another project; ask the person which.\n";
|
|
3168
|
+
case "goal.too_many":
|
|
3169
|
+
return "The project holds as many goals as one may. console goals lists them; one done or dropped is still a goal.\n";
|
|
3170
|
+
case "decision.too_many":
|
|
3171
|
+
return "The project holds as many decisions as one may. Ask the person in the report instead.\n";
|
|
3172
|
+
case "document.too_many":
|
|
3173
|
+
return "The project holds as many pages as one may. Write on a page there is: console docs lists them.\n";
|
|
3174
|
+
case "run.too_many":
|
|
3175
|
+
return "The task has been taken as many times as one may. Write a new task for what is left, and take that.\n";
|
|
3033
3176
|
case "project.invalid_address":
|
|
3034
3177
|
return "The skills address is not one as SkillCDN spells it; none makes the organization's skills the project's.\n";
|
|
3035
3178
|
case "project.invalid_icon":
|
package/src/cli/format.ts
CHANGED
|
@@ -386,7 +386,10 @@ export function formatWork(work: RestWork): string {
|
|
|
386
386
|
lines.push(` ${project.key} ${formatTaskLine(task)}`);
|
|
387
387
|
}
|
|
388
388
|
}
|
|
389
|
-
lines.push(
|
|
389
|
+
lines.push(
|
|
390
|
+
"",
|
|
391
|
+
work.decisions.length === 0 ? "decisions waiting for you: none" : "decisions waiting for you:",
|
|
392
|
+
);
|
|
390
393
|
for (const { project, decision } of work.decisions) {
|
|
391
394
|
lines.push(` ${project.key} ${formatDecisionLine(decision)}`);
|
|
392
395
|
}
|
|
@@ -404,9 +407,13 @@ export function formatPersonWork(person: RestPerson, work: RestPersonWork): stri
|
|
|
404
407
|
].join("\n");
|
|
405
408
|
}
|
|
406
409
|
|
|
410
|
+
/** Whom a decision is for, where that is not the one who asked (ADR-0042). */
|
|
411
|
+
const addressed = (decision: RestDecision): string =>
|
|
412
|
+
decision.decider.id === decision.raisedBy.id ? "" : `, for ${decision.decider.login}`;
|
|
413
|
+
|
|
407
414
|
export function formatDecisionLine(decision: RestDecision): string {
|
|
408
415
|
const state = decision.answer === null ? "waiting" : `answered ${decision.answer.option}`;
|
|
409
|
-
return `${decision.id} ${state} ${decision.question} (asked by ${asker(decision)})`;
|
|
416
|
+
return `${decision.id} ${state} ${decision.question} (asked by ${asker(decision)}${addressed(decision)})`;
|
|
410
417
|
}
|
|
411
418
|
|
|
412
419
|
/** The options, one a line; the person's own answer, when they wrote one, is the last and says so. */
|
|
@@ -423,7 +430,7 @@ export function formatOptions(decision: RestDecision): string {
|
|
|
423
430
|
export function formatAnswer(decision: RestDecision): string {
|
|
424
431
|
const { answer } = decision;
|
|
425
432
|
if (answer === null) {
|
|
426
|
-
return
|
|
433
|
+
return `waits for ${decision.decider.login}.`;
|
|
427
434
|
}
|
|
428
435
|
const chosen = decision.options.find((option) => option.id === answer.option);
|
|
429
436
|
const lines = [
|
|
@@ -438,7 +445,7 @@ export function formatAnswer(decision: RestDecision): string {
|
|
|
438
445
|
export function formatDecision(decision: RestDecision): string {
|
|
439
446
|
const lines = [
|
|
440
447
|
`decision ${decision.id}: ${decision.question}`,
|
|
441
|
-
`asked by ${asker(decision)}${decision.taskNumber === null ? "" : `, about task #${decision.taskNumber}`}`,
|
|
448
|
+
`asked by ${asker(decision)}${addressed(decision)}${decision.taskNumber === null ? "" : `, about task #${decision.taskNumber}`}`,
|
|
442
449
|
];
|
|
443
450
|
if (decision.body.trim().length > 0) {
|
|
444
451
|
lines.push("", decision.body.trimEnd());
|
package/src/cli/help.ts
CHANGED
|
@@ -7,12 +7,16 @@ import {
|
|
|
7
7
|
MAX_CATEGORY_KEY_LENGTH,
|
|
8
8
|
MAX_CATEGORY_NAME_LENGTH,
|
|
9
9
|
MAX_COMMENTS_PER_TASK,
|
|
10
|
+
MAX_DECISIONS_PER_PROJECT,
|
|
10
11
|
MAX_DOCUMENT_LENGTH,
|
|
11
12
|
MAX_DOCUMENT_PATH_LENGTH,
|
|
13
|
+
MAX_DOCUMENTS_PER_PROJECT,
|
|
12
14
|
MAX_FILE_BYTES,
|
|
13
15
|
MAX_FILES_PER_COMMENT,
|
|
14
16
|
MAX_FILES_PER_DOCUMENT,
|
|
17
|
+
MAX_GOALS_PER_PROJECT,
|
|
15
18
|
MAX_LINK_LABEL_LENGTH,
|
|
19
|
+
MAX_NOTE_LENGTH,
|
|
16
20
|
MAX_OPTION_LABEL_LENGTH,
|
|
17
21
|
MAX_OPTIONS,
|
|
18
22
|
MAX_PROJECT_DESCRIPTION_LENGTH,
|
|
@@ -20,11 +24,14 @@ import {
|
|
|
20
24
|
MAX_PROJECT_KEY_LENGTH,
|
|
21
25
|
MAX_PROJECT_NAME_LENGTH,
|
|
22
26
|
MAX_PROJECT_SYMBOL_LENGTH,
|
|
27
|
+
MAX_PROJECTS_PER_WORKSPACE,
|
|
23
28
|
MAX_QUESTION_LENGTH,
|
|
24
29
|
MAX_REPORTS_PER_RUN,
|
|
25
30
|
MAX_RULES_LENGTH,
|
|
31
|
+
MAX_RUNS_PER_TASK,
|
|
26
32
|
MAX_SEARCH_LENGTH,
|
|
27
33
|
MAX_SUMMARY_LENGTH,
|
|
34
|
+
MAX_TASKS_PER_PROJECT,
|
|
28
35
|
MAX_TITLE_LENGTH,
|
|
29
36
|
MAX_VERSIONS_PER_DOCUMENT,
|
|
30
37
|
MAX_WORKERS,
|
|
@@ -58,6 +65,7 @@ export interface CommandHelp {
|
|
|
58
65
|
/** The refusals any command may meet, said once in the overview. */
|
|
59
66
|
const COMMON_REFUSALS = [
|
|
60
67
|
"auth.required: the token is not one the console knows, any more or at all; a person signs the command in again",
|
|
68
|
+
"auth.deactivated, auth.not_admitted: the person this token acts as is out, deactivated or no longer let in; the console keeps the token, and it works again when they are back in",
|
|
61
69
|
"request.invalid: what was sent is over a limit or malformed; the message names the field",
|
|
62
70
|
"network: the console could not be reached at its address",
|
|
63
71
|
];
|
|
@@ -147,9 +155,9 @@ export const COMMAND_HELP: Readonly<Record<string, CommandHelp>> = {
|
|
|
147
155
|
work: {
|
|
148
156
|
usage: "work [--person <login>]",
|
|
149
157
|
synopsis:
|
|
150
|
-
"What is on your plate across your projects: your open tasks, and the decisions waiting.",
|
|
158
|
+
"What is on your plate across your projects: your open tasks, and the decisions waiting for you.",
|
|
151
159
|
about:
|
|
152
|
-
"What is on your plate across the projects you may see: the open tasks you work on, the sooner due first, each with its project; and the decisions waiting for
|
|
160
|
+
"What is on your plate across the projects you may see: the open tasks you work on, the sooner due first, each with its project; and the decisions waiting for your answer (ADR-0042). Needs no project. --person <login> shows another person's plate, for an administrator or for an owner of a project they are in: the open tasks they work on within the projects you may see, without the decisions.",
|
|
153
161
|
},
|
|
154
162
|
tasks: {
|
|
155
163
|
usage:
|
|
@@ -170,8 +178,13 @@ export const COMMAND_HELP: Readonly<Record<string, CommandHelp>> = {
|
|
|
170
178
|
`title: one line, up to ${MAX_TITLE_LENGTH} characters, saying what is to be done on its own; what it refers to goes in the body`,
|
|
171
179
|
`body: ${MARKDOWN}`,
|
|
172
180
|
...TASK_FIELD_LIMITS,
|
|
181
|
+
`at most ${MAX_TASKS_PER_PROJECT} tasks in one project, those put away counted`,
|
|
182
|
+
],
|
|
183
|
+
refusals: [
|
|
184
|
+
"task.not_found: no task has that number or id",
|
|
185
|
+
...TASK_FIELD_REFUSALS,
|
|
186
|
+
"task.too_many: the project holds as many tasks as one may; the work goes on in another project",
|
|
173
187
|
],
|
|
174
|
-
refusals: ["task.not_found: no task has that number or id", ...TASK_FIELD_REFUSALS],
|
|
175
188
|
},
|
|
176
189
|
goals: {
|
|
177
190
|
usage:
|
|
@@ -192,11 +205,13 @@ export const COMMAND_HELP: Readonly<Record<string, CommandHelp>> = {
|
|
|
192
205
|
`title: one line, up to ${MAX_TITLE_LENGTH} characters`,
|
|
193
206
|
`body: ${MARKDOWN}`,
|
|
194
207
|
`starts, due: ${DAY}`,
|
|
208
|
+
`at most ${MAX_GOALS_PER_PROJECT} goals in one project`,
|
|
195
209
|
],
|
|
196
210
|
refusals: [
|
|
197
211
|
"goal.not_found: no goal of this project has that id",
|
|
198
212
|
"goal.invalid_category: no category of the workspace has that key",
|
|
199
213
|
"goal.invalid_dates: the target day is before the start",
|
|
214
|
+
"goal.too_many: the project holds as many goals as one may",
|
|
200
215
|
"auth.forbidden: only an owner of the project sets its roadmap",
|
|
201
216
|
],
|
|
202
217
|
},
|
|
@@ -258,11 +273,13 @@ export const COMMAND_HELP: Readonly<Record<string, CommandHelp>> = {
|
|
|
258
273
|
`name: one line, up to ${MAX_PROJECT_NAME_LENGTH} characters; description: up to ${MAX_PROJECT_DESCRIPTION_LENGTH}`,
|
|
259
274
|
`color: ${COLORS}; symbol: up to ${MAX_PROJECT_SYMBOL_LENGTH} characters without spaces, shown on the colour; left out, the pages choose both from the key and the name`,
|
|
260
275
|
`image: a PNG, a JPEG, a GIF or a WebP of at most ${MAX_PROJECT_ICON_BYTES} bytes`,
|
|
276
|
+
`at most ${MAX_PROJECTS_PER_WORKSPACE} projects in the workspace`,
|
|
261
277
|
],
|
|
262
278
|
refusals: [
|
|
263
279
|
"project.not_found: no project has that key, or it is not yours to see",
|
|
264
|
-
"auth.forbidden: only an
|
|
280
|
+
"auth.forbidden: only an administrator makes a project, and only an owner changes it",
|
|
265
281
|
"project.key_taken: a project has that key already",
|
|
282
|
+
"project.too_many: the workspace holds as many projects as one may",
|
|
266
283
|
"project.invalid_address: the skills address is not one as SkillCDN spells it",
|
|
267
284
|
"project.invalid_icon: the file is not an image of those kinds, by its bytes",
|
|
268
285
|
"request.too_large: the image is over the limit",
|
|
@@ -313,11 +330,11 @@ export const COMMAND_HELP: Readonly<Record<string, CommandHelp>> = {
|
|
|
313
330
|
},
|
|
314
331
|
skills: {
|
|
315
332
|
usage:
|
|
316
|
-
"skills | skills <folder> | skills --search <words> [<folder>] [--limit <n>] [--cursor <cursor>]",
|
|
333
|
+
"skills | skills <folder|file> | skills --search <words> [<folder>] [--limit <n>] [--cursor <cursor>]",
|
|
317
334
|
synopsis:
|
|
318
|
-
"The project's pack: its skills; what a folder of it holds; or what words find in it.",
|
|
335
|
+
"The project's pack: its skills; what a folder of it holds, or a document's outline; or what words find in it.",
|
|
319
336
|
about:
|
|
320
|
-
"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
|
|
337
|
+
"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 a file's path: the file's outline, every heading with its level and the offset and limit that read its section with console skill --file, whole; a file that is not Markdown has none. With --search: what the words find, as search_repo does: skills first, with the files of theirs that matched, then documents, each with the sections of it that matched and what reads each, in relevance order; words in the language the pack is written in, and meaning too where the deployment searches by it, which the result then says; 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 or an outline joined.",
|
|
321
338
|
limits: ["search: 1 to 500 characters; limit: 1 to 25"],
|
|
322
339
|
refusals: [
|
|
323
340
|
"status not_found: the pack is not served to the console; private, with no pack token on the project",
|
|
@@ -325,11 +342,12 @@ export const COMMAND_HELP: Readonly<Record<string, CommandHelp>> = {
|
|
|
325
342
|
],
|
|
326
343
|
},
|
|
327
344
|
skill: {
|
|
328
|
-
usage: "skill <path> | skill --file <path>",
|
|
345
|
+
usage: "skill <path> | skill --file <path> [--offset <n>] [--limit <n>]",
|
|
329
346
|
synopsis:
|
|
330
|
-
"One skill of the pack whole, its rules first; or with --file a file of the pack, or what a folder holds.",
|
|
347
|
+
"One skill of the pack whole, its rules first; or with --file a file of the pack, one section of it, or what a folder holds.",
|
|
331
348
|
about:
|
|
332
|
-
"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.",
|
|
349
|
+
"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. --offset <n> and --limit <n>, with --file, read one page of the file as asked, from that character on and at most that many characters, as a search or an outline (console skills <file>) names a section, instead of the file whole; the result says where the file continues. --json answers with what the pack answered, in the shapes of the main repository's REST API, the pages joined.",
|
|
350
|
+
limits: ["offset: 0 or more; limit: 1 to 100000 characters; both with --file"],
|
|
333
351
|
refusals: [
|
|
334
352
|
"status not_found: the pack is not served to the console; private, with no pack token on the project",
|
|
335
353
|
"status token_invalid: the pack token the project holds no longer works; an owner sets a new one",
|
|
@@ -356,10 +374,14 @@ export const COMMAND_HELP: Readonly<Record<string, CommandHelp>> = {
|
|
|
356
374
|
synopsis: "Takes a task: a run begins, and the task is in progress and the person's.",
|
|
357
375
|
about:
|
|
358
376
|
"Takes a task: a run begins, and the task is in progress and the person's; the run's id and the task's id are printed on a line of their own, then the task, then the rules of the board. A run still open on the task is taken over, since the board cannot know whether its agent still runs: it ends as abandoned, the feed says who took over, and that agent is refused on its next command; console task <number> shows the runs on a task, with when each was last heard from, before it is taken. --agent is what people see at work; left out, it is what the person called the token.",
|
|
359
|
-
limits: [
|
|
377
|
+
limits: [
|
|
378
|
+
`agent: one line, up to ${MAX_AGENT_LENGTH} characters`,
|
|
379
|
+
`at most ${MAX_RUNS_PER_TASK} runs on one task`,
|
|
380
|
+
],
|
|
360
381
|
refusals: [
|
|
361
382
|
"task.not_found: no task has that number or id",
|
|
362
383
|
"run.task_closed: the task is done or dropped",
|
|
384
|
+
"run.too_many: the task has been taken as many times as one may; write a new task for what is left",
|
|
363
385
|
],
|
|
364
386
|
},
|
|
365
387
|
report: {
|
|
@@ -389,22 +411,45 @@ export const COMMAND_HELP: Readonly<Record<string, CommandHelp>> = {
|
|
|
389
411
|
...RUN_REFUSALS,
|
|
390
412
|
"run.too_many_artifacts: the run carries as many as one may",
|
|
391
413
|
"request.too_large: the file is over the limit",
|
|
414
|
+
"project.too_many_bytes: the project's files hold as many bytes together as this console allows; hand in a link instead",
|
|
392
415
|
],
|
|
393
416
|
},
|
|
394
417
|
ask: {
|
|
395
418
|
usage:
|
|
396
|
-
'ask "<question>" --option "<label>" --option "<label>" [...] [--body <markdown>|--file <path>] [--wait <seconds>] [--run <id>]',
|
|
419
|
+
'ask "<question>" --option "<label>" --option "<label>" [...] [--body <markdown>|--file <path>] [--to <login|me>] [--wait <seconds>] [--run <id>]',
|
|
397
420
|
overview:
|
|
398
|
-
'ask "<question>" --option "<label>" --option "<label>" [...] [--body <markdown>|--file <path>] [--wait <seconds>]',
|
|
421
|
+
'ask "<question>" --option "<label>" --option "<label>" [...] [--body <markdown>|--file <path>] [--to <login|me>] [--wait <seconds>]',
|
|
399
422
|
synopsis:
|
|
400
423
|
"Raises a decision a person must make, with options, and waits a while for the answer.",
|
|
401
|
-
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}`,
|
|
424
|
+
about: `Raises a decision a person must make: the question, the options to choose from, and what they need to know. It is for the person you work for unless --to names another of the project, who then finds it among their decisions (ADR-0042); anyone of the project may still answer. 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}`,
|
|
402
425
|
limits: [
|
|
403
426
|
`question: one line, up to ${MAX_QUESTION_LENGTH} characters`,
|
|
404
427
|
`options: ${MIN_OPTIONS} to ${MAX_OPTIONS}, each one line up to ${MAX_OPTION_LABEL_LENGTH} characters`,
|
|
405
428
|
`body: ${MARKDOWN}`,
|
|
429
|
+
"to: a login of the project, or me",
|
|
430
|
+
`at most ${MAX_DECISIONS_PER_PROJECT} decisions in one project`,
|
|
431
|
+
],
|
|
432
|
+
refusals: [
|
|
433
|
+
...RUN_CHOICE,
|
|
434
|
+
"decision.invalid_run: the run is not yours, or is over",
|
|
435
|
+
"decision.invalid_decider: the person named may not work in the project",
|
|
436
|
+
"decision.too_many: the project holds as many decisions as one may",
|
|
437
|
+
],
|
|
438
|
+
},
|
|
439
|
+
answer: {
|
|
440
|
+
usage: 'answer <id> --option <n>|--own "<answer>" [--note <markdown>|--file <path>]',
|
|
441
|
+
synopsis: "Writes a person's answer on a decision: the option they chose, or their own words.",
|
|
442
|
+
about:
|
|
443
|
+
"Writes on the board the answer a person gave: one of the decision's options by its number, or their own words, which become one more option of the decision marked as theirs; and a note about it. The answer is the person's, written in their name through you (ADR-0021): a choice they made in chat, in a meeting or by changing the task is written here, with where and when they made it in the note, so that the record is whole and a run that waited goes on. A decision is answered once; what followed is written with console decision <id> --outcome.",
|
|
444
|
+
limits: [
|
|
445
|
+
`own: one line, up to ${MAX_OPTION_LABEL_LENGTH} characters`,
|
|
446
|
+
`note: Markdown, up to ${MAX_NOTE_LENGTH} characters`,
|
|
447
|
+
],
|
|
448
|
+
refusals: [
|
|
449
|
+
"decision.not_found: no decision has that id",
|
|
450
|
+
"decision.answered: the decision has an answer already",
|
|
451
|
+
"decision.no_such_option: the option is not one of the decision's",
|
|
406
452
|
],
|
|
407
|
-
refusals: [...RUN_CHOICE, "decision.invalid_run: the run is not yours, or is over"],
|
|
408
453
|
},
|
|
409
454
|
decision: {
|
|
410
455
|
usage: "decision <id> [--wait <seconds>] | decision <id> --outcome <markdown>|--file <path>",
|
|
@@ -416,9 +461,9 @@ export const COMMAND_HELP: Readonly<Record<string, CommandHelp>> = {
|
|
|
416
461
|
refusals: ["decision.not_found: no decision has that id"],
|
|
417
462
|
},
|
|
418
463
|
decisions: {
|
|
419
|
-
usage: "decisions [--open] [--limit <n>] [--offset <n>]",
|
|
420
|
-
synopsis: "The decisions on the board, the waiting first.",
|
|
421
|
-
about: `The decisions on the board, the waiting first; --open keeps only those. A page at a time: ${DEFAULT_PAGE_LIMIT} unless --limit says otherwise, from --offset on.`,
|
|
464
|
+
usage: "decisions [--open] [--mine|--raised] [--limit <n>] [--offset <n>]",
|
|
465
|
+
synopsis: "The decisions on the board, the waiting first; or your own across the projects.",
|
|
466
|
+
about: `The decisions on the board, the waiting first; --open keeps only those. --mine lists the decisions addressed to you instead (ADR-0042), and --raised those you asked of someone else, through your agent or yourself, each across the projects you may see with its project's key; neither needs a project. A page at a time: ${DEFAULT_PAGE_LIMIT} unless --limit says otherwise, from --offset on.`,
|
|
422
467
|
},
|
|
423
468
|
finish: {
|
|
424
469
|
usage: 'finish [--summary "<markdown>"|--file <path>] [--run <id>]',
|
|
@@ -472,6 +517,7 @@ export const COMMAND_HELP: Readonly<Record<string, CommandHelp>> = {
|
|
|
472
517
|
"comment.too_many: the task carries as many comments as one may",
|
|
473
518
|
"comment.too_many_files: more files than one comment may carry",
|
|
474
519
|
"request.too_large: the files are over the limit together",
|
|
520
|
+
"project.too_many_bytes: the project's files hold as many bytes together as this console allows; say where the file is instead",
|
|
475
521
|
],
|
|
476
522
|
},
|
|
477
523
|
file: {
|
|
@@ -503,13 +549,14 @@ export const COMMAND_HELP: Readonly<Record<string, CommandHelp>> = {
|
|
|
503
549
|
`path: ${DOCUMENT_PATH}`,
|
|
504
550
|
`title: one line, up to ${MAX_TITLE_LENGTH} characters`,
|
|
505
551
|
`body: Markdown, up to ${MAX_DOCUMENT_LENGTH} characters`,
|
|
506
|
-
`at most ${MAX_VERSIONS_PER_DOCUMENT} versions of one page`,
|
|
552
|
+
`at most ${MAX_VERSIONS_PER_DOCUMENT} versions of one page, and ${MAX_DOCUMENTS_PER_PROJECT} pages in one project`,
|
|
507
553
|
],
|
|
508
554
|
refusals: [
|
|
509
555
|
"document.invalid_path: the path is not one",
|
|
510
556
|
"document.conflict: the page has moved on since --base; read it again",
|
|
511
557
|
"document.archived: the page is archived; restore it first",
|
|
512
558
|
"document.too_many_versions: the page carries as many versions as one may; write a new page",
|
|
559
|
+
"document.too_many: the project holds as many pages as one may; write on a page there is",
|
|
513
560
|
],
|
|
514
561
|
},
|
|
515
562
|
attach: {
|
|
@@ -526,6 +573,7 @@ export const COMMAND_HELP: Readonly<Record<string, CommandHelp>> = {
|
|
|
526
573
|
"document.archived: the page is archived; restore it first",
|
|
527
574
|
"document.too_many_files: the page carries as many files as one may",
|
|
528
575
|
"request.too_large: the file is over the limit",
|
|
576
|
+
"project.too_many_bytes: the project's files hold as many bytes together as this console allows; link to where the file is instead",
|
|
529
577
|
],
|
|
530
578
|
},
|
|
531
579
|
archive: {
|
|
@@ -622,7 +670,18 @@ const SECTIONS: readonly { readonly title: string; readonly commands: readonly s
|
|
|
622
670
|
},
|
|
623
671
|
{
|
|
624
672
|
title: "Working",
|
|
625
|
-
commands: [
|
|
673
|
+
commands: [
|
|
674
|
+
"take",
|
|
675
|
+
"report",
|
|
676
|
+
"hand-in",
|
|
677
|
+
"comment",
|
|
678
|
+
"file",
|
|
679
|
+
"ask",
|
|
680
|
+
"answer",
|
|
681
|
+
"finish",
|
|
682
|
+
"fail",
|
|
683
|
+
"abandon",
|
|
684
|
+
],
|
|
626
685
|
},
|
|
627
686
|
{
|
|
628
687
|
title: "The documents: the project's pages of Markdown, in folders, by path",
|