@parkercto/cli 0.1.0 → 0.2.2

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 (95) hide show
  1. package/dist/src/bin/preuninstall.d.ts +10 -0
  2. package/dist/src/bin/preuninstall.d.ts.map +1 -0
  3. package/dist/src/bin/preuninstall.js +51 -0
  4. package/dist/src/bin/preuninstall.js.map +1 -0
  5. package/dist/src/cli.js +7 -3
  6. package/dist/src/cli.js.map +1 -1
  7. package/dist/src/client/api-client.d.ts +22 -0
  8. package/dist/src/client/api-client.d.ts.map +1 -1
  9. package/dist/src/client/api-client.js +50 -10
  10. package/dist/src/client/api-client.js.map +1 -1
  11. package/dist/src/client/auth.d.ts.map +1 -1
  12. package/dist/src/client/auth.js +14 -5
  13. package/dist/src/client/auth.js.map +1 -1
  14. package/dist/src/commands/auth.js +1 -1
  15. package/dist/src/commands/auth.js.map +1 -1
  16. package/dist/src/commands/connect.d.ts +2 -2
  17. package/dist/src/commands/connect.d.ts.map +1 -1
  18. package/dist/src/commands/connect.js +93 -8
  19. package/dist/src/commands/connect.js.map +1 -1
  20. package/dist/src/commands/disable.d.ts +3 -0
  21. package/dist/src/commands/disable.d.ts.map +1 -0
  22. package/dist/src/commands/disable.js +8 -0
  23. package/dist/src/commands/disable.js.map +1 -0
  24. package/dist/src/commands/enable.d.ts +3 -0
  25. package/dist/src/commands/enable.d.ts.map +1 -0
  26. package/dist/src/commands/enable.js +207 -0
  27. package/dist/src/commands/enable.js.map +1 -0
  28. package/dist/src/commands/hook.d.ts +3 -0
  29. package/dist/src/commands/hook.d.ts.map +1 -0
  30. package/dist/src/commands/hook.js +214 -0
  31. package/dist/src/commands/hook.js.map +1 -0
  32. package/dist/src/commands/join.d.ts +2 -2
  33. package/dist/src/commands/join.d.ts.map +1 -1
  34. package/dist/src/commands/join.js +17 -33
  35. package/dist/src/commands/join.js.map +1 -1
  36. package/dist/src/commands/update.js +1 -1
  37. package/dist/src/commands/update.js.map +1 -1
  38. package/dist/src/constants.d.ts +14 -1
  39. package/dist/src/constants.d.ts.map +1 -1
  40. package/dist/src/constants.js +14 -1
  41. package/dist/src/constants.js.map +1 -1
  42. package/dist/src/lib/auto-update.d.ts +4 -0
  43. package/dist/src/lib/auto-update.d.ts.map +1 -1
  44. package/dist/src/lib/auto-update.js +15 -2
  45. package/dist/src/lib/auto-update.js.map +1 -1
  46. package/dist/src/lib/auto-update_tests.d.ts +2 -0
  47. package/dist/src/lib/auto-update_tests.d.ts.map +1 -0
  48. package/dist/src/lib/auto-update_tests.js +36 -0
  49. package/dist/src/lib/auto-update_tests.js.map +1 -0
  50. package/dist/src/lib/claude-settings.d.ts +38 -0
  51. package/dist/src/lib/claude-settings.d.ts.map +1 -0
  52. package/dist/src/lib/claude-settings.js +66 -0
  53. package/dist/src/lib/claude-settings.js.map +1 -0
  54. package/dist/src/lib/claude-settings_tests.d.ts +2 -0
  55. package/dist/src/lib/claude-settings_tests.d.ts.map +1 -0
  56. package/dist/src/lib/claude-settings_tests.js +117 -0
  57. package/dist/src/lib/claude-settings_tests.js.map +1 -0
  58. package/dist/src/lib/local-git.d.ts.map +1 -1
  59. package/dist/src/lib/local-git.js +4 -1
  60. package/dist/src/lib/local-git.js.map +1 -1
  61. package/dist/src/lib/project-registry.d.ts +13 -0
  62. package/dist/src/lib/project-registry.d.ts.map +1 -0
  63. package/dist/src/lib/project-registry.js +115 -0
  64. package/dist/src/lib/project-registry.js.map +1 -0
  65. package/dist/src/lib/project-registry_tests.d.ts +2 -0
  66. package/dist/src/lib/project-registry_tests.d.ts.map +1 -0
  67. package/dist/src/lib/project-registry_tests.js +75 -0
  68. package/dist/src/lib/project-registry_tests.js.map +1 -0
  69. package/dist/src/lib/redact.d.ts +13 -0
  70. package/dist/src/lib/redact.d.ts.map +1 -0
  71. package/dist/src/lib/redact.js +33 -0
  72. package/dist/src/lib/redact.js.map +1 -0
  73. package/dist/src/lib/redact_tests.d.ts +2 -0
  74. package/dist/src/lib/redact_tests.d.ts.map +1 -0
  75. package/dist/src/lib/redact_tests.js +75 -0
  76. package/dist/src/lib/redact_tests.js.map +1 -0
  77. package/dist/src/lib/repo-config.d.ts +1 -0
  78. package/dist/src/lib/repo-config.d.ts.map +1 -1
  79. package/dist/src/lib/repo-config.js +6 -2
  80. package/dist/src/lib/repo-config.js.map +1 -1
  81. package/dist/src/lib/session-state.d.ts +20 -0
  82. package/dist/src/lib/session-state.d.ts.map +1 -0
  83. package/dist/src/lib/session-state.js +50 -0
  84. package/dist/src/lib/session-state.js.map +1 -0
  85. package/dist/src/lib/session-state_tests.d.ts +2 -0
  86. package/dist/src/lib/session-state_tests.d.ts.map +1 -0
  87. package/dist/src/lib/session-state_tests.js +34 -0
  88. package/dist/src/lib/session-state_tests.js.map +1 -0
  89. package/dist/src/render/help.js +2 -2
  90. package/dist/src/render/help.js.map +1 -1
  91. package/package.json +7 -3
  92. package/dist/src/commands/init.d.ts +0 -3
  93. package/dist/src/commands/init.d.ts.map +0 -1
  94. package/dist/src/commands/init.js +0 -130
  95. package/dist/src/commands/init.js.map +0 -1
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Secret redaction utilities for SACL event data.
3
+ * Prevents leaking secrets, credentials, or large file contents to the server.
4
+ */
5
+ /** Returns true if the key name matches a pattern that typically holds secrets. */
6
+ export declare function isSecretKey(key: string): boolean;
7
+ /**
8
+ * Redacts values that look like secrets from an object.
9
+ * - Keys matching secret patterns have their values replaced with [REDACTED].
10
+ * - String values over 500 chars are replaced with [CONTENT_REDACTED] (likely file contents or command output).
11
+ */
12
+ export declare function redactSecrets(obj: Record<string, unknown>): Record<string, unknown>;
13
+ //# sourceMappingURL=redact.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"redact.d.ts","sourceRoot":"","sources":["../../../src/lib/redact.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAOH,mFAAmF;AACnF,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAEhD;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAYnF"}
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Secret redaction utilities for SACL event data.
3
+ * Prevents leaking secrets, credentials, or large file contents to the server.
4
+ */
5
+ const SECRET_PATTERNS = /(?:KEY|SECRET|TOKEN|PASSWORD|CREDENTIAL|PRIVATE)/i;
6
+ const CONTENT_LENGTH_REDACTION_THRESHOLD = 500;
7
+ const REDACTED_VALUE = "[REDACTED]";
8
+ const CONTENT_REDACTED_VALUE = "[CONTENT_REDACTED]";
9
+ /** Returns true if the key name matches a pattern that typically holds secrets. */
10
+ export function isSecretKey(key) {
11
+ return SECRET_PATTERNS.test(key);
12
+ }
13
+ /**
14
+ * Redacts values that look like secrets from an object.
15
+ * - Keys matching secret patterns have their values replaced with [REDACTED].
16
+ * - String values over 500 chars are replaced with [CONTENT_REDACTED] (likely file contents or command output).
17
+ */
18
+ export function redactSecrets(obj) {
19
+ const result = {};
20
+ for (const [key, value] of Object.entries(obj)) {
21
+ if (isSecretKey(key)) {
22
+ result[key] = REDACTED_VALUE;
23
+ }
24
+ else if (typeof value === "string" && value.length > CONTENT_LENGTH_REDACTION_THRESHOLD) {
25
+ result[key] = CONTENT_REDACTED_VALUE;
26
+ }
27
+ else {
28
+ result[key] = value;
29
+ }
30
+ }
31
+ return result;
32
+ }
33
+ //# sourceMappingURL=redact.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"redact.js","sourceRoot":"","sources":["../../../src/lib/redact.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,eAAe,GAAG,mDAAmD,CAAC;AAC5E,MAAM,kCAAkC,GAAG,GAAG,CAAC;AAC/C,MAAM,cAAc,GAAG,YAAY,CAAC;AACpC,MAAM,sBAAsB,GAAG,oBAAoB,CAAC;AAEpD,mFAAmF;AACnF,MAAM,UAAU,WAAW,CAAC,GAAW;IACrC,OAAO,eAAe,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AACnC,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,aAAa,CAAC,GAA4B;IACxD,MAAM,MAAM,GAA4B,EAAE,CAAC;IAC3C,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;QAC/C,IAAI,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC;YACrB,MAAM,CAAC,GAAG,CAAC,GAAG,cAAc,CAAC;QAC/B,CAAC;aAAM,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,MAAM,GAAG,kCAAkC,EAAE,CAAC;YAC1F,MAAM,CAAC,GAAG,CAAC,GAAG,sBAAsB,CAAC;QACvC,CAAC;aAAM,CAAC;YACN,MAAM,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;QACtB,CAAC;IACH,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=redact_tests.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"redact_tests.d.ts","sourceRoot":"","sources":["../../../src/lib/redact_tests.ts"],"names":[],"mappings":""}
@@ -0,0 +1,75 @@
1
+ import { describe, it, expect } from "vitest";
2
+ import { isSecretKey, redactSecrets } from "./redact.js";
3
+ describe("isSecretKey", () => {
4
+ it("detects common secret key patterns", () => {
5
+ expect(isSecretKey("API_KEY")).toBe(true);
6
+ expect(isSecretKey("AWS_SECRET_ACCESS_KEY")).toBe(true);
7
+ expect(isSecretKey("GITHUB_TOKEN")).toBe(true);
8
+ expect(isSecretKey("DB_PASSWORD")).toBe(true);
9
+ expect(isSecretKey("PRIVATE_KEY")).toBe(true);
10
+ expect(isSecretKey("MY_CREDENTIAL")).toBe(true);
11
+ });
12
+ it("is case-insensitive", () => {
13
+ expect(isSecretKey("api_key")).toBe(true);
14
+ expect(isSecretKey("ApiKey")).toBe(true);
15
+ expect(isSecretKey("github_token")).toBe(true);
16
+ });
17
+ it("returns false for non-secret keys", () => {
18
+ expect(isSecretKey("filePath")).toBe(false);
19
+ expect(isSecretKey("toolName")).toBe(false);
20
+ expect(isSecretKey("success")).toBe(false);
21
+ expect(isSecretKey("timestamp")).toBe(false);
22
+ // Note: "keyboard" matches because it contains "KEY" — this is a deliberate
23
+ // false-positive tradeoff for security (better to over-redact than leak)
24
+ expect(isSecretKey("username")).toBe(false);
25
+ });
26
+ });
27
+ describe("redactSecrets", () => {
28
+ it("redacts values for keys matching secret patterns", () => {
29
+ const input = {
30
+ API_KEY: "sk-abc123",
31
+ toolName: "Read",
32
+ DB_PASSWORD: "hunter2",
33
+ };
34
+ const result = redactSecrets(input);
35
+ expect(result.API_KEY).toBe("[REDACTED]");
36
+ expect(result.toolName).toBe("Read");
37
+ expect(result.DB_PASSWORD).toBe("[REDACTED]");
38
+ });
39
+ it("redacts long string values as likely file content", () => {
40
+ const longContent = "x".repeat(501);
41
+ const input = {
42
+ output: longContent,
43
+ toolName: "Bash",
44
+ };
45
+ const result = redactSecrets(input);
46
+ expect(result.output).toBe("[CONTENT_REDACTED]");
47
+ expect(result.toolName).toBe("Bash");
48
+ });
49
+ it("preserves short string values", () => {
50
+ const input = {
51
+ filePath: "src/app.ts",
52
+ success: true,
53
+ count: 42,
54
+ };
55
+ const result = redactSecrets(input);
56
+ expect(result.filePath).toBe("src/app.ts");
57
+ expect(result.success).toBe(true);
58
+ expect(result.count).toBe(42);
59
+ });
60
+ it("preserves exactly 500-char strings (threshold is >500)", () => {
61
+ const exactlyFiveHundred = "x".repeat(500);
62
+ const result = redactSecrets({ content: exactlyFiveHundred });
63
+ expect(result.content).toBe(exactlyFiveHundred);
64
+ });
65
+ it("handles empty object", () => {
66
+ expect(redactSecrets({})).toEqual({});
67
+ });
68
+ it("handles null and undefined values", () => {
69
+ const input = { filePath: null, other: undefined };
70
+ const result = redactSecrets(input);
71
+ expect(result.filePath).toBeNull();
72
+ expect(result.other).toBeUndefined();
73
+ });
74
+ });
75
+ //# sourceMappingURL=redact_tests.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"redact_tests.js","sourceRoot":"","sources":["../../../src/lib/redact_tests.ts"],"names":[],"mappings":"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"}
@@ -3,6 +3,7 @@ export interface RepoConfig {
3
3
  }
4
4
  /**
5
5
  * Loads the repo-level Parker config, or null if it doesn't exist.
6
+ * Throws on permission errors, corrupt JSON, or other unexpected failures.
6
7
  */
7
8
  export declare function loadRepoConfig(): Promise<RepoConfig | null>;
8
9
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"repo-config.d.ts","sourceRoot":"","sources":["../../../src/lib/repo-config.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAWD;;GAEG;AACH,wBAAsB,cAAc,IAAI,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAQjE;AAED;;GAEG;AACH,wBAAsB,cAAc,CAAC,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAOtE"}
1
+ {"version":3,"file":"repo-config.d.ts","sourceRoot":"","sources":["../../../src/lib/repo-config.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAWD;;;GAGG;AACH,wBAAsB,cAAc,IAAI,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAWjE;AAED;;GAEG;AACH,wBAAsB,cAAc,CAAC,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAOtE"}
@@ -12,6 +12,7 @@ async function getRepoConfigPath() {
12
12
  }
13
13
  /**
14
14
  * Loads the repo-level Parker config, or null if it doesn't exist.
15
+ * Throws on permission errors, corrupt JSON, or other unexpected failures.
15
16
  */
16
17
  export async function loadRepoConfig() {
17
18
  try {
@@ -19,8 +20,11 @@ export async function loadRepoConfig() {
19
20
  const data = await fs.readFile(configPath, "utf-8");
20
21
  return JSON.parse(data);
21
22
  }
22
- catch {
23
- return null;
23
+ catch (error) {
24
+ if (error instanceof Error && "code" in error && error.code === "ENOENT") {
25
+ return null;
26
+ }
27
+ throw error;
24
28
  }
25
29
  }
26
30
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"repo-config.js","sourceRoot":"","sources":["../../../src/lib/repo-config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,aAAa,CAAC;AAC7B,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAE,eAAe,EAAE,uBAAuB,EAAE,MAAM,iBAAiB,CAAC;AAC3E,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAM5C;;;GAGG;AACH,KAAK,UAAU,iBAAiB;IAC9B,MAAM,IAAI,GAAG,MAAM,UAAU,EAAE,CAAC;IAChC,OAAO,IAAI,CAAC,IAAI,EAAE,eAAe,EAAE,uBAAuB,CAAC,CAAC;AAC9D,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc;IAClC,IAAI,CAAC;QACH,MAAM,UAAU,GAAG,MAAM,iBAAiB,EAAE,CAAC;QAC7C,MAAM,IAAI,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;QACpD,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAe,CAAC;IACxC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,MAAkB;IACrD,MAAM,IAAI,GAAG,MAAM,UAAU,EAAE,CAAC;IAChC,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,EAAE,eAAe,CAAC,CAAC;IAC9C,MAAM,EAAE,CAAC,KAAK,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAE/C,MAAM,UAAU,GAAG,IAAI,CAAC,SAAS,EAAE,uBAAuB,CAAC,CAAC;IAC5D,MAAM,EAAE,CAAC,SAAS,CAAC,UAAU,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;AACzE,CAAC"}
1
+ {"version":3,"file":"repo-config.js","sourceRoot":"","sources":["../../../src/lib/repo-config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,aAAa,CAAC;AAC7B,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAE,eAAe,EAAE,uBAAuB,EAAE,MAAM,iBAAiB,CAAC;AAC3E,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAM5C;;;GAGG;AACH,KAAK,UAAU,iBAAiB;IAC9B,MAAM,IAAI,GAAG,MAAM,UAAU,EAAE,CAAC;IAChC,OAAO,IAAI,CAAC,IAAI,EAAE,eAAe,EAAE,uBAAuB,CAAC,CAAC;AAC9D,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc;IAClC,IAAI,CAAC;QACH,MAAM,UAAU,GAAG,MAAM,iBAAiB,EAAE,CAAC;QAC7C,MAAM,IAAI,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;QACpD,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAe,CAAC;IACxC,CAAC;IAAC,OAAO,KAAc,EAAE,CAAC;QACxB,IAAI,KAAK,YAAY,KAAK,IAAI,MAAM,IAAI,KAAK,IAAK,KAA+B,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YACpG,OAAO,IAAI,CAAC;QACd,CAAC;QACD,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,MAAkB;IACrD,MAAM,IAAI,GAAG,MAAM,UAAU,EAAE,CAAC;IAChC,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,EAAE,eAAe,CAAC,CAAC;IAC9C,MAAM,EAAE,CAAC,KAAK,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAE/C,MAAM,UAAU,GAAG,IAAI,CAAC,SAAS,EAAE,uBAAuB,CAAC,CAAC;IAC5D,MAAM,EAAE,CAAC,SAAS,CAAC,UAAU,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;AACzE,CAAC"}
@@ -0,0 +1,20 @@
1
+ export interface SessionState {
2
+ sessionId: string;
3
+ teamId: string;
4
+ engineerId: string;
5
+ apiUrl: string;
6
+ token: string;
7
+ }
8
+ /** Persists session state to a temp file so subsequent hook invocations can read it. */
9
+ export declare function saveSessionState(claudeSessionId: string, state: SessionState): Promise<void>;
10
+ /**
11
+ * Loads session state from the temp file.
12
+ * Returns null if the file does not exist or is corrupt (e.g., ENOENT, bad JSON).
13
+ */
14
+ export declare function loadSessionState(claudeSessionId: string): Promise<SessionState | null>;
15
+ /**
16
+ * Deletes the session state temp file.
17
+ * Logs non-ENOENT errors to stderr (ENOENT means already cleaned up).
18
+ */
19
+ export declare function clearSessionState(claudeSessionId: string): Promise<void>;
20
+ //# sourceMappingURL=session-state.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-state.d.ts","sourceRoot":"","sources":["../../../src/lib/session-state.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,YAAY;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;CACf;AAUD,wFAAwF;AACxF,wBAAsB,gBAAgB,CACpC,eAAe,EAAE,MAAM,EACvB,KAAK,EAAE,YAAY,GAClB,OAAO,CAAC,IAAI,CAAC,CAGf;AAED;;;GAGG;AACH,wBAAsB,gBAAgB,CACpC,eAAe,EAAE,MAAM,GACtB,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAY9B;AAED;;;GAGG;AACH,wBAAsB,iBAAiB,CACrC,eAAe,EAAE,MAAM,GACtB,OAAO,CAAC,IAAI,CAAC,CASf"}
@@ -0,0 +1,50 @@
1
+ import fs from "fs/promises";
2
+ import path from "path";
3
+ import os from "os";
4
+ const SESSION_STATE_PREFIX = "parker-session-";
5
+ /**
6
+ * Returns the path to the session state file for the given Claude session ID.
7
+ * Uses /tmp/parker-session-<claudeSessionId>.json for cross-hook state sharing.
8
+ */
9
+ function getSessionStatePath(claudeSessionId) {
10
+ return path.join(os.tmpdir(), `${SESSION_STATE_PREFIX}${claudeSessionId}.json`);
11
+ }
12
+ /** Persists session state to a temp file so subsequent hook invocations can read it. */
13
+ export async function saveSessionState(claudeSessionId, state) {
14
+ const filePath = getSessionStatePath(claudeSessionId);
15
+ await fs.writeFile(filePath, JSON.stringify(state));
16
+ }
17
+ /**
18
+ * Loads session state from the temp file.
19
+ * Returns null if the file does not exist or is corrupt (e.g., ENOENT, bad JSON).
20
+ */
21
+ export async function loadSessionState(claudeSessionId) {
22
+ const filePath = getSessionStatePath(claudeSessionId);
23
+ try {
24
+ const data = await fs.readFile(filePath, "utf-8");
25
+ return JSON.parse(data);
26
+ }
27
+ catch (err) {
28
+ // ENOENT is expected when no session is active; other errors are logged
29
+ if (err instanceof Error && "code" in err && err.code !== "ENOENT") {
30
+ process.stderr.write(`parker: failed to load session state: ${err.message}\n`);
31
+ }
32
+ return null;
33
+ }
34
+ }
35
+ /**
36
+ * Deletes the session state temp file.
37
+ * Logs non-ENOENT errors to stderr (ENOENT means already cleaned up).
38
+ */
39
+ export async function clearSessionState(claudeSessionId) {
40
+ const filePath = getSessionStatePath(claudeSessionId);
41
+ try {
42
+ await fs.unlink(filePath);
43
+ }
44
+ catch (err) {
45
+ if (err instanceof Error && "code" in err && err.code !== "ENOENT") {
46
+ process.stderr.write(`parker: failed to clear session state: ${err.message}\n`);
47
+ }
48
+ }
49
+ }
50
+ //# sourceMappingURL=session-state.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-state.js","sourceRoot":"","sources":["../../../src/lib/session-state.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,aAAa,CAAC;AAC7B,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,MAAM,IAAI,CAAC;AAEpB,MAAM,oBAAoB,GAAG,iBAAiB,CAAC;AAU/C;;;GAGG;AACH,SAAS,mBAAmB,CAAC,eAAuB;IAClD,OAAO,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE,GAAG,oBAAoB,GAAG,eAAe,OAAO,CAAC,CAAC;AAClF,CAAC;AAED,wFAAwF;AACxF,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,eAAuB,EACvB,KAAmB;IAEnB,MAAM,QAAQ,GAAG,mBAAmB,CAAC,eAAe,CAAC,CAAC;IACtD,MAAM,EAAE,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC;AACtD,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,eAAuB;IAEvB,MAAM,QAAQ,GAAG,mBAAmB,CAAC,eAAe,CAAC,CAAC;IACtD,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QAClD,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAiB,CAAC;IAC1C,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,wEAAwE;QACxE,IAAI,GAAG,YAAY,KAAK,IAAI,MAAM,IAAI,GAAG,IAAK,GAA6B,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YAC9F,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,yCAAyC,GAAG,CAAC,OAAO,IAAI,CAAC,CAAC;QACjF,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,eAAuB;IAEvB,MAAM,QAAQ,GAAG,mBAAmB,CAAC,eAAe,CAAC,CAAC;IACtD,IAAI,CAAC;QACH,MAAM,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IAC5B,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,GAAG,YAAY,KAAK,IAAI,MAAM,IAAI,GAAG,IAAK,GAA6B,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YAC9F,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,0CAA0C,GAAG,CAAC,OAAO,IAAI,CAAC,CAAC;QAClF,CAAC;IACH,CAAC;AACH,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=session-state_tests.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-state_tests.d.ts","sourceRoot":"","sources":["../../../src/lib/session-state_tests.ts"],"names":[],"mappings":""}
@@ -0,0 +1,34 @@
1
+ import { describe, it, expect, afterEach } from "vitest";
2
+ import { saveSessionState, loadSessionState, clearSessionState } from "./session-state.js";
3
+ const TEST_SESSION_ID = "test-session-vitest-" + Date.now();
4
+ const TEST_STATE = {
5
+ sessionId: "sess-123",
6
+ teamId: "team-456",
7
+ engineerId: "eng-789",
8
+ apiUrl: "http://localhost:4000",
9
+ token: "test-token",
10
+ };
11
+ afterEach(async () => {
12
+ await clearSessionState(TEST_SESSION_ID);
13
+ });
14
+ describe("session-state", () => {
15
+ it("saves and loads session state", async () => {
16
+ await saveSessionState(TEST_SESSION_ID, TEST_STATE);
17
+ const loaded = await loadSessionState(TEST_SESSION_ID);
18
+ expect(loaded).toEqual(TEST_STATE);
19
+ });
20
+ it("returns null when no state file exists", async () => {
21
+ const loaded = await loadSessionState("nonexistent-session-id");
22
+ expect(loaded).toBeNull();
23
+ });
24
+ it("clears session state", async () => {
25
+ await saveSessionState(TEST_SESSION_ID, TEST_STATE);
26
+ await clearSessionState(TEST_SESSION_ID);
27
+ const loaded = await loadSessionState(TEST_SESSION_ID);
28
+ expect(loaded).toBeNull();
29
+ });
30
+ it("clearSessionState does not throw for nonexistent file", async () => {
31
+ await expect(clearSessionState("nonexistent-session-id")).resolves.toBeUndefined();
32
+ });
33
+ });
34
+ //# sourceMappingURL=session-state_tests.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-state_tests.js","sourceRoot":"","sources":["../../../src/lib/session-state_tests.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AACzD,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,iBAAiB,EAAqB,MAAM,oBAAoB,CAAC;AAE9G,MAAM,eAAe,GAAG,sBAAsB,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;AAE5D,MAAM,UAAU,GAAiB;IAC/B,SAAS,EAAE,UAAU;IACrB,MAAM,EAAE,UAAU;IAClB,UAAU,EAAE,SAAS;IACrB,MAAM,EAAE,uBAAuB;IAC/B,KAAK,EAAE,YAAY;CACpB,CAAC;AAEF,SAAS,CAAC,KAAK,IAAI,EAAE;IACnB,MAAM,iBAAiB,CAAC,eAAe,CAAC,CAAC;AAC3C,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,eAAe,EAAE,GAAG,EAAE;IAC7B,EAAE,CAAC,+BAA+B,EAAE,KAAK,IAAI,EAAE;QAC7C,MAAM,gBAAgB,CAAC,eAAe,EAAE,UAAU,CAAC,CAAC;QACpD,MAAM,MAAM,GAAG,MAAM,gBAAgB,CAAC,eAAe,CAAC,CAAC;QAEvD,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;IACrC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,wCAAwC,EAAE,KAAK,IAAI,EAAE;QACtD,MAAM,MAAM,GAAG,MAAM,gBAAgB,CAAC,wBAAwB,CAAC,CAAC;QAEhE,MAAM,CAAC,MAAM,CAAC,CAAC,QAAQ,EAAE,CAAC;IAC5B,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sBAAsB,EAAE,KAAK,IAAI,EAAE;QACpC,MAAM,gBAAgB,CAAC,eAAe,EAAE,UAAU,CAAC,CAAC;QACpD,MAAM,iBAAiB,CAAC,eAAe,CAAC,CAAC;QACzC,MAAM,MAAM,GAAG,MAAM,gBAAgB,CAAC,eAAe,CAAC,CAAC;QAEvD,MAAM,CAAC,MAAM,CAAC,CAAC,QAAQ,EAAE,CAAC;IAC5B,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uDAAuD,EAAE,KAAK,IAAI,EAAE;QACrE,MAAM,MAAM,CAAC,iBAAiB,CAAC,wBAAwB,CAAC,CAAC,CAAC,QAAQ,CAAC,aAAa,EAAE,CAAC;IACrF,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -8,9 +8,9 @@ export function renderHelp(version) {
8
8
  console.log("");
9
9
  // Getting Started
10
10
  console.log(chalk.bold(" Getting Started"));
11
- console.log(` ${cmd("parker init")} Set up Parker and authenticate`);
11
+ console.log(` ${cmd("parker enable")} Enable Parker for this repo`);
12
+ console.log(` ${cmd("parker disable")} Remove Parker from this repo`);
12
13
  console.log(` ${cmd("parker join")} ${arg("<code>")} Join an existing team`);
13
- console.log(` ${cmd("parker connect claude")} Connect to Claude Code`);
14
14
  console.log("");
15
15
  // Tips
16
16
  console.log(dim(" Tips"));
@@ -1 +1 @@
1
- {"version":3,"file":"help.js","sourceRoot":"","sources":["../../../src/render/help.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,MAAM,UAAU,UAAU,CAAC,OAAe;IACxC,MAAM,GAAG,GAAG,CAAC,IAAY,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAChD,MAAM,GAAG,GAAG,CAAC,IAAY,EAAE,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IACjD,MAAM,GAAG,GAAG,KAAK,CAAC,GAAG,CAAC;IAEtB,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChB,OAAO,CAAC,GAAG,CAAC,KAAK,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,GAAG,CAAC,IAAI,OAAO,EAAE,CAAC,kCAAkC,CAAC,CAAC;IAC/F,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAEhB,kBAAkB;IAClB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC,CAAC;IAC7C,OAAO,CAAC,GAAG,CAAC,OAAO,GAAG,CAAC,aAAa,CAAC,oDAAoD,CAAC,CAAC;IAC3F,OAAO,CAAC,GAAG,CAAC,OAAO,GAAG,CAAC,aAAa,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,oCAAoC,CAAC,CAAC;IAC5F,OAAO,CAAC,GAAG,CAAC,OAAO,GAAG,CAAC,uBAAuB,CAAC,mCAAmC,CAAC,CAAC;IACpF,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAEhB,OAAO;IACP,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC;IAC3B,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,WAAW,KAAK,CAAC,KAAK,CAAC,yBAAyB,CAAC,uBAAuB,CAAC,CAAC,CAAC;IAC3F,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,WAAW,KAAK,CAAC,KAAK,CAAC,eAAe,CAAC,kCAAkC,CAAC,CAAC,CAAC;IAC5F,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;AAClB,CAAC"}
1
+ {"version":3,"file":"help.js","sourceRoot":"","sources":["../../../src/render/help.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,MAAM,UAAU,UAAU,CAAC,OAAe;IACxC,MAAM,GAAG,GAAG,CAAC,IAAY,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAChD,MAAM,GAAG,GAAG,CAAC,IAAY,EAAE,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IACjD,MAAM,GAAG,GAAG,KAAK,CAAC,GAAG,CAAC;IAEtB,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChB,OAAO,CAAC,GAAG,CAAC,KAAK,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,GAAG,CAAC,IAAI,OAAO,EAAE,CAAC,kCAAkC,CAAC,CAAC;IAC/F,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAEhB,kBAAkB;IAClB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC,CAAC;IAC7C,OAAO,CAAC,GAAG,CAAC,OAAO,GAAG,CAAC,eAAe,CAAC,+CAA+C,CAAC,CAAC;IACxF,OAAO,CAAC,GAAG,CAAC,OAAO,GAAG,CAAC,gBAAgB,CAAC,+CAA+C,CAAC,CAAC;IACzF,OAAO,CAAC,GAAG,CAAC,OAAO,GAAG,CAAC,aAAa,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,oCAAoC,CAAC,CAAC;IAC5F,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAEhB,OAAO;IACP,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC;IAC3B,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,WAAW,KAAK,CAAC,KAAK,CAAC,yBAAyB,CAAC,uBAAuB,CAAC,CAAC,CAAC;IAC3F,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,WAAW,KAAK,CAAC,KAAK,CAAC,eAAe,CAAC,kCAAkC,CAAC,CAAC,CAAC;IAC5F,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;AAClB,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@parkercto/cli",
3
- "version": "0.1.0",
3
+ "version": "0.2.2",
4
4
  "type": "module",
5
5
  "files": [
6
6
  "dist",
@@ -19,12 +19,16 @@
19
19
  "@types/node": "^22.0.0",
20
20
  "@types/update-notifier": "^6.0.8",
21
21
  "tsx": "^4.19.0",
22
- "typescript": "^5.7.0"
22
+ "typescript": "^5.7.0",
23
+ "vitest": "^4.0.18"
23
24
  },
24
25
  "scripts": {
25
26
  "build": "tsc",
26
27
  "dev": "tsx src/cli.ts",
27
28
  "typecheck": "tsc --noEmit",
28
- "clean": "rm -rf dist"
29
+ "clean": "rm -rf dist",
30
+ "test": "vitest run",
31
+ "test:watch": "vitest",
32
+ "preuninstall": "node dist/bin/preuninstall.js"
29
33
  }
30
34
  }
@@ -1,3 +0,0 @@
1
- import { Command } from "commander";
2
- export declare const initCommand: Command;
3
- //# sourceMappingURL=init.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../../src/commands/init.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAYpC,eAAO,MAAM,WAAW,SAoIpB,CAAC"}
@@ -1,130 +0,0 @@
1
- import { Command } from "commander";
2
- import chalk from "chalk";
3
- import readline from "readline/promises";
4
- import { ParkerClient } from "../client/api-client.js";
5
- import { saveAuth, getApiUrl } from "../client/auth.js";
6
- import { loadRepoConfig } from "../lib/repo-config.js";
7
- import { OAUTH_CALLBACK_PORT } from "../constants.js";
8
- import { joinTeamInteractive } from "./join.js";
9
- import open from "open";
10
- import http from "http";
11
- import url from "url";
12
- export const initCommand = new Command("init")
13
- .description("Set up Parker — verify your team, authenticate, and join")
14
- .option("--dev", "Use dev auth (no GitHub OAuth)")
15
- .action(async (options) => {
16
- const apiUrl = await getApiUrl();
17
- const client = new ParkerClient(apiUrl, "");
18
- // Step 1: Determine team code (auto-detect from repo config or prompt)
19
- let teamCode;
20
- const repoConfig = await loadRepoConfig();
21
- if (repoConfig?.teamCode) {
22
- teamCode = repoConfig.teamCode;
23
- console.log(chalk.dim(`Found team code in .parker/config.json: ${teamCode}`));
24
- }
25
- else {
26
- const rl = readline.createInterface({
27
- input: process.stdin,
28
- output: process.stdout,
29
- });
30
- const answer = await rl.question("Team code: ");
31
- rl.close();
32
- if (!answer.trim()) {
33
- console.error(chalk.red("Team code is required to get started."));
34
- console.log(chalk.dim("Ask your team admin for the join code (e.g., XKCD-LAMP-FISH)"));
35
- process.exit(1);
36
- }
37
- teamCode = answer.trim();
38
- }
39
- // Step 2: Verify team code exists
40
- let verifiedTeam;
41
- try {
42
- verifiedTeam = await client.verifyTeamCode(teamCode);
43
- }
44
- catch (error) {
45
- if (error.status === 404) {
46
- console.error(chalk.red("Team not found. Double-check the code and try again."));
47
- }
48
- else {
49
- console.error(chalk.red("Could not verify team:", error.message));
50
- }
51
- process.exit(1);
52
- }
53
- console.log(chalk.green(`✓ Found team "${verifiedTeam.name}"`));
54
- console.log("");
55
- // Step 3: Authenticate
56
- if (options.dev) {
57
- const rl = readline.createInterface({
58
- input: process.stdin,
59
- output: process.stdout,
60
- });
61
- const username = await rl.question("GitHub username: ");
62
- rl.close();
63
- try {
64
- const result = await client.authDev(username);
65
- const auth = {
66
- token: result.token,
67
- userId: result.user.id,
68
- githubUsername: result.user.githubUsername,
69
- apiUrl,
70
- };
71
- await saveAuth(auth);
72
- console.log(chalk.green("✓ Logged in as " + result.user.githubUsername));
73
- console.log("");
74
- // Step 4: Join the verified team (writes .parker/config.json)
75
- await joinTeamInteractive(auth, verifiedTeam.teamCode);
76
- }
77
- catch (error) {
78
- console.error(chalk.red("Login failed:", error.message));
79
- process.exit(1);
80
- }
81
- }
82
- else {
83
- // GitHub OAuth flow
84
- console.log("Opening browser for GitHub authentication...");
85
- const server = http.createServer();
86
- const port = OAUTH_CALLBACK_PORT;
87
- server.listen(port, () => {
88
- const authUrl = `${apiUrl}/auth/github?cli_port=${port}`;
89
- open(authUrl);
90
- });
91
- server.on("request", async (req, res) => {
92
- const parsedUrl = url.parse(req.url, true);
93
- if (parsedUrl.pathname === "/callback") {
94
- const token = parsedUrl.query.token;
95
- const userId = parsedUrl.query.user_id;
96
- const username = parsedUrl.query.username;
97
- if (token && userId && username) {
98
- const auth = {
99
- token,
100
- userId,
101
- githubUsername: username,
102
- apiUrl,
103
- };
104
- await saveAuth(auth);
105
- res.writeHead(200, { "Content-Type": "text/html" });
106
- res.end("<html><body><h1>Success!</h1><p>You can close this window.</p></body></html>");
107
- server.close();
108
- console.log(chalk.green("✓ Logged in as " + username));
109
- console.log("");
110
- // Step 4: Join the verified team (writes .parker/config.json)
111
- try {
112
- await joinTeamInteractive(auth, verifiedTeam.teamCode);
113
- }
114
- catch (error) {
115
- console.error(chalk.red("Failed to join team:", error.message));
116
- }
117
- process.exit(0);
118
- }
119
- else {
120
- res.writeHead(400, { "Content-Type": "text/html" });
121
- res.end("<html><body><h1>Error</h1><p>Authentication failed — missing token.</p></body></html>");
122
- console.error(chalk.red("Login failed: missing token in callback"));
123
- server.close();
124
- process.exit(1);
125
- }
126
- }
127
- });
128
- }
129
- });
130
- //# sourceMappingURL=init.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"init.js","sourceRoot":"","sources":["../../../src/commands/init.ts"],"names":[],"mappings":"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"}