@miadi/chronicle-tui 0.3.0 → 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/dist/api.d.ts CHANGED
@@ -1,21 +1,30 @@
1
1
  /**
2
- * The browser as a known reader of the Miadi app (phase P2, jgwill/Miadi#706).
2
+ * The browser as a known reader of the Miadi app (jgwill/Miadi#706).
3
3
  *
4
4
  * Reads that need no one (the catalog, files, search) stay on the local
5
5
  * checkout. Anything that depends on who is reading, and every write, goes
6
- * through the app's own routes with the writer token, so the app keeps the
7
- * one gate it already has (`lib/api-access.ts`, `lib/identity.ts`).
6
+ * through the app's own routes, so the app keeps the one gate it already has
7
+ * (`lib/api-access.ts`, `lib/identity.ts`, `lib/ceremony-access.ts`).
8
8
  *
9
- * - the token: `MIADI_API_TOKEN_WRITER`, sent as `Authorization: Bearer`
10
- * - the app: `--url`, else the first of MIADI_WEB_URL (or 127.0.0.1:3335),
11
- * MIADI_URL_BASE_INTERNAL, MIADI_URL_BASE whose /api/health answers
12
- * - `--env <file>` loads either or both from a file before anything is read
9
+ * Two tokens, each for what it is:
10
+ * - `MIADI_PERSON_TOKEN` is a person. It is the bearer of every read, so a
11
+ * ceremony or circle shows what that person's seat allows and nothing more.
12
+ * - `MIADI_API_TOKEN_WRITER` passes the write gate. It is the bearer of writes,
13
+ * with the person named beside it in `x-miadi-person-token`, the way the app
14
+ * expects an agent acting for someone (`lib/review-ceremony.ts`).
15
+ * Either alone works for what it can do. A token is only ever sent to the app
16
+ * chosen at start, and never over plain http to a host that is not this one.
13
17
  */
14
18
  export declare const TOKEN_ENV = "MIADI_API_TOKEN_WRITER";
19
+ export declare const PERSON_TOKEN_ENV = "MIADI_PERSON_TOKEN";
20
+ export declare const PERSON_TOKEN_HEADER = "x-miadi-person-token";
21
+ /** What `--env` may set. Anything else in the file (PATH included) is left alone. */
22
+ export declare const ENV_FILE_KEYS: readonly ["MIADI_API_TOKEN_WRITER", "MIADI_PERSON_TOKEN", "MIADI_CHRONICLE_ROOT", "MIADI_WEB_URL", "MIADI_URL_BASE_INTERNAL", "MIADI_URL_BASE", "MIADI_CHRONICLE_MW_URL"];
15
23
  /**
16
- * Load `KEY=value` lines into the environment: `export` prefixes, quotes and
17
- * `#` comments are understood, nothing is expanded. A key given by the file
18
- * wins over one already set, since the file was named on purpose.
24
+ * Load the allowed `KEY=value` lines of a file into the environment: `export`
25
+ * prefixes, quotes and `#` comments are understood, nothing is expanded. A key
26
+ * the file sets wins over one already set, since the file was named on purpose.
27
+ * Returns the keys it set.
19
28
  */
20
29
  export declare function loadEnvFile(path: string, env?: NodeJS.ProcessEnv): string[];
21
30
  export interface Reader {
@@ -34,34 +43,50 @@ export declare class ApiError extends Error {
34
43
  readonly code?: string | undefined;
35
44
  constructor(message: string, status: number, code?: string | undefined);
36
45
  }
46
+ /** A token may travel to https, or to plain http on this machine only. */
47
+ export declare function mayCarryToken(base: string): boolean;
48
+ export interface Tokens {
49
+ writer?: string;
50
+ person?: string;
51
+ }
37
52
  export declare class MiadiApi {
38
53
  readonly base: string;
39
- private readonly token?;
40
- constructor(base: string, token?: string | undefined);
54
+ private readonly tokens;
55
+ /** Set once the app has answered who is reading; false when it refused the token. */
56
+ accepted: boolean | undefined;
57
+ constructor(base: string, tokens?: Tokens);
58
+ /** A token is set (whether or not the app accepted it yet). */
41
59
  get signed(): boolean;
60
+ /** A person is named, so seats apply. */
61
+ get asPerson(): boolean;
62
+ /** Writes are offered: a token is set and the app did not refuse it. */
63
+ get mayWrite(): boolean;
64
+ private headers;
42
65
  private call;
43
66
  get<T>(path: string): Promise<T>;
44
67
  post<T>(path: string, body: unknown): Promise<T>;
68
+ /** Who the app says is reading. Marks the client refused on 401 or 403. */
45
69
  me(): Promise<Reader | null>;
70
+ /** Would the app record a write from this client? The web room asks the attention door the same. */
71
+ mayAnswer(): Promise<boolean>;
46
72
  }
47
- /** The app this browser talks to, or null when none answers. */
48
- export declare function connectApi(url?: string, env?: NodeJS.ProcessEnv): Promise<MiadiApi | null>;
49
- export interface AttentionItem {
50
- id: string;
51
- question: string;
52
- unlocks?: string;
53
- asked?: string;
54
- state: "open" | "answered" | string;
55
- answer: string | null;
56
- answered_at: string | null;
57
- episode?: string;
73
+ export interface Connection {
74
+ api: MiadiApi | null;
75
+ /** Why a token was not attached, when one was set. */
76
+ warning?: string;
58
77
  }
59
- export declare function listAttention(api: MiadiApi, episode: string): Promise<{
60
- items: AttentionItem[];
61
- canAnswer: boolean;
62
- }>;
78
+ /**
79
+ * The app this browser talks to. `--url` wins; otherwise the local app, then
80
+ * the tailnet one (`MIADI_URL_BASE_INTERNAL`). The public front is used only
81
+ * when named with `--url`, so a token never goes there by accident. Probes
82
+ * carry no token.
83
+ */
84
+ export declare function connectApi(url?: string, env?: NodeJS.ProcessEnv): Promise<Connection>;
63
85
  export declare function answerAttention(api: MiadiApi, episode: string, id: string, answer: string): Promise<{
64
86
  ok: boolean;
87
+ result?: {
88
+ synchronized?: boolean;
89
+ };
65
90
  }>;
66
91
  export interface CeremonyCard {
67
92
  kind: "ceremony";
@@ -88,9 +113,9 @@ export interface CircleCard {
88
113
  can: string[];
89
114
  }
90
115
  /**
91
- * What a ceremony shows a reader the app lets in: its kind, direction,
92
- * intention, episode, circle and whether it is closed. Never its turns: those
93
- * are people's words, read in the circle (jgwill/Miadi#680, D3).
116
+ * What a ceremony shows a seated reader: its kind, direction, intention,
117
+ * episode, circle and whether it is closed. Never its turns: those are
118
+ * people's words, read in the circle (jgwill/Miadi#680, D3).
94
119
  */
95
120
  export declare function ceremonyCard(api: MiadiApi, id: string): Promise<CeremonyCard>;
96
121
  export declare function circleCard(api: MiadiApi, id: string): Promise<CircleCard>;
@@ -100,5 +125,8 @@ export declare function addReview(api: MiadiApi, episode: string, review: string
100
125
  title?: string;
101
126
  id?: string;
102
127
  };
128
+ ceremony?: {
129
+ state?: string;
130
+ };
103
131
  }>;
104
132
  //# sourceMappingURL=api.d.ts.map
package/dist/api.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAKH,eAAO,MAAM,SAAS,2BAA2B,CAAA;AAEjD;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,MAAM,EAAE,CAexF;AAED,MAAM,WAAW,MAAM;IACrB,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,kCAAkC;IAClC,OAAO,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CAC7C;AAED,qBAAa,QAAS,SAAQ,KAAK;IAG/B,QAAQ,CAAC,MAAM,EAAE,MAAM;IACvB,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM;gBAFtB,OAAO,EAAE,MAAM,EACN,MAAM,EAAE,MAAM,EACd,IAAI,CAAC,EAAE,MAAM,YAAA;CAIzB;AAED,qBAAa,QAAQ;IAEjB,QAAQ,CAAC,IAAI,EAAE,MAAM;IACrB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC;gBADd,IAAI,EAAE,MAAM,EACJ,KAAK,CAAC,EAAE,MAAM,YAAA;IAGjC,IAAI,MAAM,IAAI,OAAO,CAEpB;YAEa,IAAI;IA+BlB,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC;IAIhC,IAAI,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC;IAI1C,EAAE,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;CAgBnC;AAeD,gEAAgE;AAChE,wBAAsB,UAAU,CAAC,GAAG,CAAC,EAAE,MAAM,EAAE,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,CAQ7G;AAMD,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAA;IACV,QAAQ,EAAE,MAAM,CAAA;IAChB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,KAAK,EAAE,MAAM,GAAG,UAAU,GAAG,MAAM,CAAA;IACnC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAA;IACrB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1B,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB;AAED,wBAAsB,aAAa,CAAC,GAAG,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC;IAAE,KAAK,EAAE,aAAa,EAAE,CAAC;IAAC,SAAS,EAAE,OAAO,CAAA;CAAE,CAAC,CAK3H;AAED,wBAAgB,eAAe,CAAC,GAAG,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC;IAAE,EAAE,EAAE,OAAO,CAAA;CAAE,CAAC,CAEpH;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,UAAU,CAAA;IAChB,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,UAAU,EAAE,MAAM,EAAE,CAAA;IACpB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,MAAM,EAAE,OAAO,CAAA;IACf,6DAA6D;IAC7D,GAAG,EAAE,MAAM,EAAE,CAAA;CACd;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,QAAQ,CAAA;IACd,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,MAAM,CAAA;IACZ,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,OAAO,CAAA;IACf,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,UAAU,EAAE,MAAM,CAAA;IAClB,GAAG,EAAE,MAAM,EAAE,CAAA;CACd;AAKD;;;;GAIG;AACH,wBAAsB,YAAY,CAAC,GAAG,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CAqBnF;AAED,wBAAsB,UAAU,CAAC,GAAG,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAkB/E;AAED,wBAAgB,SAAS,CAAC,GAAG,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC;IAAE,EAAE,CAAC,EAAE,OAAO,CAAC;IAAC,MAAM,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,EAAE,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE,CAAC,CAE7I"}
1
+ {"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"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"}
package/dist/api.js CHANGED
@@ -1,39 +1,57 @@
1
1
  /**
2
- * The browser as a known reader of the Miadi app (phase P2, jgwill/Miadi#706).
2
+ * The browser as a known reader of the Miadi app (jgwill/Miadi#706).
3
3
  *
4
4
  * Reads that need no one (the catalog, files, search) stay on the local
5
5
  * checkout. Anything that depends on who is reading, and every write, goes
6
- * through the app's own routes with the writer token, so the app keeps the
7
- * one gate it already has (`lib/api-access.ts`, `lib/identity.ts`).
6
+ * through the app's own routes, so the app keeps the one gate it already has
7
+ * (`lib/api-access.ts`, `lib/identity.ts`, `lib/ceremony-access.ts`).
8
8
  *
9
- * - the token: `MIADI_API_TOKEN_WRITER`, sent as `Authorization: Bearer`
10
- * - the app: `--url`, else the first of MIADI_WEB_URL (or 127.0.0.1:3335),
11
- * MIADI_URL_BASE_INTERNAL, MIADI_URL_BASE whose /api/health answers
12
- * - `--env <file>` loads either or both from a file before anything is read
9
+ * Two tokens, each for what it is:
10
+ * - `MIADI_PERSON_TOKEN` is a person. It is the bearer of every read, so a
11
+ * ceremony or circle shows what that person's seat allows and nothing more.
12
+ * - `MIADI_API_TOKEN_WRITER` passes the write gate. It is the bearer of writes,
13
+ * with the person named beside it in `x-miadi-person-token`, the way the app
14
+ * expects an agent acting for someone (`lib/review-ceremony.ts`).
15
+ * Either alone works for what it can do. A token is only ever sent to the app
16
+ * chosen at start, and never over plain http to a host that is not this one.
13
17
  */
14
18
  import fs from "node:fs";
15
19
  import { readWebBases } from "@miadi/inquiry-weave";
16
20
  export const TOKEN_ENV = "MIADI_API_TOKEN_WRITER";
21
+ export const PERSON_TOKEN_ENV = "MIADI_PERSON_TOKEN";
22
+ export const PERSON_TOKEN_HEADER = "x-miadi-person-token";
23
+ /** What `--env` may set. Anything else in the file (PATH included) is left alone. */
24
+ export const ENV_FILE_KEYS = [
25
+ TOKEN_ENV,
26
+ PERSON_TOKEN_ENV,
27
+ "MIADI_CHRONICLE_ROOT",
28
+ "MIADI_WEB_URL",
29
+ "MIADI_URL_BASE_INTERNAL",
30
+ "MIADI_URL_BASE",
31
+ "MIADI_CHRONICLE_MW_URL",
32
+ ];
17
33
  /**
18
- * Load `KEY=value` lines into the environment: `export` prefixes, quotes and
19
- * `#` comments are understood, nothing is expanded. A key given by the file
20
- * wins over one already set, since the file was named on purpose.
34
+ * Load the allowed `KEY=value` lines of a file into the environment: `export`
35
+ * prefixes, quotes and `#` comments are understood, nothing is expanded. A key
36
+ * the file sets wins over one already set, since the file was named on purpose.
37
+ * Returns the keys it set.
21
38
  */
22
39
  export function loadEnvFile(path, env = process.env) {
40
+ const allowed = new Set(ENV_FILE_KEYS);
23
41
  const loaded = [];
24
42
  for (const raw of fs.readFileSync(path, "utf8").split(/\r?\n/)) {
25
43
  const line = raw.trim();
26
44
  if (!line || line.startsWith("#"))
27
45
  continue;
28
46
  const m = /^(?:export\s+)?([A-Za-z_][A-Za-z0-9_]*)\s*=\s*(.*)$/.exec(line);
29
- if (!m)
47
+ if (!m || !allowed.has(m[1]))
30
48
  continue;
31
49
  let value = m[2];
32
- const quoted = /^(["'])([\s\S]*)\1$/.exec(value);
50
+ const quoted = /^(["'])(.*?)\1(?:\s+#.*)?$/.exec(value);
33
51
  if (quoted)
34
52
  value = quoted[2];
35
53
  else
36
- value = value.replace(/\s+#.*$/, "");
54
+ value = value.replace(/\s+#.*$/, "").trim();
37
55
  env[m[1]] = value;
38
56
  loaded.push(m[1]);
39
57
  }
@@ -48,15 +66,48 @@ export class ApiError extends Error {
48
66
  this.code = code;
49
67
  }
50
68
  }
69
+ /** A token may travel to https, or to plain http on this machine only. */
70
+ export function mayCarryToken(base) {
71
+ try {
72
+ const url = new URL(base);
73
+ if (url.protocol === "https:")
74
+ return true;
75
+ return url.protocol === "http:" && ["127.0.0.1", "localhost", "[::1]"].includes(url.hostname);
76
+ }
77
+ catch {
78
+ return false;
79
+ }
80
+ }
51
81
  export class MiadiApi {
52
82
  base;
53
- token;
54
- constructor(base, token) {
83
+ tokens;
84
+ /** Set once the app has answered who is reading; false when it refused the token. */
85
+ accepted;
86
+ constructor(base, tokens = {}) {
55
87
  this.base = base;
56
- this.token = token;
88
+ this.tokens = tokens;
57
89
  }
90
+ /** A token is set (whether or not the app accepted it yet). */
58
91
  get signed() {
59
- return Boolean(this.token);
92
+ return Boolean(this.tokens.writer || this.tokens.person);
93
+ }
94
+ /** A person is named, so seats apply. */
95
+ get asPerson() {
96
+ return Boolean(this.tokens.person);
97
+ }
98
+ /** Writes are offered: a token is set and the app did not refuse it. */
99
+ get mayWrite() {
100
+ return this.signed && this.accepted !== false;
101
+ }
102
+ headers(write) {
103
+ const { writer, person } = this.tokens;
104
+ const bearer = write ? (writer ?? person) : (person ?? writer);
105
+ const headers = {};
106
+ if (bearer)
107
+ headers.authorization = `Bearer ${bearer}`;
108
+ if (write && writer && person)
109
+ headers[PERSON_TOKEN_HEADER] = person;
110
+ return headers;
60
111
  }
61
112
  async call(method, path, body) {
62
113
  const controller = new AbortController();
@@ -68,7 +119,7 @@ export class MiadiApi {
68
119
  headers: {
69
120
  accept: "application/json",
70
121
  ...(body === undefined ? {} : { "content-type": "application/json" }),
71
- ...(this.token ? { authorization: `Bearer ${this.token}` } : {}),
122
+ ...this.headers(method === "POST"),
72
123
  },
73
124
  body: body === undefined ? undefined : JSON.stringify(body),
74
125
  });
@@ -96,19 +147,40 @@ export class MiadiApi {
96
147
  post(path, body) {
97
148
  return this.call("POST", path, body);
98
149
  }
150
+ /** Who the app says is reading. Marks the client refused on 401 or 403. */
99
151
  async me() {
100
- if (!this.token)
152
+ if (!this.signed)
101
153
  return null;
102
- const me = await this.get("/api/identity/me");
103
- if (!me.person)
104
- return null;
105
- return {
106
- id: me.person.id,
107
- name: me.person.name,
108
- role: me.person.role,
109
- tier: me.api_tier,
110
- circles: (me.circles ?? []).map((circle) => ({ id: circle.id, name: circle.name })),
111
- };
154
+ try {
155
+ const me = await this.get("/api/identity/me");
156
+ this.accepted = Boolean(me.person);
157
+ if (!me.person)
158
+ return null;
159
+ return {
160
+ id: me.person.id,
161
+ name: me.person.name,
162
+ role: me.person.role,
163
+ tier: me.api_tier,
164
+ circles: (me.circles ?? []).map((circle) => ({ id: circle.id, name: circle.name })),
165
+ };
166
+ }
167
+ catch (error) {
168
+ if (error instanceof ApiError && (error.status === 401 || error.status === 403))
169
+ this.accepted = false;
170
+ throw error;
171
+ }
172
+ }
173
+ /** Would the app record a write from this client? The web room asks the attention door the same. */
174
+ async mayAnswer() {
175
+ if (!this.mayWrite)
176
+ return false;
177
+ try {
178
+ const body = await this.call("GET", "/api/chronicle/attention?capabilities=1");
179
+ return body?.capabilities?.answer === true;
180
+ }
181
+ catch {
182
+ return false;
183
+ }
112
184
  }
113
185
  }
114
186
  async function answers(base) {
@@ -125,42 +197,55 @@ async function answers(base) {
125
197
  clearTimeout(timer);
126
198
  }
127
199
  }
128
- /** The app this browser talks to, or null when none answers. */
200
+ /**
201
+ * The app this browser talks to. `--url` wins; otherwise the local app, then
202
+ * the tailnet one (`MIADI_URL_BASE_INTERNAL`). The public front is used only
203
+ * when named with `--url`, so a token never goes there by accident. Probes
204
+ * carry no token.
205
+ */
129
206
  export async function connectApi(url, env = process.env) {
130
- const token = env[TOKEN_ENV]?.trim() || undefined;
207
+ const tokens = {
208
+ writer: env[TOKEN_ENV]?.trim() || undefined,
209
+ person: env[PERSON_TOKEN_ENV]?.trim() || undefined,
210
+ };
211
+ const make = (base) => {
212
+ const clean = base.replace(/\/+$/, "");
213
+ if ((tokens.writer || tokens.person) && !mayCarryToken(clean)) {
214
+ return { api: new MiadiApi(clean), warning: `${clean} is plain http on another host: the token stays home and the app is read-only.` };
215
+ }
216
+ return { api: new MiadiApi(clean, tokens) };
217
+ };
131
218
  if (url)
132
- return new MiadiApi(url.replace(/\/+$/, ""), token);
219
+ return make(url);
133
220
  const bases = readWebBases(env);
134
- for (const base of [bases.local, bases.internal, bases.public]) {
221
+ for (const base of [bases.local, bases.internal]) {
135
222
  if (base && (await answers(base.replace(/\/+$/, ""))))
136
- return new MiadiApi(base.replace(/\/+$/, ""), token);
223
+ return make(base);
137
224
  }
138
- return null;
139
- }
140
- export async function listAttention(api, episode) {
141
- const result = await api.get(`/api/chronicle/attention?episode=${encodeURIComponent(episode)}&state=all`);
142
- return { items: result.items ?? [], canAnswer: Boolean(result.capabilities?.answer) };
225
+ return { api: null };
143
226
  }
227
+ // ---------------------------------------------------------------------------
228
+ // The routes the browser uses, typed as the app answers them (checked 2026-10-01)
229
+ // ---------------------------------------------------------------------------
144
230
  export function answerAttention(api, episode, id, answer) {
145
231
  return api.post("/api/chronicle/attention", { episode, id, answer, expectedState: "open" });
146
232
  }
147
233
  const trueKeys = (can) => can && typeof can === "object" ? Object.entries(can).filter(([, v]) => v === true).map(([k]) => k) : [];
148
234
  /**
149
- * What a ceremony shows a reader the app lets in: its kind, direction,
150
- * intention, episode, circle and whether it is closed. Never its turns: those
151
- * are people's words, read in the circle (jgwill/Miadi#680, D3).
235
+ * What a ceremony shows a seated reader: its kind, direction, intention,
236
+ * episode, circle and whether it is closed. Never its turns: those are
237
+ * people's words, read in the circle (jgwill/Miadi#680, D3).
152
238
  */
153
239
  export async function ceremonyCard(api, id) {
154
240
  const view = await api.get(`/api/ceremony/${encodeURIComponent(id)}`);
155
241
  const intentions = view.ceremony.intentions;
156
- const episode = view.episode?.episode_path;
157
242
  return {
158
243
  kind: "ceremony",
159
244
  id: view.ceremony.id,
160
245
  type: view.ceremony.type,
161
246
  direction: view.ceremony.direction,
162
247
  intentions: (Array.isArray(intentions) ? intentions : intentions ? [intentions] : []).map((line) => line.replace(/\s+/g, " ").trim()),
163
- episode,
248
+ episode: view.episode?.episode_path,
164
249
  circle: view.circle?.name,
165
250
  closed: Boolean(view.closed),
166
251
  can: trueKeys(view.can),
package/dist/api.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"api.js","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"api.js","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,50 @@
1
+ /**
2
+ * Chronicle ATTENTION in the terminal, as the web room has it (jgwill/Miadi#706).
3
+ *
4
+ * The room shows attention twice: a chronicle-wide board of every open item,
5
+ * newest-asked first, filtered by the same search box as the episodes
6
+ * (`app/chronicle/components/ChronicleAttention.tsx`), and each episode's own
7
+ * panel with Open and History and the cited context of each question
8
+ * (`EpisodeAttention.tsx`). Both are hosts of `@miadi/attention-core`, whose
9
+ * plain functions decide which list shows, what each heading says and whether
10
+ * an answer may be recorded. This module is the terminal's host of the same
11
+ * core: it reads through `@miadi/inquiry-weave` exactly as the app does, and
12
+ * answers through the app's `POST /api/chronicle/attention`.
13
+ */
14
+ import { type AttentionPanelLabels, type AttentionView } from "@miadi/attention-core";
15
+ import { type ChronicleAttentionItem } from "@miadi/inquiry-weave";
16
+ export type { AttentionView };
17
+ export type BoardItem = ChronicleAttentionItem;
18
+ /** The board's words, as the web room's board says them. */
19
+ export declare const BOARD_LABELS: Required<AttentionPanelLabels>;
20
+ /** One episode's panel keeps the core's own words. */
21
+ export declare const ROOM_LABELS: Required<AttentionPanelLabels>;
22
+ export declare function readOnlyLabel(tokenEnv: string): string;
23
+ /** Every open item across the chronicle, newest-asked first: what the board lists. */
24
+ export declare function loadBoard(root: string): Promise<BoardItem[]>;
25
+ export interface EpisodePanel {
26
+ episode: string;
27
+ items: BoardItem[];
28
+ parseError?: string;
29
+ }
30
+ /** One episode's items with the cited context of each, as the room reads them. */
31
+ export declare function loadEpisodePanel(root: string, episode: string): Promise<EpisodePanel>;
32
+ /** The board answers the episode search box: question, episode and what it unlocks. */
33
+ export declare function filterBoard(items: readonly BoardItem[], query: string): BoardItem[];
34
+ /** The list a panel shows, and its heading, decided by the core. */
35
+ export declare function panelView(items: readonly BoardItem[], selected: AttentionView, labels: Required<AttentionPanelLabels>, parseError?: string): {
36
+ view: AttentionView;
37
+ shown: BoardItem[];
38
+ heading: string;
39
+ meta: string;
40
+ };
41
+ /** Check an answer the way every host checks it, before anything is sent. */
42
+ export declare function checkAnswer(draft: string, maxLength?: number): import("@miadi/attention-core").AnswerValidation;
43
+ /** What the room says once an answer is recorded: the wheel is reported, never assumed. */
44
+ export declare function answeredMessage(result: {
45
+ synchronized?: boolean;
46
+ } | undefined): {
47
+ tone: "ok" | "warn";
48
+ message: string;
49
+ };
50
+ //# sourceMappingURL=attention.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"attention.d.ts","sourceRoot":"","sources":["../src/attention.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAQL,KAAK,oBAAoB,EACzB,KAAK,aAAa,EACnB,MAAM,uBAAuB,CAAA;AAC9B,OAAO,EAGL,KAAK,sBAAsB,EAC5B,MAAM,sBAAsB,CAAA;AAE7B,YAAY,EAAE,aAAa,EAAE,CAAA;AAC7B,MAAM,MAAM,SAAS,GAAG,sBAAsB,CAAA;AAE9C,4DAA4D;AAC5D,eAAO,MAAM,YAAY,gCAKvB,CAAA;AAEF,sDAAsD;AACtD,eAAO,MAAM,WAAW,gCAAkB,CAAA;AAE1C,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAEtD;AAED,sFAAsF;AACtF,wBAAsB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC,CAGlE;AAED,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,MAAM,CAAA;IACf,KAAK,EAAE,SAAS,EAAE,CAAA;IAClB,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB;AAED,kFAAkF;AAClF,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CAG3F;AAED,uFAAuF;AACvF,wBAAgB,WAAW,CAAC,KAAK,EAAE,SAAS,SAAS,EAAE,EAAE,KAAK,EAAE,MAAM,GAAG,SAAS,EAAE,CAOnF;AAED,oEAAoE;AACpE,wBAAgB,SAAS,CACvB,KAAK,EAAE,SAAS,SAAS,EAAE,EAC3B,QAAQ,EAAE,aAAa,EACvB,MAAM,EAAE,QAAQ,CAAC,oBAAoB,CAAC,EACtC,UAAU,CAAC,EAAE,MAAM,GAClB;IAAE,IAAI,EAAE,aAAa,CAAC;IAAC,KAAK,EAAE,SAAS,EAAE,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAS5E;AAED,6EAA6E;AAC7E,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,SAA4B,oDAE/E;AAED,2FAA2F;AAC3F,wBAAgB,eAAe,CAAC,MAAM,EAAE;IAAE,YAAY,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,SAAS,GAAG;IAAE,IAAI,EAAE,IAAI,GAAG,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAIxH"}
@@ -0,0 +1,69 @@
1
+ /**
2
+ * Chronicle ATTENTION in the terminal, as the web room has it (jgwill/Miadi#706).
3
+ *
4
+ * The room shows attention twice: a chronicle-wide board of every open item,
5
+ * newest-asked first, filtered by the same search box as the episodes
6
+ * (`app/chronicle/components/ChronicleAttention.tsx`), and each episode's own
7
+ * panel with Open and History and the cited context of each question
8
+ * (`EpisodeAttention.tsx`). Both are hosts of `@miadi/attention-core`, whose
9
+ * plain functions decide which list shows, what each heading says and whether
10
+ * an answer may be recorded. This module is the terminal's host of the same
11
+ * core: it reads through `@miadi/inquiry-weave` exactly as the app does, and
12
+ * answers through the app's `POST /api/chronicle/attention`.
13
+ */
14
+ import { DEFAULT_ANSWER_MAX_LENGTH, headingMeta, headingText, partitionItems, resolveLabels, resolveView, validateAnswer, } from "@miadi/attention-core";
15
+ import { listChronicleAttention, readEpisodeAttention, } from "@miadi/inquiry-weave";
16
+ /** The board's words, as the web room's board says them. */
17
+ export const BOARD_LABELS = resolveLabels({
18
+ title: "Needs your attention",
19
+ completeTitle: "Nothing waits on you",
20
+ openSuffix: "newest first — answer one here, or open its room",
21
+ completeSuffix: "decisions recorded across the chronicle",
22
+ });
23
+ /** One episode's panel keeps the core's own words. */
24
+ export const ROOM_LABELS = resolveLabels();
25
+ export function readOnlyLabel(tokenEnv) {
26
+ return `View only — answering needs the Miadi app and ${tokenEnv} or MIADI_PERSON_TOKEN (or --env <file>).`;
27
+ }
28
+ /** Every open item across the chronicle, newest-asked first: what the board lists. */
29
+ export async function loadBoard(root) {
30
+ const items = await listChronicleAttention(root, { state: "open" });
31
+ return items.filter((item) => item.state === "open");
32
+ }
33
+ /** One episode's items with the cited context of each, as the room reads them. */
34
+ export async function loadEpisodePanel(root, episode) {
35
+ const attention = await readEpisodeAttention(root, episode, { includeContext: true });
36
+ return { episode, items: attention?.items ?? [], parseError: attention?.parseError };
37
+ }
38
+ /** The board answers the episode search box: question, episode and what it unlocks. */
39
+ export function filterBoard(items, query) {
40
+ const words = query.toLowerCase().split(/\s+/).filter(Boolean);
41
+ if (words.length === 0)
42
+ return [...items];
43
+ return items.filter((item) => {
44
+ const haystack = [item.question, item.episode, item.unlocks, item.id].filter(Boolean).join(" ").toLowerCase();
45
+ return words.every((word) => haystack.includes(word));
46
+ });
47
+ }
48
+ /** The list a panel shows, and its heading, decided by the core. */
49
+ export function panelView(items, selected, labels, parseError) {
50
+ const { open, answered } = partitionItems(items);
51
+ const view = resolveView(selected, open.length, answered.length);
52
+ return {
53
+ view,
54
+ shown: view === "history" ? answered : view === "open" ? open : [],
55
+ heading: headingText(open.length > 0, labels),
56
+ meta: headingMeta({ parseError, openCount: open.length, answeredCount: answered.length, labels }),
57
+ };
58
+ }
59
+ /** Check an answer the way every host checks it, before anything is sent. */
60
+ export function checkAnswer(draft, maxLength = DEFAULT_ANSWER_MAX_LENGTH) {
61
+ return validateAnswer(draft, ROOM_LABELS, maxLength);
62
+ }
63
+ /** What the room says once an answer is recorded: the wheel is reported, never assumed. */
64
+ export function answeredMessage(result) {
65
+ return result?.synchronized === true
66
+ ? { tone: "ok", message: "Answer recorded in the episode and verified on the wheel." }
67
+ : { tone: "warn", message: "Answer recorded in the episode; the wheel projection is pending." };
68
+ }
69
+ //# sourceMappingURL=attention.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"attention.js","sourceRoot":"","sources":["../src/attention.ts"],"names":[],"mappings":"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"}
package/dist/bin.d.ts CHANGED
@@ -7,7 +7,8 @@
7
7
  * miadi-chronicle 352 open on one episode (number, ep352 or folder name)
8
8
  * miadi-chronicle --search "talking circle" open in full-text mode
9
9
  * miadi-chronicle --filter review open with a title filter
10
- * miadi-chronicle --env ~/.env.miadi load MIADI_API_TOKEN_WRITER (and anything else) first
10
+ * miadi-chronicle --env ~/.env.miadi load the tokens, the root and the app's address first
11
+ * miadi-chronicle --attention open on the chronicle's attention board
11
12
  * miadi-chronicle --url https://miadi.tail3b11eb.ts.net act through this app
12
13
  *
13
14
  * Exit codes: 0 ok, 2 usage (no root, no terminal).
package/dist/bin.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"bin.d.ts","sourceRoot":"","sources":["../src/bin.tsx"],"names":[],"mappings":";AACA;;;;;;;;;;;;GAYG"}
1
+ {"version":3,"file":"bin.d.ts","sourceRoot":"","sources":["../src/bin.tsx"],"names":[],"mappings":";AACA;;;;;;;;;;;;;GAaG"}