intentdocs 0.8.0 → 0.10.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. package/README.md +7 -1
  2. package/bin/intentdocs.js +2 -0
  3. package/dist/chunk-34JCN66H.js +170 -0
  4. package/dist/chunk-6X4BORMW.js +317 -0
  5. package/dist/{chunk-6FGYJ3W2.js → chunk-F52HPVNQ.js} +43 -4
  6. package/dist/{chunk-ICOMMHKG.js → chunk-JX2RLGOM.js} +13 -2
  7. package/dist/chunk-KPQ42YE6.js +43 -0
  8. package/dist/chunk-LQTPZL2Y.js +15 -0
  9. package/dist/{chunk-4OWPN2RE.js → chunk-NHNBCNND.js} +28 -47
  10. package/dist/{chunk-IKF3ZLHK.js → chunk-PUGYRSMK.js} +72 -108
  11. package/dist/{chunk-ITQUQYWB.js → chunk-UQDMUKLP.js} +2 -2
  12. package/dist/chunk-UYTVTYNB.js +11 -0
  13. package/dist/{chunk-WPVDURTJ.js → chunk-WRRUCCVZ.js} +27 -3
  14. package/dist/chunk-XZE2XP6O.js +105 -0
  15. package/dist/ci-XCOXFTLB.js +11 -0
  16. package/dist/{complexity-NSSYVT54.js → complexity-X3IJKNNV.js} +12 -7
  17. package/dist/{import-prd-CKV3R67G.js → import-prd-IJTM6FZE.js} +13 -11
  18. package/dist/index.js +435 -194
  19. package/dist/{keys-EDWET3WG.js → keys-UVXCCWCS.js} +8 -7
  20. package/dist/log-XIH4BGFL.js +206 -0
  21. package/dist/{map-extract-I3AACTGL.js → map-extract-V6D27I3H.js} +3 -2
  22. package/dist/{map-import-IYUMRASO.js → map-import-LORTI4K4.js} +12 -10
  23. package/dist/{map-schema-JVL3O2TJ.js → map-schema-5BEIJM2J.js} +1 -1
  24. package/dist/projects-AYAYVFKL.js +37 -0
  25. package/dist/{prompt-WAWCRGHN.js → prompt-GOAFIKBZ.js} +3 -1
  26. package/dist/{research-6SXJ37TI.js → research-CO3W7PLC.js} +12 -10
  27. package/dist/scope-ZZLKQEF5.js +11 -0
  28. package/dist/setup-WSYIG2CR.js +14 -0
  29. package/package.json +4 -2
  30. package/dist/chunk-6XKB6RTU.js +0 -123
  31. package/dist/chunk-PCNDP5SX.js +0 -34
  32. package/dist/log-TT2UCJP7.js +0 -94
  33. package/dist/scope-OGKQ472D.js +0 -10
  34. package/dist/setup-SOI2HQAL.js +0 -11
@@ -0,0 +1,105 @@
1
+ import {
2
+ API_BASE,
3
+ canonicalApiBase
4
+ } from "./chunk-UYTVTYNB.js";
5
+
6
+ // src/lib/auth.ts
7
+ import { readFileSync, writeFileSync, mkdirSync, existsSync, unlinkSync } from "fs";
8
+ import { join } from "path";
9
+ import { homedir } from "os";
10
+ var AUTH_DIR = join(homedir(), ".intent");
11
+ var AUTH_FILE = join(AUTH_DIR, "auth.json");
12
+ function bindingLabel(binding) {
13
+ if (!binding) return "personal";
14
+ const name = binding.workspaceName ?? "a workspace";
15
+ if (binding.approvalStatus === "pending") return `bound to ${name} (awaiting an admin's approval)`;
16
+ if (binding.approvalStatus === "revoked") return `bound to ${name} (access revoked)`;
17
+ return `bound to ${name}`;
18
+ }
19
+ function getAuth() {
20
+ try {
21
+ const raw = readFileSync(AUTH_FILE, "utf-8");
22
+ const data = JSON.parse(raw);
23
+ return { ...data, apiBase: canonicalApiBase(data.apiBase ?? API_BASE) };
24
+ } catch {
25
+ return null;
26
+ }
27
+ }
28
+ function saveAuth(data) {
29
+ if (!existsSync(AUTH_DIR)) mkdirSync(AUTH_DIR, { recursive: true });
30
+ writeFileSync(AUTH_FILE, JSON.stringify(data, null, 2) + "\n", { mode: 384 });
31
+ }
32
+ function clearAuth() {
33
+ try {
34
+ if (existsSync(AUTH_FILE)) unlinkSync(AUTH_FILE);
35
+ } catch {
36
+ }
37
+ }
38
+ async function validateAuth() {
39
+ const auth = getAuth();
40
+ if (!auth) return { valid: false, reason: "no_file" };
41
+ try {
42
+ const res = await fetch(`${auth.apiBase}/api/cli/auth/verify`, {
43
+ headers: { Authorization: `Bearer ${auth.token}` }
44
+ });
45
+ if (res.ok) {
46
+ const data = await res.json();
47
+ if (data.valid) {
48
+ if (data.binding !== void 0 && JSON.stringify(data.binding) !== JSON.stringify(auth.binding ?? null)) {
49
+ auth.binding = data.binding;
50
+ saveAuth(auth);
51
+ }
52
+ return { valid: true, userId: data.userId ?? auth.userId ?? "unknown", auth };
53
+ }
54
+ }
55
+ const body = await res.json().catch(() => ({}));
56
+ const reason = body.reason;
57
+ if (reason === "revoked") return { valid: false, reason: "revoked" };
58
+ if (reason === "not_found") return { valid: false, reason: "not_found" };
59
+ return { valid: false, reason: "not_found" };
60
+ } catch {
61
+ return { valid: false, reason: "network_error" };
62
+ }
63
+ }
64
+ async function requireValidAuth() {
65
+ const result = await validateAuth();
66
+ if (result.valid) return result.auth;
67
+ switch (result.reason) {
68
+ case "no_file":
69
+ console.error("Not logged in \u2014 no auth credentials found. Run: npx intentdocs login");
70
+ break;
71
+ case "revoked":
72
+ console.error("Your auth token has been revoked. Run: npx intentdocs login");
73
+ clearAuth();
74
+ break;
75
+ case "not_found":
76
+ console.error("Your auth token is no longer valid (it may have been deleted). Run: npx intentdocs login");
77
+ clearAuth();
78
+ break;
79
+ case "network_error":
80
+ console.error("Could not reach intentdocs.com to verify your auth token. Check your internet connection and try again.");
81
+ break;
82
+ }
83
+ process.exit(1);
84
+ }
85
+ async function authenticatedFetch(path, init) {
86
+ const auth = await requireValidAuth();
87
+ return fetch(`${auth.apiBase}${path}`, {
88
+ ...init,
89
+ headers: {
90
+ "Content-Type": "application/json",
91
+ Authorization: `Bearer ${auth.token}`,
92
+ ...init?.headers ?? {}
93
+ }
94
+ });
95
+ }
96
+
97
+ export {
98
+ bindingLabel,
99
+ getAuth,
100
+ saveAuth,
101
+ clearAuth,
102
+ validateAuth,
103
+ requireValidAuth,
104
+ authenticatedFetch
105
+ };
@@ -0,0 +1,11 @@
1
+ import {
2
+ ci
3
+ } from "./chunk-6X4BORMW.js";
4
+ import "./chunk-KPQ42YE6.js";
5
+ import "./chunk-JX2RLGOM.js";
6
+ import "./chunk-WRRUCCVZ.js";
7
+ import "./chunk-XZE2XP6O.js";
8
+ import "./chunk-UYTVTYNB.js";
9
+ export {
10
+ ci
11
+ };
@@ -1,15 +1,20 @@
1
1
  import {
2
2
  isPlanGated,
3
3
  printUpgradeMessage
4
- } from "./chunk-ITQUQYWB.js";
4
+ } from "./chunk-UQDMUKLP.js";
5
+ import {
6
+ matchesStoryRef
7
+ } from "./chunk-LQTPZL2Y.js";
5
8
  import {
6
9
  apiUrl,
7
- listStories
8
- } from "./chunk-6XKB6RTU.js";
10
+ listStories,
11
+ syncHeaders
12
+ } from "./chunk-34JCN66H.js";
9
13
  import {
10
14
  requireConfig
11
- } from "./chunk-ICOMMHKG.js";
12
- import "./chunk-PCNDP5SX.js";
15
+ } from "./chunk-JX2RLGOM.js";
16
+ import "./chunk-XZE2XP6O.js";
17
+ import "./chunk-UYTVTYNB.js";
13
18
 
14
19
  // src/commands/complexity.ts
15
20
  import ora from "ora";
@@ -20,7 +25,7 @@ async function complexity(storyId) {
20
25
  const data = await listStories(config);
21
26
  let storyIds;
22
27
  if (storyId) {
23
- const match = data.stories.find((s) => s.id.startsWith(storyId));
28
+ const match = data.stories.find((s) => matchesStoryRef(s, storyId));
24
29
  if (!match) {
25
30
  spinner.fail(` No story found matching "${storyId}"`);
26
31
  return;
@@ -35,7 +40,7 @@ async function complexity(storyId) {
35
40
  }
36
41
  const res = await fetch(apiUrl(config, "/complexity"), {
37
42
  method: "POST",
38
- headers: { "Content-Type": "application/json" },
43
+ headers: syncHeaders({ "Content-Type": "application/json" }),
39
44
  body: JSON.stringify({ story_ids: storyIds })
40
45
  });
41
46
  if (!res.ok) {
@@ -1,18 +1,20 @@
1
- import {
2
- closePrompt,
3
- confirm
4
- } from "./chunk-WPVDURTJ.js";
5
1
  import {
6
2
  isPlanGated,
7
3
  printUpgradeMessage
8
- } from "./chunk-ITQUQYWB.js";
4
+ } from "./chunk-UQDMUKLP.js";
9
5
  import {
10
- apiUrl
11
- } from "./chunk-6XKB6RTU.js";
6
+ apiUrl,
7
+ syncHeaders
8
+ } from "./chunk-34JCN66H.js";
12
9
  import {
13
10
  requireConfig
14
- } from "./chunk-ICOMMHKG.js";
15
- import "./chunk-PCNDP5SX.js";
11
+ } from "./chunk-JX2RLGOM.js";
12
+ import {
13
+ closePrompt,
14
+ confirm
15
+ } from "./chunk-WRRUCCVZ.js";
16
+ import "./chunk-XZE2XP6O.js";
17
+ import "./chunk-UYTVTYNB.js";
16
18
 
17
19
  // src/commands/import-prd.ts
18
20
  import { readFileSync, existsSync } from "fs";
@@ -48,7 +50,7 @@ async function importPrd(filePath) {
48
50
  try {
49
51
  const res = await fetch(apiUrl(config, "/import"), {
50
52
  method: "POST",
51
- headers: { "Content-Type": "application/json" },
53
+ headers: syncHeaders({ "Content-Type": "application/json" }),
52
54
  body: JSON.stringify({ prd: prdText, format })
53
55
  });
54
56
  if (!res.ok) {
@@ -103,7 +105,7 @@ async function importPrd(filePath) {
103
105
  }));
104
106
  const createRes = await fetch(apiUrl(config, "/map-import"), {
105
107
  method: "POST",
106
- headers: { "Content-Type": "application/json" },
108
+ headers: syncHeaders({ "Content-Type": "application/json" }),
107
109
  body: JSON.stringify({
108
110
  schema_version: "1.0",
109
111
  source: "prd-import",