@cr8rcho/alkahest 0.1.2 → 0.1.3

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 CHANGED
@@ -93,6 +93,7 @@ alkahest hook install # run scan automatically on commit/merge (diff-driven ref
93
93
  alkahest mcp # run the MCP server (agents query the product map; no key)
94
94
  alkahest login # save your publish token (Account → Create token on alkahest.app)
95
95
  alkahest publish # upload the map to the hosted viewer → shareable link
96
+ alkahest comments pull # pull comments left on the published map → .alkahest/comments.json
96
97
  alkahest update # update to the latest GitHub release (--check to only check)
97
98
  ```
98
99
 
package/dist/cli.js CHANGED
@@ -7,6 +7,7 @@ import { mcp } from "./commands/mcp.js";
7
7
  import { hook } from "./commands/hook.js";
8
8
  import { publish } from "./commands/publish.js";
9
9
  import { login } from "./commands/login.js";
10
+ import { commentsPull } from "./commands/comments.js";
10
11
  import { update } from "./commands/update.js";
11
12
  import { maybeNotifyUpdate } from "./core/version.js";
12
13
  const require = createRequire(import.meta.url);
@@ -47,6 +48,21 @@ program
47
48
  await publish(path, opts);
48
49
  await maybeNotifyUpdate();
49
50
  });
51
+ const comments = program
52
+ .command("comments")
53
+ .description("work with comments left on this project's published map (hosted viewer)");
54
+ comments
55
+ .command("pull")
56
+ .description("pull map comments into .alkahest/comments.json for use during development")
57
+ .argument("[path]", "project path", ".")
58
+ .option("--open", "only unresolved comments", false)
59
+ .option("--slug <slug>", "project slug (defaults to the saved slug for this path)")
60
+ .option("--api <url>", "API base URL (or env ALKAHEST_API_URL)")
61
+ .option("--to-issues", "open each unresolved comment as a GitHub issue (requires gh)", false)
62
+ .action(async (path, opts) => {
63
+ await commentsPull(path, opts);
64
+ await maybeNotifyUpdate();
65
+ });
50
66
  program
51
67
  .command("mcp")
52
68
  .description("run the MCP server over stdio (agents query the product map; no key)")
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ export interface CommentsPullOptions {
2
+ api?: string;
3
+ slug?: string;
4
+ open?: boolean;
5
+ toIssues?: boolean;
6
+ }
7
+ export declare function commentsPull(path: string, options: CommentsPullOptions): Promise<void>;
@@ -0,0 +1,100 @@
1
+ import { execFileSync } from "node:child_process";
2
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
3
+ import { join, resolve } from "node:path";
4
+ import { OUTPUT_DIR } from "../core/emit.js";
5
+ import { pullComments } from "../core/comments.js";
6
+ const firstLine = (s, max = 72) => {
7
+ const line = String(s).split("\n")[0].trim();
8
+ return line.length > max ? line.slice(0, max - 1) + "…" : line;
9
+ };
10
+ export async function commentsPull(path, options) {
11
+ const res = await pullComments(path, options);
12
+ if (!res.ok) {
13
+ if (res.code === "no_slug") {
14
+ console.error(`[alkahest] ${res.message}`);
15
+ }
16
+ else if (res.code === "invalid_token") {
17
+ console.error("[alkahest] ✗ Token invalid or revoked. Run 'alkahest login' again.");
18
+ }
19
+ else if (res.code === "not_found") {
20
+ console.error(`[alkahest] ✗ ${res.message}`);
21
+ }
22
+ else {
23
+ console.error(`[alkahest] comments pull failed: ${res.message}`);
24
+ }
25
+ process.exitCode = 1;
26
+ return;
27
+ }
28
+ const projectRoot = resolve(path);
29
+ const comments = res.comments ?? [];
30
+ const roots = comments.filter((c) => !c.parent_id);
31
+ const open = roots.filter((c) => !c.resolved);
32
+ // Write next to the map so the comments travel with the project checkout.
33
+ const dir = join(projectRoot, OUTPUT_DIR);
34
+ mkdirSync(dir, { recursive: true });
35
+ const outFile = join(dir, "comments.json");
36
+ writeFileSync(outFile, JSON.stringify({ slug: res.slug, name: res.name ?? null, pulledAt: new Date().toISOString(), open: Boolean(options.open), comments }, null, 2) + "\n");
37
+ console.log(`[alkahest] pulled ${comments.length} comment${comments.length === 1 ? "" : "s"} on ${res.slug}` +
38
+ ` (${open.length} open) → ${OUTPUT_DIR}/comments.json`);
39
+ // A compact per-node digest so you can see where discussion is happening.
40
+ const byNode = new Map();
41
+ for (const c of roots) {
42
+ const k = c.node_key;
43
+ const e = byNode.get(k) ?? { label: c.anchor_label || k, open: 0, total: 0 };
44
+ e.total++;
45
+ if (!c.resolved)
46
+ e.open++;
47
+ byNode.set(k, e);
48
+ }
49
+ for (const [k, e] of byNode)
50
+ console.log(` ${k} ${e.label} — ${e.open} open / ${e.total}`);
51
+ if (options.toIssues)
52
+ createIssues(projectRoot, res.slug, comments);
53
+ }
54
+ /**
55
+ * Open each unresolved root comment as a GitHub issue via the `gh` CLI (run in the
56
+ * project's git repo). A local cache (.alkahest/comments-issues.json) maps comment id →
57
+ * issue URL so re-running doesn't create duplicates.
58
+ */
59
+ function createIssues(projectRoot, slug, comments) {
60
+ const cacheFile = join(projectRoot, OUTPUT_DIR, "comments-issues.json");
61
+ let cache = {};
62
+ if (existsSync(cacheFile)) {
63
+ try {
64
+ cache = JSON.parse(readFileSync(cacheFile, "utf8"));
65
+ }
66
+ catch { /* ignore */ }
67
+ }
68
+ const roots = comments.filter((c) => !c.parent_id && !c.resolved && !cache[c.id]);
69
+ if (!roots.length) {
70
+ console.log("[alkahest] --to-issues: no new open comments to file.");
71
+ return;
72
+ }
73
+ for (const c of roots) {
74
+ const replies = comments.filter((r) => r.parent_id === c.id);
75
+ const where = c.anchor_label ? `\`${c.node_key}\` (${c.anchor_label})` : `\`${c.node_key}\``;
76
+ const body = `From an Alkahest map comment on **${slug}**.\n\n` +
77
+ `- Node: ${where}\n- Author: ${c.author_name || c.author_id}\n- Posted: ${c.created_at}\n\n` +
78
+ `${c.body}\n` +
79
+ (replies.length
80
+ ? `\n---\n` + replies.map((r) => `**${r.author_name || r.author_id}**: ${r.body}`).join("\n\n")
81
+ : "");
82
+ const title = `[map] ${c.anchor_label || c.node_key}: ${firstLine(c.body)}`;
83
+ try {
84
+ const url = execFileSync("gh", ["issue", "create", "--title", title, "--body", body], {
85
+ cwd: projectRoot,
86
+ encoding: "utf8",
87
+ }).trim();
88
+ cache[c.id] = url;
89
+ console.log(` + ${url}`);
90
+ }
91
+ catch (err) {
92
+ const msg = err instanceof Error ? err.message : String(err);
93
+ console.error(`[alkahest] --to-issues: gh failed (${msg.split("\n")[0]}). Is the GitHub CLI installed and authenticated?`);
94
+ process.exitCode = 1;
95
+ break;
96
+ }
97
+ }
98
+ writeFileSync(cacheFile, JSON.stringify(cache, null, 2) + "\n");
99
+ }
100
+ //# sourceMappingURL=comments.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"comments.js","sourceRoot":"","sources":["../../src/commands/comments.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Shared logic for `alkahest comments pull`. Reads the comments left on this project's
3
+ * PUBLISHED map (hosted viewer) via the `comments-pull` edge function, so they can be
4
+ * used during development. Comments live only in the cloud — there is no local
5
+ * authoring; this is the read side of that loop (see alkahest-cloud ADR-001).
6
+ *
7
+ * Like publish.ts, this returns a structured result and never writes to stdout/stderr.
8
+ */
9
+ export interface PullParams {
10
+ /** API base URL (else env ALKAHEST_API_URL / saved creds). */
11
+ api?: string;
12
+ /** Project slug (else the saved slug for this project path). */
13
+ slug?: string;
14
+ /** Only unresolved comments. */
15
+ open?: boolean;
16
+ /** Publish token (else env ALKAHEST_TOKEN / saved creds). */
17
+ token?: string;
18
+ }
19
+ export interface PulledComment {
20
+ id: string;
21
+ map_version_id: string | null;
22
+ anchor_kind: string;
23
+ node_key: string;
24
+ anchor_label: string | null;
25
+ parent_id: string | null;
26
+ author_id: string;
27
+ author_name: string | null;
28
+ body: string;
29
+ resolved: boolean;
30
+ created_at: string;
31
+ updated_at: string;
32
+ }
33
+ export interface PullResult {
34
+ ok: boolean;
35
+ slug?: string;
36
+ name?: string | null;
37
+ comments?: PulledComment[];
38
+ /** no_api | no_token | no_slug | not_found | invalid_token | network | <server error>. */
39
+ code?: string;
40
+ message?: string;
41
+ }
42
+ export declare function pullComments(path: string, params?: PullParams): Promise<PullResult>;
@@ -0,0 +1,67 @@
1
+ import { resolve } from "node:path";
2
+ import { loadCredentials, resolveApiUrl, resolveToken } from "./credentials.js";
3
+ async function getJson(url, token) {
4
+ let res;
5
+ try {
6
+ res = await fetch(url, { headers: { authorization: `Bearer ${token}` } });
7
+ }
8
+ catch (err) {
9
+ const msg = err instanceof Error ? err.message : String(err);
10
+ return { ok: false, status: "network", body: { error: `could not reach ${url} (${msg})` } };
11
+ }
12
+ let parsed = null;
13
+ try {
14
+ parsed = await res.json();
15
+ }
16
+ catch {
17
+ /* non-JSON error body */
18
+ }
19
+ return { ok: res.ok, status: String(res.status), body: parsed };
20
+ }
21
+ export async function pullComments(path, params = {}) {
22
+ const projectRoot = resolve(path);
23
+ const creds = loadCredentials();
24
+ const apiUrl = resolveApiUrl(params.api, creds);
25
+ if (!apiUrl) {
26
+ return {
27
+ ok: false,
28
+ code: "no_api",
29
+ message: "Missing API URL. Set ALKAHEST_API_URL (or pass --api / run 'alkahest login --api <url>').",
30
+ };
31
+ }
32
+ const token = resolveToken(params.token, creds);
33
+ if (!token) {
34
+ return {
35
+ ok: false,
36
+ code: "no_token",
37
+ message: "Not authenticated. Set ALKAHEST_TOKEN (or run 'alkahest login --token alk_…').",
38
+ };
39
+ }
40
+ const slug = params.slug || creds.projects?.[projectRoot]?.slug;
41
+ if (!slug) {
42
+ return {
43
+ ok: false,
44
+ code: "no_slug",
45
+ message: "No published map for this project yet — run 'alkahest publish', or pass --slug <slug>.",
46
+ };
47
+ }
48
+ const qs = new URLSearchParams({ slug });
49
+ if (params.open)
50
+ qs.set("open", "1");
51
+ const res = await getJson(`${apiUrl}/comments-pull?${qs.toString()}`, token);
52
+ if (!res.ok) {
53
+ return {
54
+ ok: false,
55
+ code: res.body?.error ?? "http",
56
+ message: res.body?.message ?? res.body?.error ?? `pull failed (${res.status})`,
57
+ };
58
+ }
59
+ const proj = (res.body?.projects ?? []).find((p) => p.slug === slug) ?? res.body?.projects?.[0];
60
+ return {
61
+ ok: true,
62
+ slug,
63
+ name: proj?.name ?? null,
64
+ comments: (proj?.comments ?? []),
65
+ };
66
+ }
67
+ //# sourceMappingURL=comments.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"comments.js","sourceRoot":"","sources":["../../src/core/comments.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cr8rcho/alkahest",
3
- "version": "0.1.2",
3
+ "version": "0.1.3",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },