@raidiant/notifai 9.2.2 → 9.3.0
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/CHANGELOG.md +19 -0
- package/README.md +8 -5
- package/dist/claude-wake.js +11 -0
- package/dist/claude-wake.js.map +1 -1
- package/dist/codex-wake.js +9 -0
- package/dist/codex-wake.js.map +1 -1
- package/dist/commands-core.d.ts +0 -3
- package/dist/commands-core.js.map +1 -1
- package/dist/commands-doctor.js +41 -2
- package/dist/commands-doctor.js.map +1 -1
- package/dist/commands-hook-shape.d.ts +4 -3
- package/dist/commands-hook-shape.js +19 -10
- package/dist/commands-hook-shape.js.map +1 -1
- package/dist/commands-hooks.js +64 -13
- package/dist/commands-hooks.js.map +1 -1
- package/dist/commands-init.js +12 -1
- package/dist/commands-init.js.map +1 -1
- package/dist/commands-project.d.ts +4 -0
- package/dist/commands-project.js +41 -0
- package/dist/commands-project.js.map +1 -0
- package/dist/commands-send-support.js +1 -22
- package/dist/commands-send-support.js.map +1 -1
- package/dist/commands-send.js +10 -4
- package/dist/commands-send.js.map +1 -1
- package/dist/commands-skill.js +58 -0
- package/dist/commands-skill.js.map +1 -1
- package/dist/commands.d.ts +1 -0
- package/dist/commands.js +1 -0
- package/dist/commands.js.map +1 -1
- package/dist/config-schema.js +2 -2
- package/dist/config-schema.js.map +1 -1
- package/dist/config.d.ts +3 -3
- package/dist/config.js +4 -7
- package/dist/config.js.map +1 -1
- package/dist/guidance-content.d.ts +3 -0
- package/dist/guidance-content.js +20 -0
- package/dist/guidance-content.js.map +1 -1
- package/dist/guidance-render.js +3 -3
- package/dist/guidance-render.js.map +1 -1
- package/dist/harnesses.js +2 -2
- package/dist/harnesses.js.map +1 -1
- package/dist/hooks.d.ts +26 -50
- package/dist/hooks.js +391 -150
- package/dist/hooks.js.map +1 -1
- package/dist/install-hooks.d.ts +7 -28
- package/dist/install-hooks.js +18 -37
- package/dist/install-hooks.js.map +1 -1
- package/dist/program.d.ts +4 -1
- package/dist/program.js +19 -1
- package/dist/program.js.map +1 -1
- package/dist/project-enablement.d.ts +15 -0
- package/dist/project-enablement.js +87 -0
- package/dist/project-enablement.js.map +1 -0
- package/dist/question-timing.d.ts +46 -0
- package/dist/question-timing.js +48 -0
- package/dist/question-timing.js.map +1 -0
- package/dist/readiness.d.ts +7 -0
- package/dist/readiness.js.map +1 -1
- package/dist/send.d.ts +2 -0
- package/dist/send.js +6 -1
- package/dist/send.js.map +1 -1
- package/dist/session-activation.d.ts +1 -1
- package/dist/session-activation.js +3 -4
- package/dist/session-activation.js.map +1 -1
- package/package.json +2 -2
- package/src/claude-wake.test.ts +1 -0
- package/src/claude-wake.ts +10 -0
- package/src/codex-wake.test.ts +1 -0
- package/src/codex-wake.ts +9 -0
- package/src/commands-core.ts +0 -3
- package/src/commands-doctor.ts +48 -4
- package/src/commands-hook-shape.ts +26 -10
- package/src/commands-hooks.ts +59 -13
- package/src/commands-init.ts +11 -1
- package/src/commands-project.ts +47 -0
- package/src/commands-send-support.ts +1 -27
- package/src/commands-send.ts +8 -3
- package/src/commands-skill.test.ts +44 -0
- package/src/commands-skill.ts +57 -0
- package/src/commands.test.ts +47 -17
- package/src/commands.ts +5 -0
- package/src/config-schema.ts +2 -2
- package/src/config.test.ts +2 -3
- package/src/config.ts +7 -10
- package/src/guidance-content.ts +22 -0
- package/src/guidance-render.ts +3 -3
- package/src/harnesses.ts +2 -2
- package/src/hook-adapter.test.ts +27 -8
- package/src/hooks.test.ts +808 -80
- package/src/hooks.ts +525 -181
- package/src/install-hooks.test.ts +8 -12
- package/src/install-hooks.ts +21 -37
- package/src/program.test.ts +18 -0
- package/src/program.ts +22 -0
- package/src/project-enablement.test.ts +55 -0
- package/src/project-enablement.ts +99 -0
- package/src/question-timing.ts +56 -0
- package/src/readiness.ts +8 -1
- package/src/send.ts +8 -1
- package/src/session-activation.ts +3 -4
- package/dist/orca-session-title.d.ts +0 -10
- package/dist/orca-session-title.js +0 -99
- package/dist/orca-session-title.js.map +0 -1
- package/src/orca-session-title.test.ts +0 -95
- package/src/orca-session-title.ts +0 -105
|
@@ -1,95 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from 'vitest'
|
|
2
|
-
import { readOrcaSessionTitle, type OrcaCommand } from './orca-session-title.js'
|
|
3
|
-
|
|
4
|
-
const worktreeId = 'repo-123::/worktrees/semantic-session-implementation'
|
|
5
|
-
|
|
6
|
-
function response(overrides: Record<string, unknown> = {}): string {
|
|
7
|
-
return JSON.stringify({
|
|
8
|
-
ok: true,
|
|
9
|
-
result: {
|
|
10
|
-
worktree: {
|
|
11
|
-
id: worktreeId,
|
|
12
|
-
path: '/worktrees/semantic-session-implementation',
|
|
13
|
-
displayName: 'Worker - semantic session implementation',
|
|
14
|
-
...overrides,
|
|
15
|
-
},
|
|
16
|
-
},
|
|
17
|
-
})
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
describe('Orca semantic session title', () => {
|
|
21
|
-
it('accepts only the display name returned for the exact managed worktree', () => {
|
|
22
|
-
const calls: { executable: string; args: readonly string[] }[] = []
|
|
23
|
-
const command: OrcaCommand = (executable, args) => {
|
|
24
|
-
calls.push({ executable, args })
|
|
25
|
-
return response()
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
expect(
|
|
29
|
-
readOrcaSessionTitle(
|
|
30
|
-
{ TERM_PROGRAM: 'Orca', ORCA_WORKTREE_ID: worktreeId },
|
|
31
|
-
command,
|
|
32
|
-
),
|
|
33
|
-
).toBe('Worker - semantic session implementation')
|
|
34
|
-
expect(calls).toEqual([
|
|
35
|
-
{
|
|
36
|
-
executable: 'orca',
|
|
37
|
-
args: ['worktree', 'show', '--worktree', `id:${worktreeId}`, '--json'],
|
|
38
|
-
},
|
|
39
|
-
])
|
|
40
|
-
})
|
|
41
|
-
|
|
42
|
-
it('uses Orca-provided executable selection without invoking a shell', () => {
|
|
43
|
-
const calls: string[] = []
|
|
44
|
-
expect(
|
|
45
|
-
readOrcaSessionTitle(
|
|
46
|
-
{
|
|
47
|
-
TERM_PROGRAM: 'Orca',
|
|
48
|
-
ORCA_WORKTREE_ID: worktreeId,
|
|
49
|
-
ORCA_CLI_COMMAND: '/mnt/c/Program Files/Orca/orca.exe',
|
|
50
|
-
},
|
|
51
|
-
(executable) => {
|
|
52
|
-
calls.push(executable)
|
|
53
|
-
return response()
|
|
54
|
-
},
|
|
55
|
-
),
|
|
56
|
-
).toBe('Worker - semantic session implementation')
|
|
57
|
-
expect(calls).toEqual(['/mnt/c/Program Files/Orca/orca.exe'])
|
|
58
|
-
})
|
|
59
|
-
|
|
60
|
-
it('ignores non-Orca and malformed selectors without running a command', () => {
|
|
61
|
-
const command: OrcaCommand = () => {
|
|
62
|
-
throw new Error('must not run')
|
|
63
|
-
}
|
|
64
|
-
expect(readOrcaSessionTitle({ ORCA_WORKTREE_ID: worktreeId }, command)).toBeUndefined()
|
|
65
|
-
expect(
|
|
66
|
-
readOrcaSessionTitle(
|
|
67
|
-
{ TERM_PROGRAM: 'Orca', ORCA_WORKTREE_ID: '/private/untrusted' },
|
|
68
|
-
command,
|
|
69
|
-
),
|
|
70
|
-
).toBeUndefined()
|
|
71
|
-
expect(
|
|
72
|
-
readOrcaSessionTitle(
|
|
73
|
-
{ TERM_PROGRAM: 'Orca', ORCA_WORKTREE_ID: 'repo-123::relative/path' },
|
|
74
|
-
command,
|
|
75
|
-
),
|
|
76
|
-
).toBeUndefined()
|
|
77
|
-
})
|
|
78
|
-
|
|
79
|
-
it.each([
|
|
80
|
-
['command failure', () => null],
|
|
81
|
-
['thrown command failure', () => { throw new Error('offline') }],
|
|
82
|
-
['malformed JSON', () => '{not json}'],
|
|
83
|
-
['failed response', () => JSON.stringify({ ok: false })],
|
|
84
|
-
['different worktree id', () => response({ id: 'repo-123::/worktrees/other' })],
|
|
85
|
-
['different worktree path', () => response({ path: '/private/untrusted' })],
|
|
86
|
-
['blank display name', () => response({ displayName: ' ' })],
|
|
87
|
-
])('fails closed for %s', (_name, command) => {
|
|
88
|
-
expect(
|
|
89
|
-
readOrcaSessionTitle(
|
|
90
|
-
{ TERM_PROGRAM: 'Orca', ORCA_WORKTREE_ID: worktreeId },
|
|
91
|
-
command,
|
|
92
|
-
),
|
|
93
|
-
).toBeUndefined()
|
|
94
|
-
})
|
|
95
|
-
})
|
|
@@ -1,105 +0,0 @@
|
|
|
1
|
-
import { execFileSync } from 'node:child_process'
|
|
2
|
-
import path from 'node:path'
|
|
3
|
-
|
|
4
|
-
export type OrcaSessionTitleLookup = (env: NodeJS.ProcessEnv) => string | undefined
|
|
5
|
-
export type OrcaCommand = (executable: string, args: readonly string[]) => string | null
|
|
6
|
-
|
|
7
|
-
const runOrcaCommand: OrcaCommand = (executable, args) => {
|
|
8
|
-
try {
|
|
9
|
-
return execFileSync(executable, args, {
|
|
10
|
-
encoding: 'utf8',
|
|
11
|
-
stdio: ['ignore', 'pipe', 'ignore'],
|
|
12
|
-
timeout: 2_000,
|
|
13
|
-
maxBuffer: 512 * 1024,
|
|
14
|
-
windowsHide: true,
|
|
15
|
-
}).trim()
|
|
16
|
-
} catch {
|
|
17
|
-
return null
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
function containsControlCharacter(value: string): boolean {
|
|
22
|
-
return Array.from(value).some((character) => {
|
|
23
|
-
const codePoint = character.codePointAt(0) ?? 0
|
|
24
|
-
return codePoint < 32 || codePoint === 127
|
|
25
|
-
})
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
function worktreePathFromId(value: string): string | null {
|
|
29
|
-
if (value.length === 0 || value.length > 4_096 || containsControlCharacter(value)) {
|
|
30
|
-
return null
|
|
31
|
-
}
|
|
32
|
-
const separator = value.indexOf('::')
|
|
33
|
-
if (separator <= 0) return null
|
|
34
|
-
const repoId = value.slice(0, separator)
|
|
35
|
-
const worktreePath = value.slice(separator + 2)
|
|
36
|
-
if (!/^[A-Za-z0-9._-]+$/u.test(repoId) || worktreePath.length === 0) return null
|
|
37
|
-
return path.posix.isAbsolute(worktreePath) || path.win32.isAbsolute(worktreePath)
|
|
38
|
-
? worktreePath
|
|
39
|
-
: null
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
function orcaExecutable(env: NodeJS.ProcessEnv): string | null {
|
|
43
|
-
const configured = env['ORCA_CLI_COMMAND']?.trim()
|
|
44
|
-
if (configured !== undefined && configured.length > 0) {
|
|
45
|
-
return containsControlCharacter(configured) ? null : configured
|
|
46
|
-
}
|
|
47
|
-
return env['ORCA_DEV_REPO_ROOT'] === undefined ? 'orca' : 'orca-dev'
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
/**
|
|
51
|
-
* Read the semantic display name assigned to this exact Orca worktree.
|
|
52
|
-
*
|
|
53
|
-
* The environment contributes only an opaque selector. Orca must return that
|
|
54
|
-
* exact id and its matching path before its display name becomes trusted; no
|
|
55
|
-
* path component or identifier is ever promoted into the User-visible label.
|
|
56
|
-
*/
|
|
57
|
-
export function readOrcaSessionTitle(
|
|
58
|
-
env: NodeJS.ProcessEnv,
|
|
59
|
-
command: OrcaCommand = runOrcaCommand,
|
|
60
|
-
): string | undefined {
|
|
61
|
-
if (env['TERM_PROGRAM'] !== 'Orca') return undefined
|
|
62
|
-
const worktreeId = env['ORCA_WORKTREE_ID']
|
|
63
|
-
if (worktreeId === undefined) return undefined
|
|
64
|
-
const expectedPath = worktreePathFromId(worktreeId)
|
|
65
|
-
if (expectedPath === null) return undefined
|
|
66
|
-
const executable = orcaExecutable(env)
|
|
67
|
-
if (executable === null) return undefined
|
|
68
|
-
|
|
69
|
-
let output: string | null
|
|
70
|
-
try {
|
|
71
|
-
output = command(executable, [
|
|
72
|
-
'worktree',
|
|
73
|
-
'show',
|
|
74
|
-
'--worktree',
|
|
75
|
-
`id:${worktreeId}`,
|
|
76
|
-
'--json',
|
|
77
|
-
])
|
|
78
|
-
} catch {
|
|
79
|
-
return undefined
|
|
80
|
-
}
|
|
81
|
-
if (output === null || output === '') return undefined
|
|
82
|
-
|
|
83
|
-
let parsed: unknown
|
|
84
|
-
try {
|
|
85
|
-
parsed = JSON.parse(output)
|
|
86
|
-
} catch {
|
|
87
|
-
return undefined
|
|
88
|
-
}
|
|
89
|
-
if (typeof parsed !== 'object' || parsed === null) return undefined
|
|
90
|
-
const response = parsed as {
|
|
91
|
-
ok?: unknown
|
|
92
|
-
result?: { worktree?: { id?: unknown; path?: unknown; displayName?: unknown } }
|
|
93
|
-
}
|
|
94
|
-
const worktree = response.result?.worktree
|
|
95
|
-
if (
|
|
96
|
-
response.ok !== true ||
|
|
97
|
-
worktree?.id !== worktreeId ||
|
|
98
|
-
worktree.path !== expectedPath ||
|
|
99
|
-
typeof worktree.displayName !== 'string' ||
|
|
100
|
-
worktree.displayName.trim().length === 0
|
|
101
|
-
) {
|
|
102
|
-
return undefined
|
|
103
|
-
}
|
|
104
|
-
return worktree.displayName
|
|
105
|
-
}
|