@cmodjs/core 0.3.0 → 1.5.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/docs/commands.md +61 -10
- package/docs/dependencies.md +16 -14
- package/docs/hooks.md +64 -29
- package/docs/index.md +29 -25
- package/docs/install-steps.md +13 -9
- package/docs/jobs.md +59 -111
- package/docs/mod.md +227 -175
- package/docs/options.md +2 -2
- package/docs/permissions.md +27 -16
- package/docs/session.md +311 -0
- package/docs/state.md +11 -7
- package/docs/testing.md +68 -23
- package/docs/ui.md +116 -76
- package/jobs/check.d.ts.map +1 -1
- package/jobs/check.js +5 -2
- package/jobs/context.d.ts +7 -8
- package/jobs/context.d.ts.map +1 -1
- package/jobs/context.js +23 -73
- package/jobs/permissions/decide-permission.d.ts +5 -3
- package/jobs/permissions/decide-permission.d.ts.map +1 -1
- package/jobs/permissions/decide-permission.js +6 -4
- package/jobs/permissions/find-project-scope.d.ts +1 -1
- package/jobs/permissions/find-project-scope.d.ts.map +1 -1
- package/jobs/permissions/find-project-scope.js +8 -11
- package/jobs/permissions/match-target.d.ts +2 -2
- package/jobs/permissions/match-target.d.ts.map +1 -1
- package/jobs/permissions.d.ts +1 -1
- package/jobs/permissions.d.ts.map +1 -1
- package/jobs/permissions.js +6 -4
- package/jobs/program.d.ts.map +1 -1
- package/jobs/program.js +14 -4
- package/jobs/prompt.d.ts +4 -2
- package/jobs/prompt.d.ts.map +1 -1
- package/jobs/prompt.js +16 -15
- package/jobs/schedule.d.ts +2 -2
- package/jobs/schedule.d.ts.map +1 -1
- package/jobs/schedule.js +9 -9
- package/jobs/slash-command.d.ts +4 -4
- package/jobs/slash-command.d.ts.map +1 -1
- package/jobs/slash-command.js +14 -9
- package/jobs/status-line.d.ts +1 -11
- package/jobs/status-line.d.ts.map +1 -1
- package/jobs/status-line.js +8 -12
- package/jobs/tool.d.ts +2 -2
- package/jobs/tool.d.ts.map +1 -1
- package/jobs/tool.js +15 -9
- package/mod.d.ts +178 -75
- package/mod.d.ts.map +1 -1
- package/mod.js +127 -3
- package/options.d.ts +2 -2
- package/options.js +19 -19
- package/package.json +3 -3
- package/records.d.ts +13 -8
- package/records.d.ts.map +1 -1
- package/records.js +33 -17
- package/register.d.ts.map +1 -1
- package/register.js +34 -5
- package/runtime/announce.d.ts +18 -0
- package/runtime/announce.d.ts.map +1 -0
- package/runtime/announce.js +68 -0
- package/runtime/before.d.ts +32 -0
- package/runtime/before.d.ts.map +1 -0
- package/runtime/before.js +214 -0
- package/runtime/bound.d.ts +4 -0
- package/runtime/bound.d.ts.map +1 -0
- package/runtime/bound.js +9 -0
- package/runtime/claude.d.ts +4 -2
- package/runtime/claude.d.ts.map +1 -1
- package/runtime/conversations.d.ts +17 -0
- package/runtime/conversations.d.ts.map +1 -0
- package/runtime/conversations.js +563 -0
- package/runtime/deadline.d.ts +0 -1
- package/runtime/deadline.d.ts.map +1 -1
- package/runtime/deadline.js +1 -1
- package/runtime/dependencies.d.ts +2 -0
- package/runtime/dependencies.d.ts.map +1 -1
- package/runtime/dependencies.js +10 -1
- package/runtime/engine.d.ts +13 -0
- package/runtime/engine.d.ts.map +1 -0
- package/runtime/engine.js +10 -0
- package/runtime/grants.d.ts +4 -0
- package/runtime/grants.d.ts.map +1 -1
- package/runtime/grants.js +68 -31
- package/runtime/hooks.d.ts +5 -4
- package/runtime/hooks.d.ts.map +1 -1
- package/runtime/hooks.js +29 -9
- package/runtime/installer.d.ts +1 -1
- package/runtime/installer.d.ts.map +1 -1
- package/runtime/installer.js +17 -14
- package/runtime/lifecycle.d.ts +3 -1
- package/runtime/lifecycle.d.ts.map +1 -1
- package/runtime/lifecycle.js +414 -212
- package/runtime/metadata.d.ts +3 -1
- package/runtime/metadata.d.ts.map +1 -1
- package/runtime/metadata.js +25 -14
- package/runtime/options.d.ts +3 -1
- package/runtime/options.d.ts.map +1 -1
- package/runtime/options.js +4 -4
- package/runtime/programs.d.ts +8 -0
- package/runtime/programs.d.ts.map +1 -1
- package/runtime/programs.js +39 -1
- package/runtime/router.d.ts +2 -1
- package/runtime/router.d.ts.map +1 -1
- package/runtime/router.js +11 -3
- package/runtime/sessions.d.ts +58 -0
- package/runtime/sessions.d.ts.map +1 -0
- package/runtime/sessions.js +433 -0
- package/runtime/state.d.ts +6 -2
- package/runtime/state.d.ts.map +1 -1
- package/runtime/state.js +46 -13
- package/runtime/toaster.d.ts +24 -0
- package/runtime/toaster.d.ts.map +1 -0
- package/runtime/toaster.js +286 -0
- package/runtime/ui.d.ts +6 -17
- package/runtime/ui.d.ts.map +1 -1
- package/runtime/ui.js +62 -118
- package/session/context/context.d.ts +12 -0
- package/session/context/context.d.ts.map +1 -0
- package/session/context/context.js +2 -0
- package/session/context/turn/message/document.d.ts +7 -0
- package/session/context/turn/message/document.d.ts.map +1 -0
- package/session/context/turn/message/document.js +1 -0
- package/session/context/turn/message/message.d.ts +55 -0
- package/session/context/turn/message/message.d.ts.map +1 -0
- package/session/context/turn/message/message.js +178 -0
- package/session/context/turn/message/note.d.ts +8 -0
- package/session/context/turn/message/note.d.ts.map +1 -0
- package/session/context/turn/message/note.js +1 -0
- package/session/context/turn/message/notice.d.ts +6 -0
- package/session/context/turn/message/notice.d.ts.map +1 -0
- package/session/context/turn/message/notice.js +1 -0
- package/session/context/turn/message/prompt.d.ts +8 -0
- package/session/context/turn/message/prompt.d.ts.map +1 -0
- package/session/context/turn/message/prompt.js +1 -0
- package/session/context/turn/message/reply.d.ts +6 -0
- package/session/context/turn/message/reply.d.ts.map +1 -0
- package/session/context/turn/message/reply.js +1 -0
- package/session/context/turn/message/sender.d.ts +14 -0
- package/session/context/turn/message/sender.d.ts.map +1 -0
- package/session/context/turn/message/sender.js +30 -0
- package/session/context/turn/message/skill.d.ts +7 -0
- package/session/context/turn/message/skill.d.ts.map +1 -0
- package/session/context/turn/message/skill.js +1 -0
- package/session/context/turn/message/tool-call.d.ts +9 -0
- package/session/context/turn/message/tool-call.d.ts.map +1 -0
- package/session/context/turn/message/tool-call.js +1 -0
- package/session/context/turn/message/tool-result.d.ts +8 -0
- package/session/context/turn/message/tool-result.d.ts.map +1 -0
- package/session/context/turn/message/tool-result.js +1 -0
- package/session/context/turn/turn.d.ts +13 -0
- package/session/context/turn/turn.d.ts.map +1 -0
- package/session/context/turn/turn.js +2 -0
- package/session/conversation.d.ts +73 -0
- package/session/conversation.d.ts.map +1 -0
- package/session/conversation.js +146 -0
- package/session/goal/goal.d.ts +11 -0
- package/session/goal/goal.d.ts.map +1 -0
- package/session/goal/goal.js +1 -0
- package/session/goal/task.d.ts +16 -0
- package/session/goal/task.d.ts.map +1 -0
- package/session/goal/task.js +3 -0
- package/session/session.d.ts +158 -0
- package/session/session.d.ts.map +1 -0
- package/session/session.js +2 -0
- package/src/jobs/check.ts +7 -4
- package/src/jobs/context.ts +24 -82
- package/src/jobs/permissions/decide-permission.ts +10 -8
- package/src/jobs/permissions/find-project-scope.ts +8 -14
- package/src/jobs/permissions/match-target.ts +3 -3
- package/src/jobs/permissions.ts +8 -6
- package/src/jobs/program.ts +13 -4
- package/src/jobs/prompt.ts +21 -24
- package/src/jobs/schedule.ts +14 -14
- package/src/jobs/slash-command.ts +20 -14
- package/src/jobs/status-line.ts +9 -21
- package/src/jobs/tool.ts +17 -11
- package/src/mod.ts +252 -97
- package/src/options.ts +22 -22
- package/src/records.ts +40 -23
- package/src/register.ts +34 -5
- package/src/runtime/announce.ts +76 -0
- package/src/runtime/before.ts +200 -0
- package/src/runtime/bound.ts +12 -0
- package/src/runtime/claude.ts +7 -2
- package/src/runtime/conversations.ts +579 -0
- package/src/runtime/deadline.ts +2 -2
- package/src/runtime/dependencies.ts +13 -1
- package/src/runtime/engine.ts +23 -0
- package/src/runtime/grants.ts +69 -29
- package/src/runtime/hooks.ts +39 -14
- package/src/runtime/installer.ts +16 -14
- package/src/runtime/lifecycle.ts +413 -201
- package/src/runtime/metadata.ts +37 -14
- package/src/runtime/options.ts +19 -4
- package/src/runtime/programs.ts +40 -1
- package/src/runtime/router.ts +11 -4
- package/src/runtime/sessions.ts +447 -0
- package/src/runtime/state.ts +50 -14
- package/src/runtime/toaster.ts +334 -0
- package/src/runtime/ui.ts +65 -143
- package/src/session/context/context.ts +14 -0
- package/src/session/context/turn/message/document.ts +8 -0
- package/src/session/context/turn/message/message.ts +203 -0
- package/src/session/context/turn/message/note.ts +9 -0
- package/src/session/context/turn/message/notice.ts +7 -0
- package/src/session/context/turn/message/prompt.ts +9 -0
- package/src/session/context/turn/message/reply.ts +7 -0
- package/src/session/context/turn/message/sender.ts +38 -0
- package/src/session/context/turn/message/skill.ts +8 -0
- package/src/session/context/turn/message/tool-call.ts +10 -0
- package/src/session/context/turn/message/tool-result.ts +9 -0
- package/src/session/context/turn/turn.ts +15 -0
- package/src/session/conversation.ts +194 -0
- package/src/session/goal/goal.ts +10 -0
- package/src/session/goal/task.ts +19 -0
- package/src/session/session.ts +141 -0
- package/src/testing/fake-claude.ts +25 -17
- package/src/testing/fake-elements.ts +3 -2
- package/src/testing/fake-files.ts +1 -1
- package/src/testing/fake-sessions.ts +277 -0
- package/src/testing.ts +138 -35
- package/src/ui/components.ts +3 -3
- package/src/ui/elements.ts +22 -8
- package/src/ui/markdown.ts +22 -26
- package/src/ui/places.ts +49 -0
- package/src/utils/call-effects.ts +5 -5
- package/src/utils/changelog.ts +32 -0
- package/src/utils/disposable.ts +3 -0
- package/src/utils/matcher.ts +37 -0
- package/src/utils/metadata.ts +17 -15
- package/src/utils/parse-shell.ts +9 -8
- package/src/utils/paths.ts +21 -4
- package/src/utils/text.ts +4 -0
- package/testing/fake-claude.d.ts +5 -1
- package/testing/fake-claude.d.ts.map +1 -1
- package/testing/fake-claude.js +21 -12
- package/testing/fake-elements.js +4 -2
- package/testing/fake-files.js +1 -1
- package/testing/fake-sessions.d.ts +81 -0
- package/testing/fake-sessions.d.ts.map +1 -0
- package/testing/fake-sessions.js +249 -0
- package/testing.d.ts +34 -13
- package/testing.d.ts.map +1 -1
- package/testing.js +115 -23
- package/ui/components.d.ts +2 -3
- package/ui/components.d.ts.map +1 -1
- package/ui/components.js +3 -3
- package/ui/elements.d.ts.map +1 -1
- package/ui/elements.js +19 -9
- package/ui/markdown.d.ts +35 -33
- package/ui/markdown.d.ts.map +1 -1
- package/ui/markdown.js +14 -16
- package/ui/places.d.ts +43 -0
- package/ui/places.d.ts.map +1 -0
- package/ui/places.js +31 -0
- package/utils/call-effects.d.ts +2 -1
- package/utils/call-effects.d.ts.map +1 -1
- package/utils/call-effects.js +3 -3
- package/utils/changelog.d.ts +9 -0
- package/utils/changelog.d.ts.map +1 -0
- package/utils/changelog.js +29 -0
- package/utils/disposable.d.ts +4 -0
- package/utils/disposable.d.ts.map +1 -0
- package/utils/disposable.js +1 -0
- package/utils/matcher.d.ts +13 -0
- package/utils/matcher.d.ts.map +1 -0
- package/utils/matcher.js +32 -0
- package/utils/metadata.d.ts +3 -3
- package/utils/metadata.js +18 -14
- package/utils/parse-shell.js +9 -7
- package/utils/paths.d.ts +4 -1
- package/utils/paths.d.ts.map +1 -1
- package/utils/paths.js +19 -4
- package/utils/text.d.ts +1 -0
- package/utils/text.d.ts.map +1 -1
- package/utils/text.js +3 -0
- package/src/ui/slots.ts +0 -36
- package/ui/slots.d.ts +0 -208
- package/ui/slots.d.ts.map +0 -1
- package/ui/slots.js +0 -19
package/src/utils/metadata.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export type MetadataFormat = { readonly
|
|
1
|
+
export type MetadataFormat = { readonly type: 'frontmatter' } | { readonly type: 'comment'; readonly prefix: string } | { readonly type: 'sidecar' }
|
|
2
2
|
|
|
3
3
|
export type ReadMetadata = {
|
|
4
4
|
readonly metadata: Readonly<Record<string, string>>
|
|
@@ -26,12 +26,12 @@ export function formatOf(path: string, firstLine: string | undefined): MetadataF
|
|
|
26
26
|
const name = path.slice(path.lastIndexOf('/') + 1)
|
|
27
27
|
const dot = name.lastIndexOf('.')
|
|
28
28
|
const extension = dot <= 0 ? '' : name.slice(dot + 1).toLowerCase()
|
|
29
|
-
if (markdown.includes(extension)) return {
|
|
30
|
-
if (hashComments.includes(extension) || hashCommentNames.includes(name)) return {
|
|
31
|
-
if (slashComments.includes(extension)) return {
|
|
32
|
-
if (dashComments.includes(extension)) return {
|
|
33
|
-
if (extension === '' && firstLine?.startsWith('#!') === true) return {
|
|
34
|
-
return {
|
|
29
|
+
if (markdown.includes(extension)) return { type: 'frontmatter' }
|
|
30
|
+
if (hashComments.includes(extension) || hashCommentNames.includes(name)) return { type: 'comment', prefix: '#' }
|
|
31
|
+
if (slashComments.includes(extension)) return { type: 'comment', prefix: '//' }
|
|
32
|
+
if (dashComments.includes(extension)) return { type: 'comment', prefix: '--' }
|
|
33
|
+
if (extension === '' && firstLine?.startsWith('#!') === true) return { type: 'comment', prefix: '#' }
|
|
34
|
+
return { type: 'sidecar' }
|
|
35
35
|
}
|
|
36
36
|
|
|
37
37
|
type Region = { readonly start: number; readonly end: number; readonly lines: readonly string[] }
|
|
@@ -42,21 +42,21 @@ type Block = { readonly start: number; readonly end: number; readonly entries: r
|
|
|
42
42
|
|
|
43
43
|
export function readMetadata(text: string, format: MetadataFormat): ReadMetadata {
|
|
44
44
|
const lines = text.split('\n')
|
|
45
|
-
if (format.
|
|
45
|
+
if (format.type === 'comment') {
|
|
46
46
|
const region = commentRegion(lines, format.prefix)
|
|
47
47
|
return { metadata: region === undefined ? {} : asRecord(mapEntries(region.lines, region.start + 2, 0)) }
|
|
48
48
|
}
|
|
49
|
-
const region = format.
|
|
49
|
+
const region = format.type === 'frontmatter' ? frontmatterRegion(lines) : { start: -1, end: lines.length, lines }
|
|
50
50
|
if (region === undefined) return { metadata: {} }
|
|
51
51
|
const block = metadataBlock(region)
|
|
52
|
-
const name = format.
|
|
52
|
+
const name = format.type === 'frontmatter' ? topLevelScalar(region, 'name') : undefined
|
|
53
53
|
return { metadata: block === undefined ? {} : asRecord(block.entries), ...(name === undefined ? {} : { name }) }
|
|
54
54
|
}
|
|
55
55
|
|
|
56
56
|
export function writeMetadata(text: string, format: MetadataFormat, metadata: Readonly<Record<string, string>>): string {
|
|
57
57
|
const lines = text.split('\n')
|
|
58
58
|
const entries = Object.entries(metadata)
|
|
59
|
-
if (format.
|
|
59
|
+
if (format.type === 'comment') {
|
|
60
60
|
const { prefix } = format
|
|
61
61
|
const block = entries.length === 0 ? [] : [`${prefix} /// metadata`, ...entries.map(([key, value]) => `${prefix} ${scalar(key)}: ${scalar(value)}`), `${prefix} ///`]
|
|
62
62
|
const region = commentRegion(lines, prefix)
|
|
@@ -66,7 +66,7 @@ export function writeMetadata(text: string, format: MetadataFormat, metadata: Re
|
|
|
66
66
|
return [...lines.slice(0, at), ...block, ...lines.slice(at)].join('\n')
|
|
67
67
|
}
|
|
68
68
|
const map = entries.length === 0 ? [] : ['metadata:', ...entries.map(([key, value]) => ` ${scalar(key)}: ${scalar(value)}`)]
|
|
69
|
-
if (format.
|
|
69
|
+
if (format.type === 'sidecar') {
|
|
70
70
|
const block = metadataBlock({ start: -1, end: lines.length, lines })
|
|
71
71
|
const rest = block === undefined ? lines : [...lines.slice(0, block.start), ...lines.slice(block.end)]
|
|
72
72
|
const kept = rest.join('\n').trim()
|
|
@@ -206,7 +206,8 @@ function unquoted(text: string, lineNumber: number): string {
|
|
|
206
206
|
if (!text.endsWith('"') || text.length < 2) throw new MetadataError(lineNumber, `${text} opens a double quote that never closes.`)
|
|
207
207
|
try {
|
|
208
208
|
return JSON.parse(text) as string
|
|
209
|
-
} catch {
|
|
209
|
+
} catch (error) {
|
|
210
|
+
if (!(error instanceof SyntaxError)) throw error
|
|
210
211
|
throw new MetadataError(lineNumber, `${text} is not a double-quoted text. Escape a " inside it as \\".`)
|
|
211
212
|
}
|
|
212
213
|
}
|
|
@@ -224,8 +225,9 @@ function topLevelScalar(region: Region, key: string): string | undefined {
|
|
|
224
225
|
if (text === '') return undefined
|
|
225
226
|
try {
|
|
226
227
|
return unquoted(text, region.start + 2 + at)
|
|
227
|
-
} catch {
|
|
228
|
-
return undefined
|
|
228
|
+
} catch (error) {
|
|
229
|
+
if (error instanceof MetadataError) return undefined
|
|
230
|
+
throw error
|
|
229
231
|
}
|
|
230
232
|
}
|
|
231
233
|
|
package/src/utils/parse-shell.ts
CHANGED
|
@@ -18,7 +18,7 @@ type Scan = { text: string; markers: Marker[]; end: number }
|
|
|
18
18
|
type Redirect = { operator: string; target: Word }
|
|
19
19
|
type Pipe = { writer: number | undefined }
|
|
20
20
|
type Command = { words: Word[]; redirects: Redirect[]; pipe: Pipe | undefined }
|
|
21
|
-
type Stdin = {
|
|
21
|
+
type Stdin = { type: 'text'; text: string } | { type: 'pipe' }
|
|
22
22
|
type Access = 'reads' | 'writes'
|
|
23
23
|
type OptionSpec = { valued?: string; optional?: string; longValued?: readonly string[] }
|
|
24
24
|
type Option = { name: string; value: Word | undefined }
|
|
@@ -211,7 +211,8 @@ function parseLine(line: string, folder: string, result: ParsedShell): void {
|
|
|
211
211
|
try {
|
|
212
212
|
const { text, markers } = scan(line, 0, false)
|
|
213
213
|
walk(parse(text, (name) => (name === '' ? undefined : `$${name}`)), markers, folder, result)
|
|
214
|
-
} catch {
|
|
214
|
+
} catch (error) {
|
|
215
|
+
if (!(error instanceof SyntaxError) && !(error instanceof Error && error.message.startsWith('Bad substitution: '))) throw error
|
|
215
216
|
result.isFullyParsed = false
|
|
216
217
|
}
|
|
217
218
|
}
|
|
@@ -546,7 +547,7 @@ function finish(command: Command, operator: string, folder: string, result: Pars
|
|
|
546
547
|
const [first, ...args] = words
|
|
547
548
|
if (first === undefined || first.text === 'for' || first.text === 'select') return folder
|
|
548
549
|
const here = command.redirects.findLast((redirect) => redirect.operator === '<<<')
|
|
549
|
-
const stdin: Stdin | undefined = here !== undefined ? {
|
|
550
|
+
const stdin: Stdin | undefined = here !== undefined ? { type: 'text', text: here.target.text } : command.pipe !== undefined ? { type: 'pipe' } : undefined
|
|
550
551
|
const reader = result.commands.length
|
|
551
552
|
const changed = addCommand(first, args, folder, stdin, result)
|
|
552
553
|
const read = result.commands[reader]
|
|
@@ -629,7 +630,7 @@ function findStarts(args: Word[]): Word[] {
|
|
|
629
630
|
|
|
630
631
|
function addWrapper(first: Word, program: string, args: Word[], folder: string, stdin: Stdin | undefined, result: ParsedShell): void {
|
|
631
632
|
const wrapper = wrappers.get(program)!
|
|
632
|
-
if (program === 'xargs' && stdin?.
|
|
633
|
+
if (program === 'xargs' && stdin?.type !== 'text') result.isFullyParsed = false
|
|
633
634
|
const { options, operands } = readArguments(args, wrapper, true)
|
|
634
635
|
let start = args.length - operands.length
|
|
635
636
|
if (options.some((option) => wrapper.stops?.includes(option.name) === true)) start = args.length
|
|
@@ -669,8 +670,8 @@ function addEffects(program: string, args: Word[], flags: string[], folder: stri
|
|
|
669
670
|
else if (inlineFlags !== undefined) {
|
|
670
671
|
if (program === 'perl' && readArguments(args, perl, false).options.some((option) => option.name === '-i')) addFileArguments(perl, args, folder, result)
|
|
671
672
|
const script = args.find((word) => !word.text.startsWith('-') || word.text === '-')
|
|
672
|
-
const readsCodeFromPipe = stdin?.
|
|
673
|
-
if (flags.some((flag) => inlineFlags.includes(flag)) || stdin?.
|
|
673
|
+
const readsCodeFromPipe = stdin?.type === 'pipe' && (script === undefined || script.text === '-')
|
|
674
|
+
if (flags.some((flag) => inlineFlags.includes(flag)) || stdin?.type === 'text' || readsCodeFromPipe) result.isFullyParsed = false
|
|
674
675
|
}
|
|
675
676
|
}
|
|
676
677
|
|
|
@@ -701,8 +702,8 @@ function addFetches(fetcher: OptionSpec, args: Word[], result: ParsedShell): voi
|
|
|
701
702
|
}
|
|
702
703
|
|
|
703
704
|
function addStdinCode(stdin: Stdin | undefined, folder: string, result: ParsedShell): void {
|
|
704
|
-
if (stdin?.
|
|
705
|
-
if (stdin?.
|
|
705
|
+
if (stdin?.type === 'text') parseLine(stdin.text, folder, result)
|
|
706
|
+
if (stdin?.type === 'pipe') result.isFullyParsed = false
|
|
706
707
|
}
|
|
707
708
|
|
|
708
709
|
function addCopy(program: CopyProgram, args: Word[], folder: string, result: ParsedShell): void {
|
package/src/utils/paths.ts
CHANGED
|
@@ -1,4 +1,18 @@
|
|
|
1
1
|
import { basename, dirname, resolve } from '../vendor.js'
|
|
2
|
+
import { messageOf } from './text.js'
|
|
3
|
+
|
|
4
|
+
const missingPath = /(?:^|: )(?:ENOENT|ENOTDIR)\b/
|
|
5
|
+
|
|
6
|
+
export function isMissing(error: unknown): boolean {
|
|
7
|
+
return missingPath.test(messageOf(error))
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export function ifMissing<Value>(value: Value): (error: unknown) => Value {
|
|
11
|
+
return (error) => {
|
|
12
|
+
if (isMissing(error)) return value
|
|
13
|
+
throw error
|
|
14
|
+
}
|
|
15
|
+
}
|
|
2
16
|
|
|
3
17
|
export type FileSystem = {
|
|
4
18
|
read: (path: string) => Promise<string>
|
|
@@ -6,9 +20,12 @@ export type FileSystem = {
|
|
|
6
20
|
exists: (path: string) => Promise<boolean>
|
|
7
21
|
}
|
|
8
22
|
|
|
9
|
-
export
|
|
10
|
-
|
|
11
|
-
|
|
23
|
+
export const homePrefix = /^(~|\$HOME|\$CLAUDE_CONFIG_DIR)(?=\/|$)/
|
|
24
|
+
|
|
25
|
+
export function expandHome(path: string, home: string, configRoot = `${home}/.claude`): string {
|
|
26
|
+
const prefix = homePrefix.exec(path)?.[0]
|
|
27
|
+
if (prefix === undefined) return path
|
|
28
|
+
return `${prefix === '$CLAUDE_CONFIG_DIR' ? configRoot : home}${path.slice(prefix.length)}`
|
|
12
29
|
}
|
|
13
30
|
|
|
14
31
|
export function relativePath(base: string, path: string): string | undefined {
|
|
@@ -18,7 +35,7 @@ export function relativePath(base: string, path: string): string | undefined {
|
|
|
18
35
|
}
|
|
19
36
|
|
|
20
37
|
export async function realPathOf(path: string, fs: FileSystem): Promise<string | undefined> {
|
|
21
|
-
const stat = await fs.stat(path).catch((
|
|
38
|
+
const stat = await fs.stat(path).catch(ifMissing(undefined))
|
|
22
39
|
if (stat !== undefined || path === '/') return stat?.realPath
|
|
23
40
|
const folder = await realPathOf(dirname(path), fs)
|
|
24
41
|
return folder === undefined ? undefined : resolve(folder, basename(path))
|
package/src/utils/text.ts
CHANGED
|
@@ -3,6 +3,10 @@ export function listed(items: readonly string[]): string {
|
|
|
3
3
|
return `${items.slice(0, -1).join(', ')} and ${items.at(-1)}`
|
|
4
4
|
}
|
|
5
5
|
|
|
6
|
+
export function firstLine(text: string): string {
|
|
7
|
+
return text.split('\n').find((line) => line.trim() !== '')?.trim() ?? ''
|
|
8
|
+
}
|
|
9
|
+
|
|
6
10
|
export function messageOf(error: unknown): string {
|
|
7
11
|
return error instanceof Error ? error.message : String(error)
|
|
8
12
|
}
|
package/testing/fake-claude.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { EventResult } from 'claude-code';
|
|
1
2
|
import type { Claude } from '../runtime/claude.js';
|
|
2
3
|
export type TestCall = {
|
|
3
4
|
readonly call: string;
|
|
@@ -28,10 +29,13 @@ export type Fakes = {
|
|
|
28
29
|
ask?: Claude['ui']['ask'];
|
|
29
30
|
open?: Claude['ui']['open'];
|
|
30
31
|
scroll?: Claude['ui']['scroll'];
|
|
32
|
+
copy?: Claude['ui']['copy'];
|
|
33
|
+
focus?: Claude['ui']['focus'];
|
|
31
34
|
};
|
|
32
35
|
session: {
|
|
33
36
|
messages?: Claude['session']['messages'];
|
|
34
37
|
append?: Claude['session']['append'];
|
|
38
|
+
send?: Claude['session']['send'];
|
|
35
39
|
};
|
|
36
40
|
prompt: {
|
|
37
41
|
submit?: Claude['prompt']['submit'];
|
|
@@ -60,7 +64,6 @@ export type ShownSchedule = {
|
|
|
60
64
|
readonly prompt: string;
|
|
61
65
|
};
|
|
62
66
|
export type Shown = {
|
|
63
|
-
readonly toasts: string[];
|
|
64
67
|
readonly notes: string[];
|
|
65
68
|
readonly prompts: string[];
|
|
66
69
|
readonly logs: string[];
|
|
@@ -79,6 +82,7 @@ export type FakeClaude = {
|
|
|
79
82
|
readonly store: Map<string, unknown>;
|
|
80
83
|
settle(): Promise<void>;
|
|
81
84
|
};
|
|
85
|
+
export declare function calledAnswer(caller: string, answer: EventResult<'cmod.call'>): unknown;
|
|
82
86
|
export declare function fakeClaude(plugin: {
|
|
83
87
|
readonly name: string;
|
|
84
88
|
readonly root: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fake-claude.d.ts","sourceRoot":"","sources":["../src/testing/fake-claude.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"fake-claude.d.ts","sourceRoot":"","sources":["../src/testing/fake-claude.ts"],"names":[],"mappings":"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"}
|
package/testing/fake-claude.js
CHANGED
|
@@ -1,8 +1,16 @@
|
|
|
1
|
+
import { isObject } from '../records.js';
|
|
1
2
|
import { elements } from './fake-elements.js';
|
|
3
|
+
import { fakeFiles } from './fake-files.js';
|
|
4
|
+
export function calledAnswer(caller, answer) {
|
|
5
|
+
if (isObject(answer) && typeof answer['deny'] === 'string')
|
|
6
|
+
throw new Error(`${caller}: $.cmod.call: ${answer['deny']}`);
|
|
7
|
+
return isObject(answer) ? answer['value'] : undefined;
|
|
8
|
+
}
|
|
2
9
|
export function fakeClaude(plugin) {
|
|
3
10
|
const calls = [];
|
|
4
11
|
const fakes = { process: {}, fs: {}, http: {}, settings: {}, config: {}, ui: {}, session: {}, prompt: {}, model: {}, agent: {}, clock: {}, cmod: {}, tool: {} };
|
|
5
|
-
const
|
|
12
|
+
const emptyDisk = fakeFiles({});
|
|
13
|
+
const shown = { notes: [], prompts: [], logs: [], debug: [], statuses: [], openPanes: new Set(), commands: [], tools: [], schedules: [] };
|
|
6
14
|
const unplacedPanes = new Set();
|
|
7
15
|
let focusedPane;
|
|
8
16
|
const store = new Map();
|
|
@@ -49,9 +57,6 @@ export function fakeClaude(plugin) {
|
|
|
49
57
|
const claude = {
|
|
50
58
|
plugin,
|
|
51
59
|
ui: {
|
|
52
|
-
toast: (text) => {
|
|
53
|
-
shown.toasts.push(text);
|
|
54
|
-
},
|
|
55
60
|
status: (text) => {
|
|
56
61
|
shown.statuses.push(text);
|
|
57
62
|
},
|
|
@@ -66,6 +71,7 @@ export function fakeClaude(plugin) {
|
|
|
66
71
|
calls.push({ call: 'ui.open', args: [pane] });
|
|
67
72
|
const answer = fakes.ui.open === undefined ? { isPlaced: true } : await fakes.ui.open(pane);
|
|
68
73
|
if (answer.isPlaced) {
|
|
74
|
+
shown.openPanes.delete(pane.id);
|
|
69
75
|
shown.openPanes.add(pane.id);
|
|
70
76
|
unplacedPanes.delete(pane.id);
|
|
71
77
|
if (pane.focus === true)
|
|
@@ -84,10 +90,12 @@ export function fakeClaude(plugin) {
|
|
|
84
90
|
focusedPane = undefined;
|
|
85
91
|
},
|
|
86
92
|
panes: async () => [
|
|
87
|
-
...[...shown.openPanes].map((id) => ({ id, title: id, isShown:
|
|
93
|
+
...[...shown.openPanes].map((id) => ({ id, title: id, isShown: id === [...shown.openPanes].at(-1), isFocused: id === focusedPane, isPlaced: true })),
|
|
88
94
|
...[...unplacedPanes].map((id) => ({ id, title: id, isShown: false, isFocused: false, isPlaced: false })),
|
|
89
95
|
],
|
|
90
96
|
scroll: rejected('ui.scroll', () => fakes.ui.scroll ?? (async () => ({}))),
|
|
97
|
+
copy: rejected('ui.copy', () => fakes.ui.copy ?? (async () => ({ isCopied: true }))),
|
|
98
|
+
focus: rejected('ui.focus', () => fakes.ui.focus ?? (async () => ({}))),
|
|
91
99
|
resolve: () => elements,
|
|
92
100
|
},
|
|
93
101
|
process: {
|
|
@@ -95,14 +103,14 @@ export function fakeClaude(plugin) {
|
|
|
95
103
|
spawn: faked('process.spawn', () => fakes.process.spawn),
|
|
96
104
|
},
|
|
97
105
|
fs: {
|
|
98
|
-
read: rejected('fs.read', () => fakes.fs.read),
|
|
99
|
-
write: rejected('fs.write', () => fakes.fs.write),
|
|
100
|
-
list: rejected('fs.list', () => fakes.fs.list),
|
|
101
|
-
exists: rejected('fs.exists', () => fakes.fs.exists ??
|
|
102
|
-
stat: rejected('fs.stat', () => fakes.fs.stat),
|
|
106
|
+
read: rejected('fs.read', () => fakes.fs.read ?? emptyDisk.read),
|
|
107
|
+
write: rejected('fs.write', () => fakes.fs.write ?? emptyDisk.write),
|
|
108
|
+
list: rejected('fs.list', () => fakes.fs.list ?? emptyDisk.list),
|
|
109
|
+
exists: rejected('fs.exists', () => fakes.fs.exists ?? emptyDisk.exists),
|
|
110
|
+
stat: rejected('fs.stat', () => fakes.fs.stat ?? emptyDisk.stat),
|
|
103
111
|
},
|
|
104
112
|
http: { fetch: rejected('http.fetch', () => fakes.http.fetch) },
|
|
105
|
-
settings: { read: rejected('settings.read', () => fakes.settings.read) },
|
|
113
|
+
settings: { read: rejected('settings.read', () => fakes.settings.read ?? (async () => ({}))) },
|
|
106
114
|
config: {
|
|
107
115
|
list: rejected('config.list', () => fakes.config.list ?? (async () => [])),
|
|
108
116
|
},
|
|
@@ -130,10 +138,11 @@ export function fakeClaude(plugin) {
|
|
|
130
138
|
root: async () => plugin.root,
|
|
131
139
|
cwd: async () => plugin.root,
|
|
132
140
|
model: async () => 'test-model',
|
|
133
|
-
usage: async () => ({ context: { window: 200000 }, rateLimits:
|
|
141
|
+
usage: async () => ({ startedAt: Date.parse('2026-01-01T00:00:00.000Z'), context: { window: 200000 }, rateLimits: [], cost: { usd: 0 } }),
|
|
134
142
|
surfaces: async () => ['terminal'],
|
|
135
143
|
messages: rejected('session.messages', () => fakes.session.messages),
|
|
136
144
|
append: rejected('session.append', () => fakes.session.append ?? appendNote),
|
|
145
|
+
send: rejected('session.send', () => fakes.session.send ?? (async () => ({ isDelivered: true }))),
|
|
137
146
|
},
|
|
138
147
|
prompt: { submit: rejected('prompt.submit', () => fakes.prompt.submit ?? submitPrompt) },
|
|
139
148
|
model: { complete: rejected('model.complete', () => fakes.model.complete) },
|
package/testing/fake-elements.js
CHANGED
|
@@ -119,8 +119,10 @@ function sideBySide(children, width, gap) {
|
|
|
119
119
|
function minWidthOf(node) {
|
|
120
120
|
if (typeof node === 'string')
|
|
121
121
|
return 0;
|
|
122
|
-
const
|
|
123
|
-
|
|
122
|
+
const { props } = insideOf(node);
|
|
123
|
+
if (props['flexShrink'] === 0)
|
|
124
|
+
return Number.POSITIVE_INFINITY;
|
|
125
|
+
return typeof props['minWidth'] === 'number' ? props['minWidth'] : 0;
|
|
124
126
|
}
|
|
125
127
|
function blankRows(count) {
|
|
126
128
|
return Array.from({ length: count }, () => '');
|
package/testing/fake-files.js
CHANGED
|
@@ -37,7 +37,7 @@ export function fakeFiles(files, links = {}) {
|
|
|
37
37
|
},
|
|
38
38
|
list: async (path) => {
|
|
39
39
|
if (path === undefined)
|
|
40
|
-
throw new Error('fs.list() lists the working folder, which the fake files do not know. Name the folder, such as fs.list(
|
|
40
|
+
throw new Error('fs.list() lists the working folder, which the fake files do not know. Name the folder, such as fs.list(sessions.current.cwd).');
|
|
41
41
|
const folder = realPathOf(path);
|
|
42
42
|
if (kindOf(folder) !== 'dir')
|
|
43
43
|
throw new Error(`ENOENT: no such directory, list '${path}'`);
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { Document } from '../session/context/turn/message/document.js';
|
|
2
|
+
import { Message } from '../session/context/turn/message/message.js';
|
|
3
|
+
import { Note } from '../session/context/turn/message/note.js';
|
|
4
|
+
import { Notice } from '../session/context/turn/message/notice.js';
|
|
5
|
+
import { Prompt } from '../session/context/turn/message/prompt.js';
|
|
6
|
+
import { Reply } from '../session/context/turn/message/reply.js';
|
|
7
|
+
import { type Sender } from '../session/context/turn/message/sender.js';
|
|
8
|
+
import { Skill } from '../session/context/turn/message/skill.js';
|
|
9
|
+
import { ToolCall } from '../session/context/turn/message/tool-call.js';
|
|
10
|
+
import { ToolResult } from '../session/context/turn/message/tool-result.js';
|
|
11
|
+
import { type SessionChange, type SessionData } from '../session/conversation.js';
|
|
12
|
+
import type { Place } from '../runtime/before.js';
|
|
13
|
+
import type { Claude } from '../runtime/claude.js';
|
|
14
|
+
export type MessageDraft = {
|
|
15
|
+
readonly type: typeof Prompt;
|
|
16
|
+
readonly text: string;
|
|
17
|
+
readonly from?: Sender;
|
|
18
|
+
} | {
|
|
19
|
+
readonly type: typeof Note;
|
|
20
|
+
readonly text: string;
|
|
21
|
+
readonly from?: Sender;
|
|
22
|
+
} | {
|
|
23
|
+
readonly type: typeof Reply;
|
|
24
|
+
readonly text: string;
|
|
25
|
+
} | {
|
|
26
|
+
readonly type: typeof ToolCall;
|
|
27
|
+
readonly name: string;
|
|
28
|
+
readonly input?: Readonly<Record<string, unknown>>;
|
|
29
|
+
readonly callId?: string;
|
|
30
|
+
} | {
|
|
31
|
+
readonly type: typeof ToolResult;
|
|
32
|
+
readonly callId: string;
|
|
33
|
+
readonly text: string;
|
|
34
|
+
readonly isError?: boolean;
|
|
35
|
+
} | {
|
|
36
|
+
readonly type: typeof Skill;
|
|
37
|
+
readonly name: string;
|
|
38
|
+
readonly text: string;
|
|
39
|
+
} | {
|
|
40
|
+
readonly type: typeof Document;
|
|
41
|
+
readonly path: string;
|
|
42
|
+
readonly text: string;
|
|
43
|
+
} | {
|
|
44
|
+
readonly type: typeof Notice;
|
|
45
|
+
readonly text: string;
|
|
46
|
+
};
|
|
47
|
+
export type FakeSession = Partial<Omit<SessionData, 'id'>> & {
|
|
48
|
+
readonly id: string;
|
|
49
|
+
readonly messages?: readonly MessageDraft[];
|
|
50
|
+
readonly goal?: string;
|
|
51
|
+
};
|
|
52
|
+
export type FakeSessions = {
|
|
53
|
+
answer(caller: string, method: string, input: unknown): unknown;
|
|
54
|
+
add(draft: MessageDraft, task?: string): Message[];
|
|
55
|
+
place(): Place;
|
|
56
|
+
wants(mod: string, event: string): boolean;
|
|
57
|
+
endTurn(): void;
|
|
58
|
+
compact(): void;
|
|
59
|
+
startTask(task: {
|
|
60
|
+
readonly title: string;
|
|
61
|
+
readonly agentType?: string;
|
|
62
|
+
readonly model?: string;
|
|
63
|
+
readonly openedBy?: string;
|
|
64
|
+
readonly parent?: string;
|
|
65
|
+
}): string;
|
|
66
|
+
start(id: string): void;
|
|
67
|
+
readonly sent: {
|
|
68
|
+
readonly session: string;
|
|
69
|
+
readonly task?: string;
|
|
70
|
+
readonly type: string;
|
|
71
|
+
readonly text: string;
|
|
72
|
+
readonly as?: string;
|
|
73
|
+
}[];
|
|
74
|
+
};
|
|
75
|
+
export declare function fakeSessions({ project, given, push, callTool }: {
|
|
76
|
+
readonly project: () => string;
|
|
77
|
+
readonly given: readonly FakeSession[];
|
|
78
|
+
readonly push: (mod: string, session: string, change: SessionChange) => void;
|
|
79
|
+
readonly callTool: Claude['tool']['call'];
|
|
80
|
+
}): FakeSessions;
|
|
81
|
+
//# sourceMappingURL=fake-sessions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fake-sessions.d.ts","sourceRoot":"","sources":["../src/testing/fake-sessions.ts"],"names":[],"mappings":"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"}
|