@relace-ai/jacq 0.1.2-beta.4 → 0.1.2-beta.6

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 (94) hide show
  1. package/dist/actions/messages.d.ts +16 -16
  2. package/dist/actions/messages.js +47 -29
  3. package/dist/actions/messages.js.map +1 -1
  4. package/dist/actions/tasks.d.ts +1 -2
  5. package/dist/actions/tasks.js +8 -8
  6. package/dist/actions/tasks.js.map +1 -1
  7. package/dist/approvalGate.d.ts +42 -0
  8. package/dist/approvalGate.js +140 -0
  9. package/dist/approvalGate.js.map +1 -0
  10. package/dist/approvals.d.ts +21 -0
  11. package/dist/approvals.js +79 -0
  12. package/dist/approvals.js.map +1 -0
  13. package/dist/auth.d.ts +1 -0
  14. package/dist/auth.js +3 -0
  15. package/dist/auth.js.map +1 -1
  16. package/dist/charWidth.d.ts +7 -0
  17. package/dist/charWidth.js +24 -19
  18. package/dist/charWidth.js.map +1 -1
  19. package/dist/clipboard.d.ts +0 -5
  20. package/dist/clipboard.js +0 -5
  21. package/dist/clipboard.js.map +1 -1
  22. package/dist/commands.js +3 -2
  23. package/dist/commands.js.map +1 -1
  24. package/dist/config.d.ts +2 -1
  25. package/dist/config.js +17 -10
  26. package/dist/config.js.map +1 -1
  27. package/dist/connection.d.ts +2 -0
  28. package/dist/connection.js +199 -6
  29. package/dist/connection.js.map +1 -1
  30. package/dist/index.js +196 -34
  31. package/dist/index.js.map +1 -1
  32. package/dist/markdown/parser.js +248 -60
  33. package/dist/markdown/parser.js.map +1 -1
  34. package/dist/markdown/renderer.d.ts +3 -3
  35. package/dist/markdown/renderer.js +254 -108
  36. package/dist/markdown/renderer.js.map +1 -1
  37. package/dist/markdown/types.d.ts +4 -1
  38. package/dist/markdown/types.js.map +1 -1
  39. package/dist/protocol.d.ts +0 -2
  40. package/dist/protocol.js +137 -98
  41. package/dist/protocol.js.map +1 -1
  42. package/dist/renderer.js +4 -0
  43. package/dist/renderer.js.map +1 -1
  44. package/dist/startupAnimation.d.ts +4 -0
  45. package/dist/startupAnimation.js +326 -0
  46. package/dist/startupAnimation.js.map +1 -0
  47. package/dist/state.js +23 -5
  48. package/dist/state.js.map +1 -1
  49. package/dist/styles.js +4 -1
  50. package/dist/styles.js.map +1 -1
  51. package/dist/terminal.d.ts +9 -0
  52. package/dist/terminal.js +15 -0
  53. package/dist/terminal.js.map +1 -1
  54. package/dist/tools/registry.js +138 -13
  55. package/dist/tools/registry.js.map +1 -1
  56. package/dist/types.d.ts +57 -21
  57. package/dist/types.js +3 -1
  58. package/dist/types.js.map +1 -1
  59. package/dist/ui/config.d.ts +6 -0
  60. package/dist/ui/config.js +53 -0
  61. package/dist/ui/config.js.map +1 -0
  62. package/dist/ui/diffViewer.d.ts +9 -0
  63. package/dist/ui/diffViewer.js +320 -0
  64. package/dist/ui/diffViewer.js.map +1 -0
  65. package/dist/ui/index.js +40 -21
  66. package/dist/ui/index.js.map +1 -1
  67. package/dist/ui/input.d.ts +1 -1
  68. package/dist/ui/input.js +40 -15
  69. package/dist/ui/input.js.map +1 -1
  70. package/dist/ui/localCommands.d.ts +8 -0
  71. package/dist/ui/localCommands.js +267 -0
  72. package/dist/ui/localCommands.js.map +1 -0
  73. package/dist/ui/messages.js +195 -93
  74. package/dist/ui/messages.js.map +1 -1
  75. package/dist/ui/primitives.js +2 -1
  76. package/dist/ui/primitives.js.map +1 -1
  77. package/dist/ui/promptInput.js +42 -8
  78. package/dist/ui/promptInput.js.map +1 -1
  79. package/dist/ui/promptPicker.js +3 -4
  80. package/dist/ui/promptPicker.js.map +1 -1
  81. package/dist/ui/resumeTask.d.ts +6 -0
  82. package/dist/ui/resumeTask.js +136 -0
  83. package/dist/ui/resumeTask.js.map +1 -0
  84. package/dist/ui/sessions.js +2 -2
  85. package/dist/ui/sessions.js.map +1 -1
  86. package/dist/ui/welcome.js +22 -35
  87. package/dist/ui/welcome.js.map +1 -1
  88. package/dist/utils/resolvePath.d.ts +10 -0
  89. package/dist/utils/resolvePath.js +24 -0
  90. package/dist/utils/resolvePath.js.map +1 -0
  91. package/package.json +7 -4
  92. package/dist/ui/backgroundTasks.d.ts +0 -7
  93. package/dist/ui/backgroundTasks.js +0 -192
  94. package/dist/ui/backgroundTasks.js.map +0 -1
@@ -1,31 +1,32 @@
1
1
  /**
2
- * Message actions
3
- *
4
- * Message types: 'user' | 'agent' | 'tool' | 'status' | 'error'
2
+ * Message actions — typed factory functions for each message variant.
5
3
  */
6
- import type { Message } from '../types.js';
7
- interface AddMessageOptions {
4
+ import type { Message, UserMessage, ToolMessage, StatusMessage, ErrorMessage, ToolCall, StatusKind } from '../types.js';
5
+ export declare function addUserMessage(content: string, taskId?: string): UserMessage;
6
+ export declare function addToolMessage(content: string, attrs: {
8
7
  taskId?: string;
9
- toolCalls?: Message['toolCalls'];
8
+ toolCalls: ToolCall[];
10
9
  agentMessage?: string | null;
11
10
  tokens?: {
12
11
  input: number;
13
12
  output: number;
14
13
  } | null;
14
+ }): ToolMessage;
15
+ export declare function addStatusMessage(content: string, attrs: {
16
+ taskId?: string;
17
+ statusKind: StatusKind;
15
18
  linkUrl?: string;
16
- }
17
- /**
18
- * Add a message to the list
19
- */
20
- export declare function addMessage(type: Message['type'], content: string, options?: AddMessageOptions): Message;
19
+ timestamp?: number;
20
+ }): StatusMessage;
21
+ export declare function addErrorMessage(content: string, attrs?: {
22
+ taskId?: string;
23
+ statusKind?: StatusKind;
24
+ timestamp?: number;
25
+ }): ErrorMessage;
21
26
  /**
22
27
  * Append to stream buffer (for streaming responses)
23
28
  */
24
29
  export declare function appendStream(chunk: string): void;
25
- /**
26
- * Flush stream buffer to a message
27
- */
28
- export declare function flushStream(taskId?: string): void;
29
30
  /**
30
31
  * Clear messages (when switching tasks)
31
32
  */
@@ -38,4 +39,3 @@ export declare function getVisibleMessages(): Message[];
38
39
  * Check if the current task is running
39
40
  */
40
41
  export declare function isCurrentTaskRunning(): boolean;
41
- export {};
@@ -1,28 +1,13 @@
1
1
  /**
2
- * Message actions
3
- *
4
- * Message types: 'user' | 'agent' | 'tool' | 'status' | 'error'
2
+ * Message actions — typed factory functions for each message variant.
5
3
  */
6
4
  import { state, markDirty } from '../state.js';
7
5
  let messageIdCounter = 0;
8
- const MAX_MESSAGES = 100;
9
- /**
10
- * Add a message to the list
11
- */
12
- export function addMessage(type, content, options = {}) {
13
- const message = {
14
- id: `msg-${++messageIdCounter}`,
15
- type,
16
- content,
17
- taskId: options.taskId || state.currentTaskId || undefined,
18
- toolCalls: options.toolCalls || null,
19
- agentMessage: options.agentMessage || null,
20
- tokens: options.tokens || null,
21
- linkUrl: options.linkUrl,
22
- timestamp: Date.now(),
23
- };
6
+ const MAX_MESSAGES = 10000;
7
+ function nextId() { return `msg-${++messageIdCounter}`; }
8
+ function resolveTaskId(taskId) { return taskId || state.currentTaskId || undefined; }
9
+ function pushMessage(message) {
24
10
  state.messages.push(message);
25
- // Trim old messages
26
11
  if (state.messages.length > MAX_MESSAGES) {
27
12
  const trimCount = state.messages.length - MAX_MESSAGES;
28
13
  state.messages = state.messages.slice(trimCount);
@@ -30,6 +15,48 @@ export function addMessage(type, content, options = {}) {
30
15
  markDirty();
31
16
  return message;
32
17
  }
18
+ export function addUserMessage(content, taskId) {
19
+ return pushMessage({
20
+ id: nextId(),
21
+ type: 'user',
22
+ content,
23
+ taskId: resolveTaskId(taskId),
24
+ timestamp: Date.now(),
25
+ });
26
+ }
27
+ export function addToolMessage(content, attrs) {
28
+ return pushMessage({
29
+ id: nextId(),
30
+ type: 'tool',
31
+ content,
32
+ taskId: resolveTaskId(attrs.taskId),
33
+ toolCalls: attrs.toolCalls,
34
+ agentMessage: attrs.agentMessage ?? null,
35
+ tokens: attrs.tokens ?? null,
36
+ timestamp: Date.now(),
37
+ });
38
+ }
39
+ export function addStatusMessage(content, attrs) {
40
+ return pushMessage({
41
+ id: nextId(),
42
+ type: 'status',
43
+ content,
44
+ taskId: resolveTaskId(attrs.taskId),
45
+ statusKind: attrs.statusKind,
46
+ linkUrl: attrs.linkUrl,
47
+ timestamp: attrs.timestamp || Date.now(),
48
+ });
49
+ }
50
+ export function addErrorMessage(content, attrs) {
51
+ return pushMessage({
52
+ id: nextId(),
53
+ type: 'error',
54
+ content,
55
+ taskId: resolveTaskId(attrs?.taskId),
56
+ statusKind: attrs?.statusKind,
57
+ timestamp: attrs?.timestamp || Date.now(),
58
+ });
59
+ }
33
60
  /**
34
61
  * Append to stream buffer (for streaming responses)
35
62
  */
@@ -37,15 +64,6 @@ export function appendStream(chunk) {
37
64
  state.streamBuffer += chunk;
38
65
  markDirty();
39
66
  }
40
- /**
41
- * Flush stream buffer to a message
42
- */
43
- export function flushStream(taskId) {
44
- if (state.streamBuffer.trim()) {
45
- addMessage('agent', state.streamBuffer, { taskId });
46
- }
47
- state.streamBuffer = '';
48
- }
49
67
  /**
50
68
  * Clear messages (when switching tasks)
51
69
  */
@@ -1 +1 @@
1
- {"version":3,"file":"messages.js","sourceRoot":"","sources":["../../src/actions/messages.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAG/C,IAAI,gBAAgB,GAAG,CAAC,CAAC;AACzB,MAAM,YAAY,GAAG,GAAG,CAAC;AAUzB;;GAEG;AACH,MAAM,UAAU,UAAU,CAAC,IAAqB,EAAE,OAAe,EAAE,UAA6B,EAAE;IAC9F,MAAM,OAAO,GAAY;QACrB,EAAE,EAAE,OAAO,EAAE,gBAAgB,EAAE;QAC/B,IAAI;QACJ,OAAO;QACP,MAAM,EAAE,OAAO,CAAC,MAAM,IAAI,KAAK,CAAC,aAAa,IAAI,SAAS;QAC1D,SAAS,EAAE,OAAO,CAAC,SAAS,IAAI,IAAI;QACpC,YAAY,EAAE,OAAO,CAAC,YAAY,IAAI,IAAI;QAC1C,MAAM,EAAE,OAAO,CAAC,MAAM,IAAI,IAAI;QAC9B,OAAO,EAAE,OAAO,CAAC,OAAO;QACxB,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;KACxB,CAAC;IAEF,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAE7B,oBAAoB;IACpB,IAAI,KAAK,CAAC,QAAQ,CAAC,MAAM,GAAG,YAAY,EAAE,CAAC;QACvC,MAAM,SAAS,GAAG,KAAK,CAAC,QAAQ,CAAC,MAAM,GAAG,YAAY,CAAC;QACvD,KAAK,CAAC,QAAQ,GAAG,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;IACrD,CAAC;IAED,SAAS,EAAE,CAAC;IACZ,OAAO,OAAO,CAAC;AACnB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,YAAY,CAAC,KAAa;IACtC,KAAK,CAAC,YAAY,IAAI,KAAK,CAAC;IAC5B,SAAS,EAAE,CAAC;AAChB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,WAAW,CAAC,MAAe;IACvC,IAAI,KAAK,CAAC,YAAY,CAAC,IAAI,EAAE,EAAE,CAAC;QAC5B,UAAU,CAAC,OAAO,EAAE,KAAK,CAAC,YAAY,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;IACxD,CAAC;IACD,KAAK,CAAC,YAAY,GAAG,EAAE,CAAC;AAC5B,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,aAAa;IACzB,KAAK,CAAC,QAAQ,GAAG,EAAE,CAAC;IACpB,KAAK,CAAC,YAAY,GAAG,EAAE,CAAC;IACxB,SAAS,EAAE,CAAC;AAChB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,kBAAkB;IAC9B,IAAI,CAAC,KAAK,CAAC,aAAa,EAAE,CAAC;QACvB,OAAO,KAAK,CAAC,QAAQ,CAAC;IAC1B,CAAC;IACD,OAAO,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAC7B,CAAC,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,MAAM,KAAK,KAAK,CAAC,aAAa,CAChD,CAAC;AACN,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,oBAAoB;IAChC,IAAI,KAAK,CAAC,UAAU;QAAE,OAAO,IAAI,CAAC;IAClC,IAAI,CAAC,KAAK,CAAC,aAAa;QAAE,OAAO,KAAK,CAAC;IACvC,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,KAAK,CAAC,aAAa,CAAC,CAAC;IACjE,OAAO,CAAC,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,KAAK,SAAS,IAAI,IAAI,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC;AAC9E,CAAC"}
1
+ {"version":3,"file":"messages.js","sourceRoot":"","sources":["../../src/actions/messages.ts"],"names":[],"mappings":"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"}
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * Task & connection state actions
3
3
  */
4
- import type { Task, Widget } from '../types.js';
4
+ import type { Task } from '../types.js';
5
5
  export declare function setConnected(clientId: string): void;
6
6
  export declare function setDisconnected(): void;
7
7
  export declare function setServerStatus(status: unknown): void;
@@ -10,4 +10,3 @@ export declare function setTasks(tasks: Task[]): void;
10
10
  export declare function updateTask(taskId: string | undefined, updates: Record<string, unknown>): void;
11
11
  export declare function setCurrentTask(taskId: string | null): void;
12
12
  export declare function setSubmitting(val: boolean): void;
13
- export declare function setWidgets(widgets: Widget[]): void;
@@ -5,12 +5,14 @@ import { state, markDirty } from '../state.js';
5
5
  // --- Connection state ---
6
6
  export function setConnected(clientId) {
7
7
  state.connected = true;
8
+ state.wasConnected = true;
8
9
  state.clientId = clientId;
9
10
  state.statusMessage = null;
10
11
  markDirty();
11
12
  }
12
13
  export function setDisconnected() {
13
14
  state.connected = false;
15
+ state.statusMessage = null;
14
16
  markDirty();
15
17
  }
16
18
  export function setServerStatus(status) {
@@ -42,10 +44,14 @@ export function updateTask(taskId, updates) {
42
44
  cacheCreate: prev.cacheCreate + (delta.cacheCreate || 0),
43
45
  };
44
46
  const { tokensDelta: _, ...rest } = updates;
45
- Object.assign(task, rest, { updatedAt: new Date().toISOString() });
47
+ Object.assign(task, rest);
48
+ if (!rest.updatedAt)
49
+ task.updatedAt = new Date().toISOString();
46
50
  }
47
51
  else {
48
- Object.assign(task, updates, { updatedAt: new Date().toISOString() });
52
+ Object.assign(task, updates);
53
+ if (!updates.updatedAt)
54
+ task.updatedAt = new Date().toISOString();
49
55
  }
50
56
  }
51
57
  }
@@ -57,10 +63,4 @@ export function setSubmitting(val) {
57
63
  state.submitting = val;
58
64
  markDirty();
59
65
  }
60
- // --- Widgets ---
61
- export function setWidgets(widgets) {
62
- state.widgets = widgets;
63
- state.widgetsLoaded = true;
64
- markDirty();
65
- }
66
66
  //# sourceMappingURL=tasks.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"tasks.js","sourceRoot":"","sources":["../../src/actions/tasks.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"tasks.js","sourceRoot":"","sources":["../../src/actions/tasks.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Approval gate — promise-based gate for tool execution approval
3
+ *
4
+ * When a bash or write_file tool needs user approval, creates a promise
5
+ * that blocks execution until the user acts on the overlay dialog.
6
+ * Only one approval can be pending at a time (server waits for tool.result).
7
+ */
8
+ export type ApprovalDecision = {
9
+ action: 'approve';
10
+ } | {
11
+ action: 'allowlist';
12
+ prefix?: string;
13
+ dir?: string;
14
+ } | {
15
+ action: 'reject';
16
+ };
17
+ /**
18
+ * Request approval for a bash command.
19
+ * Returns null if the command is already allowlisted (auto-approved).
20
+ * Otherwise returns a Promise that resolves when the user acts.
21
+ */
22
+ export declare function requestBashApproval(command: string): Promise<ApprovalDecision> | null;
23
+ /**
24
+ * Request approval for a file edit (write_file).
25
+ * Returns null if the edit is already allowed (dir allowlist).
26
+ * Otherwise returns a Promise that resolves when the user acts.
27
+ */
28
+ export declare function requestEditApproval(filePath: string, newContent: string, cwd: string, append?: boolean): Promise<ApprovalDecision> | null;
29
+ /**
30
+ * Request approval for an edit_file operation.
31
+ * Returns null if auto-approved. Otherwise shows diff viewer.
32
+ */
33
+ export declare function requestEditFileApproval(filePath: string, oldString: string, newString: string, replaceAll: boolean, cwd: string): Promise<ApprovalDecision> | null;
34
+ /**
35
+ * Request approval for a file operation (copy_file, delete_file).
36
+ * Returns null if auto-approved. Otherwise shows localCommands overlay.
37
+ */
38
+ export declare function requestFileOpApproval(title: string, description: string, targetPath: string, cwd: string): Promise<ApprovalDecision> | null;
39
+ /**
40
+ * Resolve the pending approval promise. Called from index.ts action handlers.
41
+ */
42
+ export declare function resolveApproval(decision: ApprovalDecision): void;
@@ -0,0 +1,140 @@
1
+ /**
2
+ * Approval gate — promise-based gate for tool execution approval
3
+ *
4
+ * When a bash or write_file tool needs user approval, creates a promise
5
+ * that blocks execution until the user acts on the overlay dialog.
6
+ * Only one approval can be pending at a time (server waits for tool.result).
7
+ */
8
+ import fs from 'fs';
9
+ import path from 'path';
10
+ import { state, markDirty } from './state.js';
11
+ import { isBashAllowed, isEditAllowed, suggestBashPrefix } from './approvals.js';
12
+ import { resolvePath } from './utils/resolvePath.js';
13
+ let pendingResolve = null;
14
+ /**
15
+ * Request approval for a bash command.
16
+ * Returns null if the command is already allowlisted (auto-approved).
17
+ * Otherwise returns a Promise that resolves when the user acts.
18
+ */
19
+ export function requestBashApproval(command) {
20
+ if (isBashAllowed(command))
21
+ return null;
22
+ return new Promise((resolve) => {
23
+ pendingResolve = resolve;
24
+ state.localCommandsTitle = null; // Reset to show default "Bash command" title
25
+ state.localCommandsProposed = command;
26
+ state.localCommandsSuggestedPrefix = suggestBashPrefix(command);
27
+ state.localCommandsDir = process.cwd();
28
+ state.localCommandsIndex = 0;
29
+ state.localCommandsFullscreen = false;
30
+ state.localCommandsScrollOffset = 0;
31
+ state.overlay = 'localCommands';
32
+ markDirty();
33
+ });
34
+ }
35
+ /**
36
+ * Request approval for a file edit (write_file).
37
+ * Returns null if the edit is already allowed (dir allowlist).
38
+ * Otherwise returns a Promise that resolves when the user acts.
39
+ */
40
+ export function requestEditApproval(filePath, newContent, cwd, append) {
41
+ const resolved = resolvePath(filePath, cwd);
42
+ if (isEditAllowed(resolved))
43
+ return null;
44
+ // Read existing file content for diff
45
+ let oldContent = '';
46
+ try {
47
+ oldContent = fs.readFileSync(resolved, 'utf-8');
48
+ }
49
+ catch {
50
+ // File doesn't exist yet — old content is empty
51
+ }
52
+ // For append mode, new content is old + appended
53
+ const effectiveNewContent = append ? oldContent + newContent : newContent;
54
+ return new Promise((resolve) => {
55
+ pendingResolve = resolve;
56
+ state.diffViewerFileName = filePath;
57
+ state.diffViewerOldContent = oldContent;
58
+ state.diffViewerNewContent = effectiveNewContent;
59
+ state.diffViewerSuggestedDir = path.dirname(resolved);
60
+ state.diffViewerIndex = 0;
61
+ state.diffViewerFullscreen = false;
62
+ state.diffViewerScrollOffset = 0;
63
+ state.overlay = 'diffViewer';
64
+ markDirty();
65
+ });
66
+ }
67
+ /**
68
+ * Request approval for an edit_file operation.
69
+ * Returns null if auto-approved. Otherwise shows diff viewer.
70
+ */
71
+ export function requestEditFileApproval(filePath, oldString, newString, replaceAll, cwd) {
72
+ const resolved = resolvePath(filePath, cwd);
73
+ if (isEditAllowed(resolved))
74
+ return null;
75
+ // Read file and compute replacement result
76
+ let oldContent = '';
77
+ try {
78
+ oldContent = fs.readFileSync(resolved, 'utf-8');
79
+ }
80
+ catch {
81
+ // File doesn't exist — will error in execution
82
+ }
83
+ let newContent;
84
+ if (replaceAll) {
85
+ newContent = oldContent.split(oldString).join(newString);
86
+ }
87
+ else {
88
+ const pos = oldContent.indexOf(oldString);
89
+ if (pos === -1) {
90
+ newContent = oldContent; // No match — execution will handle the error
91
+ }
92
+ else {
93
+ newContent = oldContent.slice(0, pos) + newString + oldContent.slice(pos + oldString.length);
94
+ }
95
+ }
96
+ return new Promise((resolve) => {
97
+ pendingResolve = resolve;
98
+ state.diffViewerFileName = filePath;
99
+ state.diffViewerOldContent = oldContent;
100
+ state.diffViewerNewContent = newContent;
101
+ state.diffViewerSuggestedDir = path.dirname(resolved);
102
+ state.diffViewerIndex = 0;
103
+ state.diffViewerFullscreen = false;
104
+ state.diffViewerScrollOffset = 0;
105
+ state.overlay = 'diffViewer';
106
+ markDirty();
107
+ });
108
+ }
109
+ /**
110
+ * Request approval for a file operation (copy_file, delete_file).
111
+ * Returns null if auto-approved. Otherwise shows localCommands overlay.
112
+ */
113
+ export function requestFileOpApproval(title, description, targetPath, cwd) {
114
+ const resolved = resolvePath(targetPath, cwd);
115
+ if (isEditAllowed(resolved))
116
+ return null;
117
+ return new Promise((resolve) => {
118
+ pendingResolve = resolve;
119
+ state.localCommandsTitle = title;
120
+ state.localCommandsProposed = description;
121
+ state.localCommandsSuggestedPrefix = null;
122
+ state.localCommandsDir = path.dirname(resolved);
123
+ state.localCommandsIndex = 0;
124
+ state.localCommandsFullscreen = false;
125
+ state.localCommandsScrollOffset = 0;
126
+ state.overlay = 'localCommands';
127
+ markDirty();
128
+ });
129
+ }
130
+ /**
131
+ * Resolve the pending approval promise. Called from index.ts action handlers.
132
+ */
133
+ export function resolveApproval(decision) {
134
+ if (pendingResolve) {
135
+ const resolve = pendingResolve;
136
+ pendingResolve = null;
137
+ resolve(decision);
138
+ }
139
+ }
140
+ //# sourceMappingURL=approvalGate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"approvalGate.js","sourceRoot":"","sources":["../src/approvalGate.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Approval persistence — manages ~/.jacq/approvals.json
3
+ *
4
+ * Stores bash command prefix allowlist and edit directory allowlist.
5
+ * Uses atomic writes (write-to-tmp + rename) same as config.ts.
6
+ */
7
+ interface ApprovalsData {
8
+ bash_allowlist: string[];
9
+ edit_allowed_dirs: string[];
10
+ }
11
+ export declare function loadApprovals(): ApprovalsData;
12
+ export declare function saveApprovals(data: ApprovalsData): void;
13
+ export declare function addBashPrefix(prefix: string): void;
14
+ export declare function addEditDir(dir: string): void;
15
+ export declare function isBashAllowed(command: string): boolean;
16
+ export declare function isEditAllowed(filePath: string): boolean;
17
+ /**
18
+ * Extract the first word of a command as a suggested allowlist prefix.
19
+ */
20
+ export declare function suggestBashPrefix(command: string): string;
21
+ export {};
@@ -0,0 +1,79 @@
1
+ /**
2
+ * Approval persistence — manages ~/.jacq/approvals.json
3
+ *
4
+ * Stores bash command prefix allowlist and edit directory allowlist.
5
+ * Uses atomic writes (write-to-tmp + rename) same as config.ts.
6
+ */
7
+ import fs from 'fs';
8
+ import path from 'path';
9
+ import os from 'os';
10
+ const APPROVALS_DIR = path.join(os.homedir(), '.jacq');
11
+ const APPROVALS_FILE = path.join(APPROVALS_DIR, 'approvals.json');
12
+ const DEFAULT_DATA = {
13
+ bash_allowlist: [],
14
+ edit_allowed_dirs: [],
15
+ };
16
+ export function loadApprovals() {
17
+ try {
18
+ if (fs.existsSync(APPROVALS_FILE)) {
19
+ const content = fs.readFileSync(APPROVALS_FILE, 'utf-8');
20
+ const parsed = JSON.parse(content);
21
+ return {
22
+ bash_allowlist: Array.isArray(parsed.bash_allowlist) ? parsed.bash_allowlist : [],
23
+ edit_allowed_dirs: Array.isArray(parsed.edit_allowed_dirs) ? parsed.edit_allowed_dirs : [],
24
+ };
25
+ }
26
+ }
27
+ catch {
28
+ // Ignore errors, use defaults
29
+ }
30
+ return { ...DEFAULT_DATA };
31
+ }
32
+ export function saveApprovals(data) {
33
+ if (!fs.existsSync(APPROVALS_DIR)) {
34
+ fs.mkdirSync(APPROVALS_DIR, { recursive: true });
35
+ }
36
+ const tmpFile = APPROVALS_FILE + '.tmp';
37
+ fs.writeFileSync(tmpFile, JSON.stringify(data, null, 2) + '\n', 'utf-8');
38
+ fs.renameSync(tmpFile, APPROVALS_FILE);
39
+ }
40
+ export function addBashPrefix(prefix) {
41
+ const data = loadApprovals();
42
+ if (!data.bash_allowlist.includes(prefix)) {
43
+ data.bash_allowlist.push(prefix);
44
+ saveApprovals(data);
45
+ }
46
+ }
47
+ export function addEditDir(dir) {
48
+ const normalized = dir.endsWith('/') ? dir : dir + '/';
49
+ const data = loadApprovals();
50
+ if (!data.edit_allowed_dirs.includes(normalized)) {
51
+ data.edit_allowed_dirs.push(normalized);
52
+ saveApprovals(data);
53
+ }
54
+ }
55
+ export function isBashAllowed(command) {
56
+ const data = loadApprovals();
57
+ // Check that prefix is followed by a space or end-of-string to prevent
58
+ // bypass via shell operators (e.g., "git status && malicious_cmd")
59
+ return data.bash_allowlist.some(prefix => {
60
+ if (!command.startsWith(prefix))
61
+ return false;
62
+ const nextChar = command[prefix.length];
63
+ return nextChar === undefined || nextChar === ' ';
64
+ });
65
+ }
66
+ export function isEditAllowed(filePath) {
67
+ const resolved = path.resolve(filePath);
68
+ const data = loadApprovals();
69
+ return data.edit_allowed_dirs.some(dir => resolved.startsWith(dir));
70
+ }
71
+ /**
72
+ * Extract the first word of a command as a suggested allowlist prefix.
73
+ */
74
+ export function suggestBashPrefix(command) {
75
+ const trimmed = command.trimStart();
76
+ const firstWord = trimmed.split(/\s+/)[0] || trimmed;
77
+ return firstWord;
78
+ }
79
+ //# sourceMappingURL=approvals.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"approvals.js","sourceRoot":"","sources":["../src/approvals.ts"],"names":[],"mappings":"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"}
package/dist/auth.d.ts CHANGED
@@ -5,6 +5,7 @@ interface LoginResult {
5
5
  success: boolean;
6
6
  error?: string;
7
7
  alreadyLoggedIn?: boolean;
8
+ denied?: boolean;
8
9
  name?: string;
9
10
  }
10
11
  export declare function loginFromTUI(onProgress: (msg: string) => void): Promise<LoginResult>;
package/dist/auth.js CHANGED
@@ -104,6 +104,9 @@ export async function loginFromTUI(onProgress) {
104
104
  if (pollRes.status === 410 || pollRes.data.status === 'expired') {
105
105
  return { success: false, error: 'Device code expired. Try again.' };
106
106
  }
107
+ if (pollRes.data.status === 'denied') {
108
+ return { success: false, error: 'Unauthorized', denied: true };
109
+ }
107
110
  onProgress('Waiting for approval...');
108
111
  }
109
112
  catch {
package/dist/auth.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"auth.js","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"auth.js","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,11 @@
1
1
  /**
2
2
  * Character display width helpers for terminal rendering.
3
+ * Uses `string-width` which correctly handles East Asian Width,
4
+ * Emoji_Presentation, combining marks, ZWJ sequences, etc.
3
5
  */
6
+ /** Return the display width (in terminal columns) of a single code point. */
4
7
  export declare function codePointWidth(cp: number): number;
8
+ /** Return the display width (in terminal columns) of a string. */
9
+ export declare function displayWidth(text: string): number;
10
+ /** Truncate or pad `text` to exactly `targetWidth` display columns. */
11
+ export declare function fitToDisplayWidth(text: string, targetWidth: number): string;
package/dist/charWidth.js CHANGED
@@ -1,26 +1,31 @@
1
1
  /**
2
2
  * Character display width helpers for terminal rendering.
3
+ * Uses `string-width` which correctly handles East Asian Width,
4
+ * Emoji_Presentation, combining marks, ZWJ sequences, etc.
3
5
  */
4
- function isCombiningMark(cp) {
5
- return ((cp >= 0x0300 && cp <= 0x036f) ||
6
- (cp >= 0x1ab0 && cp <= 0x1aff) ||
7
- (cp >= 0x1dc0 && cp <= 0x1dff) ||
8
- (cp >= 0x20d0 && cp <= 0x20ff) ||
9
- (cp >= 0xfe20 && cp <= 0xfe2f));
6
+ import stringWidth from 'string-width';
7
+ /** Return the display width (in terminal columns) of a single code point. */
8
+ export function codePointWidth(cp) {
9
+ return stringWidth(String.fromCodePoint(cp));
10
10
  }
11
- function isWideCodePoint(cp) {
12
- return ((cp >= 0x1100 && cp <= 0x115f) ||
13
- (cp >= 0x2e80 && cp <= 0xa4cf) ||
14
- (cp >= 0xac00 && cp <= 0xd7a3) ||
15
- (cp >= 0xf900 && cp <= 0xfaff) ||
16
- (cp >= 0xfe10 && cp <= 0xfe6f) ||
17
- (cp >= 0xff01 && cp <= 0xff60) ||
18
- (cp >= 0xffe0 && cp <= 0xffe6) ||
19
- (cp >= 0x1f300 && cp <= 0x1faff));
11
+ /** Return the display width (in terminal columns) of a string. */
12
+ export function displayWidth(text) {
13
+ return stringWidth(text);
20
14
  }
21
- export function codePointWidth(cp) {
22
- if (cp === 0x200d || cp === 0xfe0f || isCombiningMark(cp))
23
- return 0;
24
- return isWideCodePoint(cp) ? 2 : 1;
15
+ /** Truncate or pad `text` to exactly `targetWidth` display columns. */
16
+ export function fitToDisplayWidth(text, targetWidth) {
17
+ let out = '';
18
+ let used = 0;
19
+ for (const ch of text) {
20
+ const w = codePointWidth(ch.codePointAt(0));
21
+ if (used + w > targetWidth)
22
+ break;
23
+ out += ch;
24
+ used += w;
25
+ }
26
+ if (used < targetWidth) {
27
+ out += ' '.repeat(targetWidth - used);
28
+ }
29
+ return out;
25
30
  }
26
31
  //# sourceMappingURL=charWidth.js.map