Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
75 changes: 0 additions & 75 deletions examples/simple/repoless.ts
Original file line number Diff line number Diff line change
Expand Up @@ -359,31 +359,6 @@ async function runRepolessAutomated() {

// Save the code to .output directory
await saveChangeSet(artifact, run.id);
} else if (artifact.type === 'bashOutput') {
const exitIcon = artifact.exitCode === 0 ? '✅' : '❌';
console.log(`\n 💻 Bash ${exitIcon}`);
console.log(` $ ${artifact.command}`);
if (artifact.stdout) {
artifact.stdout
.split('\n')
.slice(0, 8)
.forEach((line: string) => {
console.log(` │ ${line}`);
});
if (artifact.stdout.split('\n').length > 8) {
console.log(
` │ ... (${artifact.stdout.split('\n').length - 8} more lines)`,
);
}
}
if (artifact.stderr) {
artifact.stderr
.split('\n')
.slice(0, 3)
.forEach((line: string) => {
console.log(` ⚠ ${line}`);
});
}
}
}
}
Expand Down Expand Up @@ -520,31 +495,6 @@ async function runRepolessSession() {
if (artifact.gitPatch?.unidiffPatch) {
await renderDiff(artifact.gitPatch.unidiffPatch);
}
} else if (artifact.type === 'bashOutput') {
const exitIcon = artifact.exitCode === 0 ? '✅' : '❌';
console.log(`\n 💻 Bash ${exitIcon}`);
console.log(` $ ${artifact.command}`);
if (artifact.stdout) {
artifact.stdout
.split('\n')
.slice(0, 8)
.forEach((line: string) => {
console.log(` │ ${line}`);
});
if (artifact.stdout.split('\n').length > 8) {
console.log(
` │ ... (${artifact.stdout.split('\n').length - 8} more lines)`,
);
}
}
if (artifact.stderr) {
artifact.stderr
.split('\n')
.slice(0, 3)
.forEach((line: string) => {
console.log(` ⚠ ${line}`);
});
}
}
}
}
Expand Down Expand Up @@ -651,31 +601,6 @@ async function resumeSession(sessionId: string) {

// Save the code to .output directory
await saveChangeSet(artifact, sessionId);
} else if (artifact.type === 'bashOutput') {
const exitIcon = artifact.exitCode === 0 ? '✅' : '❌';
console.log(`\n 💻 Bash ${exitIcon}`);
console.log(` $ ${artifact.command}`);
if (artifact.stdout) {
artifact.stdout
.split('\n')
.slice(0, 8)
.forEach((line: string) => {
console.log(` │ ${line}`);
});
if (artifact.stdout.split('\n').length > 8) {
console.log(
` │ ... (${artifact.stdout.split('\n').length - 8} more lines)`,
);
}
}
if (artifact.stderr) {
artifact.stderr
.split('\n')
.slice(0, 3)
.forEach((line: string) => {
console.log(` ⚠ ${line}`);
});
}
}
}
}
Expand Down
14 changes: 3 additions & 11 deletions packages/core/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -178,11 +178,7 @@ const messages = await jules.select({
limit: 5,
});

// Find activities with bash errors (exitCode > 0)
const errors = await jules.select({
from: 'activities',
where: { 'artifacts.exitCode': { $gt: 0 } },
});

```

### Reactive Streams
Expand All @@ -208,15 +204,12 @@ for await (const activity of session.stream()) {
}
```

### Code Diffs, Shell Output, and Media Artifacts
### Code Diffs and Media Artifacts

Activities can contain artifacts: code changes (`changeSet`), shell output (`bashOutput`), or images (`media`).
Activities can contain artifacts: code changes (`changeSet`) or images (`media`).

```typescript
for (const artifact of activity.artifacts) {
if (artifact.type === 'bashOutput') {
console.log(artifact.toString());
}
if (artifact.type === 'changeSet') {
const parsed = artifact.parsed();
for (const file of parsed.files) {
Expand Down Expand Up @@ -312,7 +305,6 @@ if (myRepo) {
- **Artifacts:**
- `artifact.save()`: Save to filesystem.
- `artifact.toUrl()`: Get data URI.
- `artifact.toString()`: Formatted output for bash artifacts.
- `artifact.parsed()`: Structured diff parsing for changesets.
- **Sources:**
- `jules.sources()`: Async iterator over all connected sources.
Expand Down
4 changes: 2 additions & 2 deletions packages/core/spec/snapshot.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ interface SessionInsights {
readonly completionAttempts: number; // sessionCompleted events
readonly planRegenerations: number; // planGenerated events
readonly userInterventions: number; // userMessaged events
readonly failedCommands: readonly Activity[]; // bashOutput with exitCode !== 0
readonly failedCommands: readonly Activity[]; // deprecated: always empty (bashOutput removed)
}

interface SerializedSnapshot {
Expand Down Expand Up @@ -172,7 +172,7 @@ interface SerializedSnapshot {
| INS-01 | `completionAttempts` = count of `sessionCompleted` activities | implemented |
| INS-02 | `planRegenerations` = count of `planGenerated` activities | implemented |
| INS-03 | `userInterventions` = count of `userMessaged` activities | implemented |
| INS-04 | `failedCommands` = activities with `bashOutput.exitCode !== 0` | implemented |
| INS-04 | `failedCommands` = always empty (bashOutput artifacts removed) | implemented |

---

Expand Down
6 changes: 0 additions & 6 deletions packages/core/src/activities/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@

import {
MediaArtifact,
BashArtifact,
ChangeSetArtifact,
} from '../artifacts.js';
import { Activity, Artifact } from '../types.js';
Expand Down Expand Up @@ -81,7 +80,6 @@ export class DefaultActivityClient implements ActivityClient {
const hydratedArtifacts = activity.artifacts.map((artifact) => {
// If it's already a class instance, we're done.
if (artifact instanceof MediaArtifact) return artifact;
if (artifact instanceof BashArtifact) return artifact;
if (artifact instanceof ChangeSetArtifact) return artifact;

// It's a plain object from JSON.parse(), so we need to re-hydrate it.
Expand All @@ -95,10 +93,6 @@ export class DefaultActivityClient implements ActivityClient {
rawChangeSet.source,
rawChangeSet.gitPatch,
);
case 'bashOutput':
// The raw cached format has artifact.bashOutput
const rawBashOutput = (artifact as any).bashOutput || artifact;
return new BashArtifact(rawBashOutput);
case 'media':
const rawMedia = (artifact as any).media || artifact;
return new MediaArtifact(rawMedia, this.platform, activity.id);
Expand Down
35 changes: 0 additions & 35 deletions packages/core/src/artifacts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@

import type {
RestMediaArtifact,
RestBashOutputArtifact,
GitPatch,
ParsedChangeSet,
ParsedFile,
Expand Down Expand Up @@ -255,40 +254,6 @@ export class MediaArtifact {
}
}

/**
* Represents the output of a bash command executed by the agent.
*/
export class BashArtifact {
public readonly type = 'bashOutput';
public readonly command: string;
public readonly stdout: string;
public readonly stderr: string;
public readonly exitCode: number | null;

constructor(artifact: RestBashOutputArtifact['bashOutput']) {
this.command = artifact.command;
this.stdout = artifact.output;
this.stderr = '';
this.exitCode = artifact.exitCode;
}

/**
* Formats the bash output as a string, mimicking a terminal session.
*
* **Data Transformation:**
* - Combines `stdout` and `stderr`.
* - Formats the command with a `$` prompt.
* - Appends the exit code.
*/
toString(): string {
const output = [this.stdout, this.stderr].filter(Boolean).join('');
const commandLine = `$ ${this.command}`;
const outputLine = output ? `${output}\n` : '';
const exitLine = `[exit code: ${this.exitCode ?? 'N/A'}]`;
return `${commandLine}\n${outputLine}${exitLine}`;
}
}

/**
* Represents a set of code changes (unified diff) produced by an activity.
* Provides a helper method to parse the diff into structured data.
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -130,4 +130,4 @@ export type { Platform } from './platform/types.js';
export type { StorageFactory } from './types.js';

// Artifact classes with helper methods
export { ChangeSetArtifact, BashArtifact, parseUnidiff } from './artifacts.js';
export { ChangeSetArtifact, parseUnidiff } from './artifacts.js';
4 changes: 0 additions & 4 deletions packages/core/src/mappers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
// src/mappers.ts
import {
MediaArtifact,
BashArtifact,
ChangeSetArtifact,
createGeneratedFiles,
parseUnidiffWithContent,
Expand Down Expand Up @@ -62,9 +61,6 @@ export function mapRestArtifactToSdkArtifact(
if ('media' in restArtifact) {
return new MediaArtifact(restArtifact.media, platform, activityId);
}
if ('bashOutput' in restArtifact) {
return new BashArtifact(restArtifact.bashOutput);
}
// This provides a fallback, though the API should always provide a known type.
throw new Error(`Unknown artifact type: ${JSON.stringify(restArtifact)}`);
}
Expand Down
51 changes: 2 additions & 49 deletions packages/core/src/query/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -417,7 +417,7 @@ export const ACTIVITY_SCHEMA: DomainSchema = {
fields: [
{
name: 'type',
type: '"changeSet" | "media" | "bashOutput"',
type: '"changeSet" | "media"',
description: 'Artifact type discriminator',
filterable: true,
selectable: true,
Expand Down Expand Up @@ -463,36 +463,6 @@ export const ACTIVITY_SCHEMA: DomainSchema = {
},
],
},
{
name: 'command',
type: 'string',
description: 'Bash command executed (for bashOutput type)',
optional: true,
filterable: true,
selectable: true,
},
{
name: 'stdout',
type: 'string',
description: 'Standard output (for bashOutput type)',
optional: true,
selectable: true,
},
{
name: 'stderr',
type: 'string',
description: 'Standard error (for bashOutput type)',
optional: true,
selectable: true,
},
{
name: 'exitCode',
type: 'number | null',
description: 'Exit code (for bashOutput type)',
optional: true,
filterable: true,
selectable: true,
},
{
name: 'data',
type: 'string',
Expand Down Expand Up @@ -520,22 +490,6 @@ export const ACTIVITY_SCHEMA: DomainSchema = {
select: ['id', 'createTime', 'plan.steps.title'],
},
},
{
description: 'Find activities with bash commands that failed',
query: {
from: 'activities',
where: {
'artifacts.type': 'bashOutput',
'artifacts.exitCode': { neq: 0 },
},
select: [
'id',
'artifacts.command',
'artifacts.exitCode',
'artifacts.stderr',
],
},
},
{
description: 'Get agent messages with their artifacts',
query: {
Expand Down Expand Up @@ -615,8 +569,7 @@ export const FILTER_OP_SCHEMA = {
description:
'Use dot notation for nested field paths. When filtering arrays, uses existential matching (ANY element matches).',
examples: [
'"artifacts.type": "bashOutput"',
'"artifacts.exitCode": { neq: 0 }',
'"artifacts.type": "changeSet"',
'"plan.steps.title": { contains: "test" }',
'"outputs.pullRequest.url": { exists: true }',
],
Expand Down
11 changes: 1 addition & 10 deletions packages/core/src/snapshot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -148,20 +148,11 @@ export class SessionSnapshotImpl implements SessionSnapshot {
}

private computeInsights(): SessionInsights {
const failedCommands = this.activities.filter((activity) =>
activity.artifacts.some((artifact) => {
if (artifact.type === 'bashOutput') {
return artifact.exitCode !== 0;
}
return false;
}),
);

return {
completionAttempts: this.activityCounts['sessionCompleted'] || 0,
planRegenerations: this.activityCounts['planGenerated'] || 0,
userInterventions: this.activityCounts['userMessaged'] || 0,
failedCommands,
failedCommands: [],
};
}

Expand Down
Loading
Loading